src/ip/Makefile \
src/log/Makefile \
src/ipc/Makefile \
+ src/mgr/Makefile \
contrib/Makefile \
snmplib/Makefile \
icons/Makefile \
#ifndef SQUID_CACHEMANAGER_H
#define SQUID_CACHEMANAGER_H
-#include "squid.h"
-#include "Array.h"
+#include "mgr/Action.h"
+#include "mgr/ActionProfile.h"
+#include "mgr/Command.h"
+#include "mgr/forward.h"
+#include <vector>
/**
\defgroup CacheManagerAPI Cache Manager API
\ingroup CacheManagerAPI
*/
-/**
- \ingroup CacheManagerInternal
- * The basic action handler. Its virtual method run(StoreEntry *) is invoked
- * to perform the actual action.
- */
-class CacheManagerAction
-{
-public:
- virtual void run(StoreEntry *sentry) = 0;
- char *action;
- char *desc;
- struct {
- unsigned int pw_req:1;
- unsigned int atomic:1;
- } flags;
- virtual ~CacheManagerAction();
- CacheManagerAction(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic);
-
-};
-
-/**
- \ingroup CacheManagerInternal
- * wrapper allowing c-style callbacks to be used. Arguments are supposed to
- * managed by the caller.
- * This object is generated by CacheManager::registerAction
- */
-class CacheManagerActionLegacy : public CacheManagerAction
-{
-public:
- OBJH *handler;
- virtual void run (StoreEntry *sentry);
- CacheManagerActionLegacy(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic, OBJH *aHandler);
-};
-
-
/**
\ingroup CacheManagerAPI
* a CacheManager - the menu system for interacting with squid.
*/
class CacheManager
{
-
public:
- /* the holy trinity - assignment, copy cons, destructor */
- /* unimplemented - prevents bugs from synthetic */
- CacheManager & operator = (CacheManager &);
- /* unimplemented - prevents bugs from synthetic */
- CacheManager(CacheManager const &);
- /* inline so that we dont need to link in cachemgr.cc at all in tests */
- virtual ~CacheManager() {}
-
- void registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic);
- void registerAction(CacheManagerAction *anAction);
- CacheManagerAction * findAction(char const * action);
+ typedef std::vector<Mgr::ActionProfilePointer> Menu;
+
+ void registerProfile(char const * action, char const * desc,
+ OBJH * handler,
+ int pw_req_flag, int atomic);
+ void registerProfile(char const * action, char const * desc,
+ Mgr::ClassActionCreationHandler *handler,
+ int pw_req_flag, int atomic);
+ Mgr::ActionProfilePointer findAction(char const * action) const;
+ Mgr::Action::Pointer createNamedAction(const char *actionName);
+ Mgr::Action::Pointer createRequestedAction(const Mgr::ActionParams &);
+ const Menu& menu() const { return menu_; }
void Start(int fd, HttpRequest * request, StoreEntry * entry);
static CacheManager* GetInstance();
- const char *ActionProtection(const CacheManagerAction * at);
+ const char *ActionProtection(const Mgr::ActionProfilePointer &profile);
protected:
- // command classes. They are private to the cachemanager, they
- // may require access to local data, plus we avoid polluting
- // the namespace more than needed.
- class ShutdownAction : public CacheManagerAction
- {
- public:
- virtual void run (StoreEntry *sentry);
- ShutdownAction();
- };
- class ReconfigureAction : public CacheManagerAction
- {
- public:
- virtual void run (StoreEntry *sentry);
- ReconfigureAction();
- };
- class RotateAction : public CacheManagerAction
- {
- public:
- virtual void run (StoreEntry *sentry);
- RotateAction();
- };
- class OfflineToggleAction : public CacheManagerAction
- {
- public:
- virtual void run (StoreEntry *sentry);
- OfflineToggleAction();
- };
- class MenuAction : public CacheManagerAction
- {
- private:
- //needs to reference the cachemgr in order to get to ActionsList
- CacheManager *cmgr;
- public:
- virtual void run (StoreEntry *sentry);
- MenuAction(CacheManager *);
-
- };
+ CacheManager() {} ///< use Instance() instead
- /// \ingroup CacheManagerInternal
- typedef struct {
- StoreEntry *entry;
- char *action;
- char *user_name;
- char *passwd;
- } cachemgrStateData;
-
-
- CacheManager();
- cachemgrStateData* ParseUrl(const char *url);
- void ParseHeaders(cachemgrStateData * mgr, const HttpRequest * request);
- int CheckPassword(cachemgrStateData * mgr);
+ Mgr::CommandPointer ParseUrl(const char *url);
+ void ParseHeaders(const HttpRequest * request, Mgr::ActionParams ¶ms);
+ int CheckPassword(const Mgr::Command &cmd);
char *PasswdGet(cachemgr_passwd *, const char *);
- // \ingroup CacheManagerInternal
- typedef Vector<CacheManagerAction *> CacheManagerActionList;
- CacheManagerActionList ActionsList;
+ void registerProfile(const Mgr::ActionProfilePointer &profile);
+ Menu menu_;
private:
static CacheManager* instance;
-
- void StateFree(cachemgrStateData * mgr);
-
-
};
#endif /* SQUID_CACHEMANAGER_H */
#include "squid.h"
#include "DiskDaemonDiskIOModule.h"
-#include "CacheManager.h"
#include "DiskdIOStrategy.h"
+#include "DiskIO/DiskDaemon/DiskdAction.h"
+#include "mgr/Registration.h"
#include "Store.h"
DiskDaemonDiskIOModule::DiskDaemonDiskIOModule() : initialised(false)
void
DiskDaemonDiskIOModule::registerWithCacheManager(void)
{
- CacheManager::GetInstance()->registerAction("diskd", "DISKD Stats", Stats, 0, 1);
+ Mgr::RegisterAction("diskd", "DISKD Stats", &DiskdAction::Create, 0, 1);
}
void
DiskDaemonDiskIOModule DiskDaemonDiskIOModule::Instance;
-void
-DiskDaemonDiskIOModule::Stats(StoreEntry * sentry)
-{
- storeAppendPrintf(sentry, "sent_count: %d\n", diskd_stats.sent_count);
- storeAppendPrintf(sentry, "recv_count: %d\n", diskd_stats.recv_count);
- storeAppendPrintf(sentry, "max_away: %d\n", diskd_stats.max_away);
- storeAppendPrintf(sentry, "max_shmuse: %d\n", diskd_stats.max_shmuse);
- storeAppendPrintf(sentry, "open_fail_queue_len: %d\n", diskd_stats.open_fail_queue_len);
- storeAppendPrintf(sentry, "block_queue_len: %d\n", diskd_stats.block_queue_len);
- diskd_stats.max_away = diskd_stats.max_shmuse = 0;
- storeAppendPrintf(sentry, "\n OPS SUCCESS FAIL\n");
- storeAppendPrintf(sentry, "%7s %9d %9d %7d\n",
- "open", diskd_stats.open.ops, diskd_stats.open.success, diskd_stats.open.fail);
- storeAppendPrintf(sentry, "%7s %9d %9d %7d\n",
- "create", diskd_stats.create.ops, diskd_stats.create.success, diskd_stats.create.fail);
- storeAppendPrintf(sentry, "%7s %9d %9d %7d\n",
- "close", diskd_stats.close.ops, diskd_stats.close.success, diskd_stats.close.fail);
- storeAppendPrintf(sentry, "%7s %9d %9d %7d\n",
- "unlink", diskd_stats.unlink.ops, diskd_stats.unlink.success, diskd_stats.unlink.fail);
- storeAppendPrintf(sentry, "%7s %9d %9d %7d\n",
- "read", diskd_stats.read.ops, diskd_stats.read.success, diskd_stats.read.fail);
- storeAppendPrintf(sentry, "%7s %9d %9d %7d\n",
- "write", diskd_stats.write.ops, diskd_stats.write.success, diskd_stats.write.fail);
-}
-
char const *
DiskDaemonDiskIOModule::type () const
{
virtual DiskIOStrategy* createStrategy();
private:
- static void Stats(StoreEntry * sentry);
static DiskDaemonDiskIOModule Instance;
bool initialised;
void registerWithCacheManager(void);
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 79 Squid-side DISKD I/O functions.
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "Store.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/ActionWriter.h"
+#include "DiskIO/DiskDaemon/DiskdAction.h"
+#include "DiskIO/DiskDaemon/DiskdIOStrategy.h"
+
+
+DiskdActionData::DiskdActionData()
+{
+ xmemset(this, 0, sizeof(*this));
+}
+
+DiskdActionData&
+DiskdActionData::operator += (const DiskdActionData& stats)
+{
+ sent_count += stats.sent_count;
+ recv_count += stats.recv_count;
+ if (stats.max_away > max_away)
+ max_away = stats.max_away;
+ if (stats.max_shmuse > max_shmuse)
+ max_shmuse += stats.max_shmuse;
+ open_fail_queue_len += stats.open_fail_queue_len;
+ block_queue_len += stats.block_queue_len;
+ open_ops += stats.open_ops;
+ open_success += stats.open_success;
+ open_fail += stats.open_fail;
+ create_ops += stats.create_ops;
+ create_success += stats.create_success;
+ create_fail += stats.create_fail;
+ close_ops += stats.close_ops;
+ close_success += stats.close_success;
+ close_fail += stats.close_fail;
+ unlink_ops += stats.unlink_ops;
+ unlink_success += stats.unlink_success;
+ unlink_fail += stats.unlink_fail;
+ read_ops += stats.read_ops;
+ read_success += stats.read_success;
+ read_fail += stats.read_fail;
+ write_ops += stats.write_ops;
+ write_success += stats.write_success;
+ write_fail += stats.write_fail;
+
+ return *this;
+}
+
+
+DiskdAction::Pointer
+DiskdAction::Create(const Mgr::CommandPointer &aCmd)
+{
+ return new DiskdAction(aCmd);
+}
+
+DiskdAction::DiskdAction(const Mgr::CommandPointer &aCmd):
+ Action(aCmd), data()
+{
+ debugs(79, 5, HERE);
+}
+
+void
+DiskdAction::add(const Action& action)
+{
+ debugs(79, 5, HERE);
+ data += dynamic_cast<const DiskdAction&>(action).data;
+}
+
+void
+DiskdAction::collect()
+{
+ data.sent_count = diskd_stats.sent_count;
+ data.recv_count = diskd_stats.recv_count;
+ data.max_away = diskd_stats.max_away;
+ data.max_shmuse = diskd_stats.max_shmuse;
+ data.open_fail_queue_len = diskd_stats.open_fail_queue_len;
+ data.block_queue_len = diskd_stats.block_queue_len;
+ diskd_stats.max_away = diskd_stats.max_shmuse = 0;
+
+ data.open_ops = diskd_stats.open.ops;
+ data.open_success = diskd_stats.open.success;
+ data.open_fail = diskd_stats.open.fail;
+
+ data.create_ops = diskd_stats.create.ops;
+ data.create_success = diskd_stats.create.success;
+ data.create_fail = diskd_stats.create.fail;
+
+ data.close_ops = diskd_stats.close.ops;
+ data.close_success = diskd_stats.close.success;
+ data.close_fail = diskd_stats.close.fail;
+
+ data.unlink_ops = diskd_stats.unlink.ops;
+ data.unlink_success = diskd_stats.unlink.success;
+ data.unlink_fail = diskd_stats.unlink.fail;
+
+ data.read_ops = diskd_stats.read.ops;
+ data.read_success = diskd_stats.read.success;
+ data.read_fail = diskd_stats.read.fail;
+
+ data.write_ops = diskd_stats.write.ops;
+ data.write_success = diskd_stats.write.success;
+ data.write_fail = diskd_stats.write.fail;
+}
+
+void
+DiskdAction::dump(StoreEntry* entry)
+{
+ debugs(79, 5, HERE);
+ Must(entry != NULL);
+ storeAppendPrintf(entry, "sent_count: %.0f\n", data.sent_count);
+ storeAppendPrintf(entry, "recv_count: %.0f\n", data.recv_count);
+ storeAppendPrintf(entry, "max_away: %.0f\n", data.max_away);
+ storeAppendPrintf(entry, "max_shmuse: %.0f\n", data.max_shmuse);
+ storeAppendPrintf(entry, "open_fail_queue_len: %.0f\n", data.open_fail_queue_len);
+ storeAppendPrintf(entry, "block_queue_len: %.0f\n", data.block_queue_len);
+ storeAppendPrintf(entry, "\n OPS SUCCESS FAIL\n");
+ storeAppendPrintf(entry, "%7s %9.0f %9.0f %7.0f\n",
+ "open", data.open_ops, data.open_success, data.open_fail);
+ storeAppendPrintf(entry, "%7s %9.0f %9.0f %7.0f\n",
+ "create", data.create_ops, data.create_success, data.create_fail);
+ storeAppendPrintf(entry, "%7s %9.0f %9.0f %7.0f\n",
+ "close", data.close_ops, data.close_success, data.close_fail);
+ storeAppendPrintf(entry, "%7s %9.0f %9.0f %7.0f\n",
+ "unlink", data.unlink_ops, data.unlink_success, data.unlink_fail);
+ storeAppendPrintf(entry, "%7s %9.0f %9.0f %7.0f\n",
+ "read", data.read_ops, data.read_success, data.read_fail);
+ storeAppendPrintf(entry, "%7s %9.0f %9.0f %7.0f\n",
+ "write", data.write_ops, data.write_success, data.write_fail);
+}
+
+void
+DiskdAction::pack(Ipc::TypedMsgHdr& hdrMsg) const
+{
+ hdrMsg.setType(Ipc::mtCacheMgrResponse);
+ hdrMsg.putPod(data);
+}
+
+void
+DiskdAction::unpack(const Ipc::TypedMsgHdr& hdrMsg)
+{
+ hdrMsg.checkType(Ipc::mtCacheMgrResponse);
+ hdrMsg.getPod(data);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 79 Squid-side DISKD I/O functions.
+ *
+ */
+
+#ifndef SQUID_DISKD_ACTION_H
+#define SQUID_DISKD_ACTION_H
+
+#include "ipc/forward.h"
+#include "mgr/forward.h"
+#include "mgr/Action.h"
+
+
+/// store disk daemon stats
+class DiskdActionData
+{
+public:
+ DiskdActionData();
+ DiskdActionData& operator += (const DiskdActionData& stats);
+
+public:
+ double sent_count;
+ double recv_count;
+ double max_away;
+ double max_shmuse;
+ double open_fail_queue_len;
+ double block_queue_len;
+ double open_ops;
+ double open_success;
+ double open_fail;
+ double create_ops;
+ double create_success;
+ double create_fail;
+ double close_ops;
+ double close_success;
+ double close_fail;
+ double unlink_ops;
+ double unlink_success;
+ double unlink_fail;
+ double read_ops;
+ double read_success;
+ double read_fail;
+ double write_ops;
+ double write_success;
+ double write_fail;
+};
+
+/// implement aggregated 'diskd' action
+class DiskdAction: public Mgr::Action
+{
+protected:
+ DiskdAction(const Mgr::CommandPointer &aCmd);
+
+public:
+ static Pointer Create(const Mgr::CommandPointer &aCmd);
+ /* Action API */
+ virtual void add(const Mgr::Action& action);
+ virtual void pack(Ipc::TypedMsgHdr& hdrMsg) const;
+ virtual void unpack(const Ipc::TypedMsgHdr& hdrMsg);
+
+protected:
+ /* Action API */
+ virtual void collect();
+ virtual void dump(StoreEntry* entry);
+
+private:
+ DiskdActionData data;
+};
+
+#endif /* SQUID_DISKD_ACTION_H */
#include "squid.h"
-#include "CacheManager.h"
-#include "DiskThreadsIOStrategy.h"
#include "DiskThreadsDiskFile.h"
+#include "DiskThreadsIOStrategy.h"
+#include "fde.h"
+#include "mgr/Registration.h"
/* for statfs */
#include "Store.h"
-#include "fde.h"
+
void
DiskThreadsIOStrategy::init(void)
void
DiskThreadsIOStrategy::registerWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("squidaio_counts", "Async IO Function Counters",
+ Mgr::RegisterAction("squidaio_counts", "Async IO Function Counters",
aioStats, 0, 1);
}
*/
#include "squid.h"
-#include "CacheManager.h"
-#include "Store.h"
-#include "HttpHeader.h"
#include "HttpHdrContRange.h"
#include "HttpHdrSc.h"
+#include "HttpHeader.h"
#include "MemBuf.h"
+#include "mgr/Registration.h"
+#include "Store.h"
/*
* On naming conventions:
static void
httpHeaderRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("http_headers",
+ Mgr::RegisterAction("http_headers",
"HTTP Header Statistics",
httpHeaderStoreReport, 0, 1);
}
LoadableModules.h \
LoadableModules.cc
-SUBDIRS = base comm eui acl fs repl auth ip icmp ident log ipc
+SUBDIRS = base comm eui acl fs repl auth ip icmp ident log ipc mgr
if USE_ADAPTATION
SUBDIRS += adaptation
libsquid.la \
ip/libip.la \
fs/libfs.la \
- ipc/libipc.la
+ ipc/libipc.la \
+ mgr/libmgr.la
EXTRA_PROGRAMS = \
DiskIO/DiskDaemon/diskd \
DiskIO/DiskDaemon/DiskdIOStrategy.h \
DiskIO/DiskDaemon/diomsg.h \
DiskIO/DiskDaemon/DiskDaemonDiskIOModule.cc \
- DiskIO/DiskDaemon/DiskDaemonDiskIOModule.h
+ DiskIO/DiskDaemon/DiskDaemonDiskIOModule.h \
+ DiskIO/DiskDaemon/DiskdAction.cc \
+ DiskIO/DiskDaemon/DiskdAction.h
libDiskThreads_a_SOURCES = \
$(AIOPS_SOURCE) \
tests/testDiskIO.h \
tests/testMain.cc \
tests/stub_cache_manager.cc \
- tests/stub_HelperChildConfig.cc
+ tests/stub_HelperChildConfig.cc \
+ tests/stub_Port.cc \
+ tests/stub_TypedMsgHdr.cc \
+ tests/stub_UdsOp.cc
nodist_tests_testDiskIO_SOURCES= \
$(SWAP_TEST_GEN_SOURCES) \
SquidMath.cc \
$(DISK_OS_LIBS) \
$(COMMON_LIBS) \
SquidConfig.o \
+ CommCalls.o \
+ DnsLookupDetails.o \
$(XTRA_LIBS)
tests_testDiskIO_LDFLAGS = $(LIBADD_DL)
tests/stub_HelperChildConfig.cc \
tests/stub_HttpReply.cc \
tests/stub_cache_manager.cc \
+ tests/stub_Port.cc \
+ tests/stub_TypedMsgHdr.cc \
+ tests/stub_UdsOp.cc \
$(STORE_TEST_SOURCES) \
tests/stub_fd.cc
$(REGEXLIB) \
$(SQUID_CPPUNIT_LIBS) \
$(SSLLIB) \
+ CommCalls.o \
+ DnsLookupDetails.o \
$(COMPAT_LIB) \
$(XTRA_LIBS)
tests_testStore_LDFLAGS = $(LIBADD_DL)
tests/testUfs.h \
tests/stub_cache_manager.cc \
tests/stub_HelperChildConfig.cc \
+ tests/stub_Port.cc \
+ tests/stub_TypedMsgHdr.cc \
+ tests/stub_UdsOp.cc \
$(SWAP_TEST_SOURCES)
nodist_tests_testUfs_SOURCES = \
$(SWAP_TEST_GEN_SOURCES) \
$(SWAP_TEST_LDADD) \
$(COMMON_LIBS) \
$(SSLLIB) \
+ CommCalls.o \
+ DnsLookupDetails.o \
$(XTRA_LIBS)
tests_testUfs_LDFLAGS = $(LIBADD_DL)
tests_testUfs_DEPENDENCIES = \
#if USE_XPROF_STATS
-#include "CacheManager.h"
#include "event.h"
+#include "mgr/Registration.h"
#include "SquidMath.h"
#include "Store.h"
static void
xprofRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("cpu_profile", "CPU Profiling Stats", xprof_summary, 0, 1);
+ Mgr::RegisterAction("cpu_profile", "CPU Profiling Stats", xprof_summary, 0, 1);
}
// FIXME:
class Store;
class StoreSearch;
+typedef struct {
+
+ struct {
+ int calls;
+ int select_fail;
+ int create_fail;
+ int success;
+ } create;
+} StoreIoStats;
+
+extern StoreIoStats store_io_stats;
+
/**
\ingroup StoreAPI
*/
char *data;
};
+inline
+std::ostream &
+operator <<(std::ostream &os, const StoreIOBuffer &b)
+{
+ return os << "ioBuf(@" << b.offset << ", len=" << b.length << ", " <<
+ (void*)b.data << (b.flags.error ? ", ERR" : "") << ')';
+}
+
#endif /* SQUID_STOREIOBUFFER_H */
#include "squid.h"
#include "base/TextException.h"
+#include "mgr/Registration.h"
#include "Store.h"
int
StringRegistry::StringRegistry()
{
#if DEBUGSTRINGS
- CacheManager::GetInstance()->registerAction("strings",
+ Mgr::RegisterAction("strings",
"Strings in use in squid", Stat, 0, 1);
#endif
}
*/
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "radix.h"
#include "HttpRequest.h"
#include "StoreClient.h"
static void
asnRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->registerAction("asndb", "AS Number Database", asnStats, 0, 1);
+ Mgr::RegisterAction("asndb", "AS Number Database", asnStats, 0, 1);
}
/* initialize the radix tree structure */
#include "auth/basic/basicUserRequest.h"
#include "auth/Gadgets.h"
#include "auth/State.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "HttpReply.h"
#include "rfc1738.h"
void
AuthBasicConfig::registerWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("basicauthenticator",
+ Mgr::RegisterAction("basicauthenticator",
"Basic User Authenticator Stats",
authenticateBasicStats, 0, 1);
}
#include "auth/digest/auth_digest.h"
#include "auth/Gadgets.h"
#include "event.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "HttpRequest.h"
#include "HttpReply.h"
void
AuthDigestConfig::registerWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("digestauthenticator",
+ Mgr::RegisterAction("digestauthenticator",
"Digest User Authenticator Stats",
authenticateDigestStats, 0, 1);
}
#include "auth/negotiate/auth_negotiate.h"
#include "auth/Gadgets.h"
#include "auth/State.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "client_side.h"
#include "HttpReply.h"
void
AuthNegotiateConfig::registerWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("negotiateauthenticator",
+ Mgr::RegisterAction("negotiateauthenticator",
"Negotiate User Authenticator Stats",
authenticateNegotiateStats, 0, 1);
}
#include "auth/ntlm/ntlmScheme.h"
#include "auth/ntlm/ntlmUserRequest.h"
#include "auth/State.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "client_side.h"
#include "HttpReply.h"
void
AuthNTLMConfig::registerWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("ntlmauthenticator",
+ Mgr::RegisterAction("ntlmauthenticator",
"NTLM User Authenticator Stats",
authenticateNTLMStats, 0, 1);
}
virtual void doDial() { ((&(*this->job))->*method)(); }
};
-template <class Job, class Argument1>
+template <class Job, class Data, class Argument1 = Data>
class UnaryMemFunT: public JobDialer<Job>
{
public:
typedef void (Job::*Method)(Argument1);
explicit UnaryMemFunT(const CbcPointer<Job> &aJob, Method aMethod,
- const Argument1 &anArg1): JobDialer<Job>(aJob),
+ const Data &anArg1): JobDialer<Job>(aJob),
method(aMethod), arg1(anArg1) {}
virtual void print(std::ostream &os) const { os << '(' << arg1 << ')'; }
public:
Method method;
- Argument1 arg1;
+ Data arg1;
protected:
virtual void doDial() { ((&(*this->job))->*method)(arg1); }
#endif
#include "auth/Config.h"
#include "auth/Scheme.h"
-#include "CacheManager.h"
#include "ConfigParser.h"
#include "CpuAffinityMap.h"
#include "eui/Config.h"
#include "ip/tools.h"
#include "log/Config.h"
#include "MemBuf.h"
+#include "mgr/Registration.h"
#include "Parsing.h"
#include "ProtoPort.h"
#include "rfc1738.h"
parseConfigFile(const char *file_name)
{
int err_count = 0;
- CacheManager *manager=CacheManager::GetInstance();
debugs(5, 4, HERE);
}
if (opt_send_signal == -1) {
- manager->registerAction("config",
+ Mgr::RegisterAction("config",
"Current Squid Configuration",
dump_config,
1, 1);
*
*/
+#include "config.h"
+#include "base/TextException.h"
#include "CacheManager.h"
+#include "Debug.h"
#include "errorpage.h"
+#include "fde.h"
#include "HttpReply.h"
#include "HttpRequest.h"
-#include "Store.h"
-#include "fde.h"
+#include "mgr/ActionCreator.h"
+#include "mgr/Action.h"
+#include "mgr/ActionProfile.h"
+#include "mgr/BasicActions.h"
+#include "mgr/Command.h"
+#include "mgr/Forwarder.h"
+#include "mgr/FunAction.h"
+#include "protos.h" /* rotate_logs() */
#include "SquidTime.h"
+#include "Store.h"
#include "wordlist.h"
-#include "Debug.h"
+#include <algorithm>
-// for rotate_logs()
-#include "protos.h"
/// \ingroup CacheManagerInternal
#define MGR_PASSWD_SZ 128
+/// creates Action using supplied Action::Create method and command
+class ClassActionCreator: public Mgr::ActionCreator
+{
+public:
+ typedef Mgr::Action::Pointer Handler(const Mgr::Command::Pointer &cmd);
-/**
- \ingroup CacheManagerInternals
- * Constructor. Its purpose is to register internal commands
- */
-CacheManager::CacheManager()
+public:
+ ClassActionCreator(Handler *aHandler): handler(aHandler) {}
+
+ virtual Mgr::Action::Pointer create(const Mgr::Command::Pointer &cmd) const
+ {
+ return handler(cmd);
+ }
+
+private:
+ Handler *handler;
+};
+
+
+/// Registers new profiles, ignoring attempts to register a duplicate
+void
+CacheManager::registerProfile(const Mgr::ActionProfile::Pointer &profile)
{
- registerAction(new OfflineToggleAction);
- registerAction(new ShutdownAction);
- registerAction(new ReconfigureAction);
- registerAction(new RotateAction);
- registerAction(new MenuAction(this));
+ Must(profile != NULL);
+ if (find(menu_.begin(), menu_.end(), profile) == menu_.end()) {
+ menu_.push_back(profile);
+ debugs(16, 3, HERE << "registered profile: " << *profile);
+ } else {
+ debugs(16, 2, HERE << "skipped duplicate profile: " << *profile);
+ }
}
/**
* Implemented via CacheManagerActionLegacy.
*/
void
-CacheManager::registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic)
+CacheManager::registerProfile(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic)
{
- debugs(16, 3, "CacheManager::registerAction: registering legacy " << action);
- registerAction(new CacheManagerActionLegacy(action,desc,pw_req_flag,atomic,handler));
+ debugs(16, 3, HERE << "registering legacy " << action);
+ const Mgr::ActionProfile::Pointer profile = new Mgr::ActionProfile(action,
+ desc, pw_req_flag, atomic, new Mgr::FunActionCreator(handler));
+ registerProfile(profile);
}
-/**
- \ingroup CacheManagerAPI
- * Registers a C++-style action, via a poiner to a subclass of
- * a CacheManagerAction object, whose run() method will be invoked when
- * CacheManager identifies that the user has requested the action.
- */
void
-CacheManager::registerAction(CacheManagerAction *anAction)
+CacheManager::registerProfile(char const * action, char const * desc,
+ ClassActionCreator::Handler *handler,
+ int pw_req_flag, int atomic)
{
- char *action = anAction->action;
- if (findAction(action) != NULL) {
- debugs(16, 2, "CacheManager::registerAction: Duplicate '" << action << "'. Skipping.");
- return;
- }
-
- assert (strstr (" ", action) == NULL);
-
- ActionsList += anAction;
-
- debugs(16, 3, "CacheManager::registerAction: registered " << action);
+ const Mgr::ActionProfile::Pointer profile = new Mgr::ActionProfile(action,
+ desc, pw_req_flag, atomic, new ClassActionCreator(handler));
+ registerProfile(profile);
}
-
/**
\ingroup CacheManagerInternal
* Locates an action in the actions registry ActionsList.
\retval NULL if Action not found
\retval CacheManagerAction* if the action was found
*/
-CacheManagerAction *
-CacheManager::findAction(char const * action)
+Mgr::ActionProfile::Pointer
+CacheManager::findAction(char const * action) const
{
- CacheManagerActionList::iterator a;
+ Must(action != NULL);
+ Menu::const_iterator a;
debugs(16, 5, "CacheManager::findAction: looking for action " << action);
- for ( a = ActionsList.begin(); a != ActionsList.end(); a++) {
- if (0 == strcmp((*a)->action, action)) {
+ for (a = menu_.begin(); a != menu_.end(); ++a) {
+ if (0 == strcmp((*a)->name, action)) {
debugs(16, 6, " found");
return *a;
}
}
debugs(16, 6, "Action not found.");
- return NULL;
+ return Mgr::ActionProfilePointer();
+}
+
+Mgr::Action::Pointer
+CacheManager::createNamedAction(const char *actionName)
+{
+ Must(actionName);
+
+ Mgr::Command::Pointer cmd = new Mgr::Command;
+ cmd->profile = findAction(actionName);
+ cmd->params.actionName = actionName;
+
+ Must(cmd->profile != NULL);
+ return cmd->profile->creator->create(cmd);
+}
+
+Mgr::Action::Pointer
+CacheManager::createRequestedAction(const Mgr::ActionParams ¶ms)
+{
+ Mgr::Command::Pointer cmd = new Mgr::Command;
+ cmd->params = params;
+ cmd->profile = findAction(params.actionName.termedBuf());
+ Must(cmd->profile != NULL);
+ return cmd->profile->creator->create(cmd);
}
/**
\retval CacheManager::cachemgrStateData state object for the following handling
\retval NULL if the action can't be found or can't be accessed by the user
*/
-CacheManager::cachemgrStateData *
+Mgr::Command::Pointer
CacheManager::ParseUrl(const char *url)
{
int t;
LOCAL_ARRAY(char, host, MAX_URL);
LOCAL_ARRAY(char, request, MAX_URL);
LOCAL_ARRAY(char, password, MAX_URL);
- CacheManagerAction *a;
- cachemgrStateData *mgr = NULL;
- const char *prot;
t = sscanf(url, "cache_object://%[^/]/%[^@]@%s", host, request, password);
- if (t < 2) {
+ if (t < 2)
xstrncpy(request, "menu", MAX_URL);
+
#ifdef _SQUID_OS2_
+ if (t == 2 && request[0] == '\0') {
/*
* emx's sscanf insists of returning 2 because it sets request
* to null
*/
- } else if (request[0] == '\0') {
xstrncpy(request, "menu", MAX_URL);
+ }
#endif
- } else if ((a = findAction(request)) == NULL) {
+ Mgr::ActionProfile::Pointer profile = findAction(request);
+ if (!profile) {
debugs(16, DBG_IMPORTANT, "CacheManager::ParseUrl: action '" << request << "' not found");
return NULL;
- } else {
- prot = ActionProtection(a);
-
- if (!strcmp(prot, "disabled") || !strcmp(prot, "hidden")) {
- debugs(16, DBG_IMPORTANT, "CacheManager::ParseUrl: action '" << request << "' is " << prot);
- return NULL;
- }
}
- /* set absent entries to NULL so we can test if they are present later */
- mgr = (cachemgrStateData *)xcalloc(1, sizeof(cachemgrStateData));
-
- mgr->user_name = NULL;
-
- mgr->passwd = t == 3 ? xstrdup(password) : NULL;
-
- mgr->action = xstrdup(request);
+ const char *prot = ActionProtection(profile);
+ if (!strcmp(prot, "disabled") || !strcmp(prot, "hidden")) {
+ debugs(16, DBG_IMPORTANT, "CacheManager::ParseUrl: action '" << request << "' is " << prot);
+ return NULL;
+ }
- return mgr;
+ Mgr::Command::Pointer cmd = new Mgr::Command;
+ cmd->profile = profile;
+ cmd->params.httpUri = url;
+ cmd->params.userName = String();
+ cmd->params.password = t == 3 ? String(password) : String();
+ cmd->params.actionName = request;
+ return cmd;
}
/// \ingroup CacheManagerInternal
* the details into the cachemgrStateData argument
*/
void
-CacheManager::ParseHeaders(cachemgrStateData * mgr, const HttpRequest * request)
+CacheManager::ParseHeaders(const HttpRequest * request, Mgr::ActionParams ¶ms)
{
const char *basic_cookie; /* base 64 _decoded_ user:passwd pair */
const char *passwd_del;
- assert(mgr && request);
+ assert(request);
+
+ params.httpMethod = request->method.id();
+ params.httpFlags = request->flags;
+
basic_cookie = request->header.getAuth(HDR_AUTHORIZATION, "Basic");
if (!basic_cookie)
}
/* found user:password pair, reset old values */
- safe_free(mgr->user_name);
-
- safe_free(mgr->passwd);
-
- mgr->user_name = xstrdup(basic_cookie);
-
- mgr->user_name[passwd_del - basic_cookie] = '\0';
-
- mgr->passwd = xstrdup(passwd_del + 1);
+ params.userName.limitInit(basic_cookie, passwd_del - basic_cookie);
+ params.password = passwd_del + 1;
/* warning: this prints decoded password which maybe not what you want to do @?@ @?@ */
- debugs(16, 9, "CacheManager::ParseHeaders: got user: '" << mgr->user_name << "' passwd: '" << mgr->passwd << "'");
+ debugs(16, 9, "CacheManager::ParseHeaders: got user: '" <<
+ params.userName << "' passwd: '" << params.password << "'");
}
/**
\retval !0 if mgr->password does not match configured password
*/
int
-CacheManager::CheckPassword(cachemgrStateData * mgr)
+CacheManager::CheckPassword(const Mgr::Command &cmd)
{
- char *pwd = PasswdGet(Config.passwd_list, mgr->action);
- CacheManagerAction *a = findAction(mgr->action);
+ assert(cmd.profile != NULL);
+ const char *action = cmd.profile->name;
+ char *pwd = PasswdGet(Config.passwd_list, action);
- debugs(16, 4, "CacheManager::CheckPassword for action " << mgr->action);
- assert(a != NULL);
+ debugs(16, 4, "CacheManager::CheckPassword for action " << action);
if (pwd == NULL)
- return a->flags.pw_req;
+ return cmd.profile->isPwReq;
if (strcmp(pwd, "disable") == 0)
return 1;
if (strcmp(pwd, "none") == 0)
return 0;
- if (!mgr->passwd)
+ if (!cmd.params.password.size())
return 1;
- return strcmp(pwd, mgr->passwd);
-}
-
-/// \ingroup CacheManagerInternal
-void
-CacheManager::StateFree(cachemgrStateData * mgr)
-{
- safe_free(mgr->action);
- safe_free(mgr->user_name);
- safe_free(mgr->passwd);
- mgr->entry->unlock();
- xfree(mgr);
+ return cmd.params.password != pwd;
}
/**
void
CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry)
{
- cachemgrStateData *mgr = NULL;
ErrorState *err = NULL;
- CacheManagerAction *a;
debugs(16, 3, "CacheManager::Start: '" << entry->url() << "'" );
- if ((mgr = ParseUrl(entry->url())) == NULL) {
+ Mgr::Command::Pointer cmd = ParseUrl(entry->url());
+ if (!cmd) {
err = errorCon(ERR_INVALID_URL, HTTP_NOT_FOUND, request);
err->url = xstrdup(entry->url());
errorAppendEntry(entry, err);
return;
}
- mgr->entry = entry;
+ const char *actionName = cmd->profile->name;
- entry->lock();
entry->expires = squid_curtime;
- debugs(16, 5, "CacheManager: " << fd_table[fd].ipaddr << " requesting '" << mgr->action << "'");
+ debugs(16, 5, "CacheManager: " << fd_table[fd].ipaddr << " requesting '" << actionName << "'");
/* get additional info from request headers */
- ParseHeaders(mgr, request);
+ ParseHeaders(request, cmd->params);
+
+ const char *userName = cmd->params.userName.size() ?
+ cmd->params.userName.termedBuf() : "unknown";
/* Check password */
- if (CheckPassword(mgr) != 0) {
+ if (CheckPassword(*cmd) != 0) {
/* build error message */
ErrorState *errState;
HttpReply *rep;
errState = errorCon(ERR_CACHE_MGR_ACCESS_DENIED, HTTP_UNAUTHORIZED, request);
/* warn if user specified incorrect password */
- if (mgr->passwd)
+ if (cmd->params.password.size()) {
debugs(16, DBG_IMPORTANT, "CacheManager: " <<
- (mgr->user_name ? mgr->user_name : "<unknown>") << "@" <<
+ userName << "@" <<
fd_table[fd].ipaddr << ": incorrect password for '" <<
- mgr->action << "'" );
- else
+ actionName << "'" );
+ } else {
debugs(16, DBG_IMPORTANT, "CacheManager: " <<
- (mgr->user_name ? mgr->user_name : "<unknown>") << "@" <<
+ userName << "@" <<
fd_table[fd].ipaddr << ": password needed for '" <<
- mgr->action << "'" );
+ actionName << "'" );
+ }
rep = errState->BuildHttpReply();
errorStateFree(errState);
/*
- * add Authenticate header, use 'action' as a realm because
- * password depends on action
+ * add Authenticate header using action name as a realm because
+ * password depends on the action
*/
- rep->header.putAuth("Basic", mgr->action);
+ rep->header.putAuth("Basic", actionName);
/* store the reply */
entry->replaceHttpReply(rep);
entry->complete();
- StateFree(mgr);
-
return;
}
debugs(16, 2, "CacheManager: " <<
- (mgr->user_name ? mgr->user_name : "<unknown>") << "@" <<
+ userName << "@" <<
fd_table[fd].ipaddr << " requesting '" <<
- mgr->action << "'" );
- /* retrieve object requested */
- a = findAction(mgr->action);
- assert(a != NULL);
+ actionName << "'" );
- entry->buffer();
-
- {
- HttpReply *rep = new HttpReply;
- rep->setHeaders(HTTP_OK, NULL, "text/plain", -1, squid_curtime, squid_curtime);
- entry->replaceHttpReply(rep);
+ if (UsingSmp() && IamWorkerProcess()) {
+ AsyncJob::Start(new Mgr::Forwarder(fd, cmd->params, request, entry));
+ return;
}
- a->run(entry);
-
- entry->flush();
-
- if (a->flags.atomic)
- entry->complete();
-
- StateFree(mgr);
-}
-
-/// \ingroup CacheManagerInternal
-void CacheManager::ShutdownAction::run(StoreEntry *sentry)
-{
- debugs(16, DBG_CRITICAL, "Shutdown by Cache Manager command.");
- shut_down(0);
-}
-/// \ingroup CacheManagerInternal
-CacheManager::ShutdownAction::ShutdownAction() : CacheManagerAction("shutdown","Shut Down the Squid Process", 1, 1) { }
-
-/// \ingroup CacheManagerInternal
-void
-CacheManager::ReconfigureAction::run(StoreEntry * sentry)
-{
- debugs(16, DBG_IMPORTANT, "Reconfigure by Cache Manager command.");
- storeAppendPrintf(sentry, "Reconfiguring Squid Process ....");
- reconfigure(SIGHUP);
-}
-/// \ingroup CacheManagerInternal
-CacheManager::ReconfigureAction::ReconfigureAction() : CacheManagerAction("reconfigure","Reconfigure Squid", 1, 1) { }
-
-/// \ingroup CacheManagerInternal
-void
-CacheManager::RotateAction::run(StoreEntry * sentry)
-{
- debugs(16, DBG_IMPORTANT, "Rotate Logs by Cache Manager command.");
- storeAppendPrintf(sentry, "Rotating Squid Process Logs ....");
-#ifdef _SQUID_LINUX_THREADS_
- rotate_logs(SIGQUIT);
-#else
- rotate_logs(SIGUSR1);
-#endif
-}
-/// \ingroup CacheManagerInternal
-CacheManager::RotateAction::RotateAction() : CacheManagerAction("rotate","Rotate Squid Logs", 1, 1) { }
-
-/// \ingroup CacheManagerInternal
-void
-CacheManager::OfflineToggleAction::run(StoreEntry * sentry)
-{
- Config.onoff.offline = !Config.onoff.offline;
- debugs(16, DBG_IMPORTANT, "offline_mode now " << (Config.onoff.offline ? "ON" : "OFF") << " by Cache Manager request.");
-
- storeAppendPrintf(sentry, "offline_mode is now %s\n",
- Config.onoff.offline ? "ON" : "OFF");
+ Mgr::Action::Pointer action = cmd->profile->creator->create(cmd);
+ Must(action != NULL);
+ action->run(entry, true);
}
-/// \ingroup CacheManagerInternal
-CacheManager::OfflineToggleAction::OfflineToggleAction() : CacheManagerAction ("offline_toggle", "Toggle offline_mode setting", 1, 1) { }
/*
\ingroup CacheManagerInternal
* Also doubles as a check for the protection level.
*/
const char *
-CacheManager::ActionProtection(const CacheManagerAction * at)
+CacheManager::ActionProtection(const Mgr::ActionProfile::Pointer &profile)
{
- char *pwd;
- assert(at);
- pwd = PasswdGet(Config.passwd_list, at->action);
+ assert(profile != NULL);
+ const char *pwd = PasswdGet(Config.passwd_list, profile->name);
if (!pwd)
- return at->flags.pw_req ? "hidden" : "public";
+ return profile->isPwReq ? "hidden" : "public";
if (!strcmp(pwd, "disable"))
return "disabled";
return "protected";
}
-/// \ingroup CacheManagerInternal
-void
-CacheManager::MenuAction::run(StoreEntry * sentry)
-{
- CacheManagerActionList::iterator a;
-
- debugs(16, 4, "CacheManager::MenuCommand invoked");
- for (a = cmgr->ActionsList.begin(); a != cmgr->ActionsList.end(); ++a) {
- debugs(16, 5, " showing action " << (*a)->action);
- storeAppendPrintf(sentry, " %-22s\t%-32s\t%s\n",
- (*a)->action, (*a)->desc, cmgr->ActionProtection(*a));
- }
-}
-/// \ingroup CacheManagerInternal
-CacheManager::MenuAction::MenuAction(CacheManager *aMgr) : CacheManagerAction ("menu", "Cache Manager Menu", 0, 1), cmgr(aMgr) { }
-
/*
\ingroup CacheManagerInternal
* gets from the global Config the password the user would need to supply
if (instance == 0) {
debugs(16, 6, "CacheManager::GetInstance: starting cachemanager up");
instance = new CacheManager;
+ Mgr::RegisterBasics();
}
return instance;
}
-
-
-/// \ingroup CacheManagerInternal
-void CacheManagerActionLegacy::run(StoreEntry *sentry)
-{
- handler(sentry);
-}
-/// \ingroup CacheManagerInternal
-CacheManagerAction::CacheManagerAction(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic)
-{
- flags.pw_req = isPwReq;
- flags.atomic = isAtomic;
- action = xstrdup (anAction);
- desc = xstrdup (aDesc);
-}
-/// \ingroup CacheManagerInternal
-CacheManagerAction::~CacheManagerAction()
-{
- xfree(action);
- xfree(desc);
-}
-
-/// \ingroup CacheManagerInternal
-CacheManagerActionLegacy::CacheManagerActionLegacy(char const *anAction, char const *aDesc, unsigned int isPwReq, unsigned int isAtomic, OBJH *aHandler) : CacheManagerAction(anAction, aDesc, isPwReq, isAtomic), handler(aHandler)
-{
-}
*/
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
static void
carpRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("carp", "CARP information", carpCachemgr, 0, 1);
+ Mgr::RegisterAction("carp", "CARP information", carpCachemgr, 0, 1);
}
void
*/
#include "cbdata.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#if CBDATA_DEBUG
#include "Stack.h"
void
cbdataRegisterWithCacheManager(void)
{
- CacheManager *manager=CacheManager::GetInstance();
- manager->registerAction("cbdata",
+ Mgr::RegisterAction("cbdata",
"Callback Data Registry Contents",
cbdataDump, 0, 1);
#if CBDATA_DEBUG
- manager->registerAction("cbdatahistory",
+ Mgr::RegisterAction("cbdatahistory",
"Detailed call history for all current cbdata contents",
cbdataDumpHistory, 0, 1);
#endif
#include "squid.h"
#include "event.h"
-#include "CacheManager.h"
#include "ClientInfo.h"
#include "ip/Address.h"
+#include "mgr/Registration.h"
#include "SquidMath.h"
#include "SquidTime.h"
#include "Store.h"
static void
clientdbRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("client_list", "Cache Client List", clientdbDump, 0, 1);
+ Mgr::RegisterAction("client_list", "Cache Client List", clientdbDump, 0, 1);
}
void
#include "squid.h"
#include "comm_epoll.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "fde.h"
#include "SquidTime.h"
static void
commEPollRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("comm_epoll_incoming",
+ Mgr::RegisterAction("comm_epoll_incoming",
"comm_incoming() stats",
commIncomingStats, 0, 1);
}
#if USE_KQUEUE
#include "comm_kqueue.h"
-#include "CacheManager.h"
#include "Store.h"
#include "fde.h"
#include "SquidTime.h"
#include "squid.h"
#include "comm_poll.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "SquidTime.h"
#include "Store.h"
#include "fde.h"
static void
commPollRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("comm_poll_incoming",
+ Mgr::RegisterAction("comm_poll_incoming",
"comm_incoming() stats",
commIncomingStats, 0, 1);
}
#include "squid.h"
#include "comm_select.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "SquidTime.h"
#if USE_SELECT
static void
commSelectRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("comm_select_incoming",
+ Mgr::RegisterAction("comm_select_incoming",
"comm_incoming() stats",
commIncomingStats, 0, 1);
}
#include "squid.h"
#include "comm_select.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "SquidTime.h"
#if USE_SELECT_WIN32
static void
commSelectRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("comm_select_incoming",
+ Mgr::RegisterAction("comm_select_incoming",
"comm_incoming() stats",
commIncomingStats, 0, 1);
}
#if DELAY_POOLS
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "DelaySpec.h"
#include "DelayPools.h"
#include "event.h"
void
DelayPools::RegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("delay", "Delay Pool Levels", Stats, 0, 1);
+ Mgr::RegisterAction("delay", "Delay Pool Levels", Stats, 0, 1);
}
void
#include "Store.h"
#include "wordlist.h"
#include "SquidTime.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "helper.h"
/* MS VisualStudio Projects are monolitich, so we need the following
static void
dnsRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("dns", "Dnsserver Statistics", dnsStats, 0, 1);
+ Mgr::RegisterAction("dns", "Dnsserver Statistics", dnsStats, 0, 1);
}
void
#include "config.h"
#include "squid.h"
#include "event.h"
-#include "CacheManager.h"
#include "SquidTime.h"
#include "Store.h"
#include "comm.h"
#include "fde.h"
#include "ip/tools.h"
#include "MemBuf.h"
+#include "mgr/Registration.h"
#include "util.h"
#include "wordlist.h"
static void
idnsRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("idns", "Internal DNS Statistics", idnsStats, 0, 1);
+ Mgr::RegisterAction("idns", "Internal DNS Statistics", idnsStats, 0, 1);
}
void
#include "config.h"
#include "compat/drand48.h"
-#include "CacheManager.h"
#include "event.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "SquidTime.h"
void
eventInit(void)
{
- CacheManager::GetInstance()->
- registerAction("events", "Event Queue", eventDump, 0, 1);
+ Mgr::RegisterAction("events", "Event Queue", eventDump, 0, 1);
}
static void
*/
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "ExternalACL.h"
#include "ExternalACLEntry.h"
#include "auth/UserRequest.h"
static void
externalAclRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("external_acl",
+ Mgr::RegisterAction("external_acl",
"External ACL stats",
externalAclStats, 0, 1);
}
#include "icmp/net_db.h"
#include "ip/Intercept.h"
#include "ip/tools.h"
+#include "mgr/Registration.h"
static PSC fwdStartCompleteWrapper;
static PF fwdServerClosedWrapper;
void
FwdState::RegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("forward", "Request Forwarding Statistics", fwdStats, 0, 1);
+ Mgr::RegisterAction("forward", "Request Forwarding Statistics", fwdStats, 0, 1);
}
void
#include "squid.h"
#include "cbdata.h"
#include "event.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "SquidTime.h"
#include "Store.h"
#include "wordlist.h"
static void
fqdncacheRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("fqdncache", "FQDN Cache Stats and Contents",
+ Mgr::RegisterAction("fqdncache", "FQDN Cache Stats and Contents",
fqdnStats, 0, 1);
}
#include "StoreFileSystem.h"
#include "StoreFScoss.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "CossSwapDir.h"
#include "store_coss.h"
void
StoreFScoss::registerWithCacheManager()
{
- CacheManager::GetInstance()->registerAction("coss", "COSS Stats", Stats, 0, 1);
+ Mgr::RegisterAction("coss", "COSS Stats", Stats, 0, 1);
}
void
#include "log/File.h"
#include "cbdata.h"
#include "event.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "SwapDir.h"
#include "HttpRequest.h"
static void
netdbRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("netdb", "Network Measurement Database", netdbDump, 0, 1);
+ Mgr::RegisterAction("netdb", "Network Measurement Database", netdbDump, 0, 1);
}
#endif /* USE_ICMP */
#include "config.h"
+#include "base/TextException.h"
+#include "CacheManager.h"
#include "comm.h"
#include "ipc/Coordinator.h"
#include "ipc/FdNotes.h"
#include "ipc/SharedListen.h"
+#include "mgr/Inquirer.h"
+#include "mgr/Request.h"
+#include "mgr/Response.h"
+#include "mgr/StoreToCommWriter.h"
CBDATA_NAMESPACED_CLASS_INIT(Ipc, Coordinator);
Ipc::StrandCoord* Ipc::Coordinator::findStrand(int kidId)
{
- typedef Strands::iterator SI;
- for (SI iter = strands.begin(); iter != strands.end(); ++iter) {
+ typedef StrandCoords::iterator SI;
+ for (SI iter = strands_.begin(); iter != strands_.end(); ++iter) {
if (iter->kidId == kidId)
return &(*iter);
}
if (StrandCoord* found = findStrand(strand.kidId))
*found = strand;
else
- strands.push_back(strand);
+ strands_.push_back(strand);
}
void Ipc::Coordinator::receive(const TypedMsgHdr& message)
handleSharedListenRequest(SharedListenRequest(message));
break;
+ case mtCacheMgrRequest:
+ debugs(54, 6, HERE << "Cache manager request");
+ handleCacheMgrRequest(Mgr::Request(message));
+ break;
+
+ case mtCacheMgrResponse:
+ debugs(54, 6, HERE << "Cache manager response");
+ handleCacheMgrResponse(Mgr::Response(message));
+ break;
+
default:
debugs(54, 1, HERE << "Unhandled message type: " << message.type());
break;
SendMessage(MakeAddr(strandAddrPfx, request.requestorId), message);
}
+void
+Ipc::Coordinator::handleCacheMgrRequest(const Mgr::Request& request)
+{
+ debugs(54, 4, HERE);
+
+ // Let the strand know that we are now responsible for handling the request
+ Mgr::Response response(request.requestId);
+ TypedMsgHdr message;
+ response.pack(message);
+ SendMessage(MakeAddr(strandAddrPfx, request.requestorId), message);
+
+ Mgr::Action::Pointer action =
+ CacheManager::GetInstance()->createRequestedAction(request.params);
+ AsyncJob::Start(new Mgr::Inquirer(action,
+ Mgr::ImportHttpFdIntoComm(request.fd), request, strands_));
+}
+
+void
+Ipc::Coordinator::handleCacheMgrResponse(const Mgr::Response& response)
+{
+ Mgr::Inquirer::HandleRemoteAck(response);
+}
+
int
Ipc::Coordinator::openListenSocket(const SharedListenRequest& request,
int &errNo)
void Ipc::Coordinator::broadcastSignal(int sig) const
{
- typedef Strands::const_iterator SCI;
- for (SCI iter = strands.begin(); iter != strands.end(); ++iter) {
+ typedef StrandCoords::const_iterator SCI;
+ for (SCI iter = strands_.begin(); iter != strands_.end(); ++iter) {
debugs(54, 5, HERE << "signal " << sig << " to kid" << iter->kidId <<
", PID=" << iter->pid);
kill(iter->pid, sig);
// Strands do not re-register, even process death would be pointless.
return TheInstance;
}
+
+const Ipc::StrandCoords&
+Ipc::Coordinator::strands() const
+{
+ return strands_;
+}
#include "Array.h"
-#include <map>
-#include "ipc/Port.h"
#include "ipc/Messages.h"
+#include "ipc/Port.h"
#include "ipc/SharedListen.h"
+#include "ipc/StrandCoords.h"
+#include "mgr/forward.h"
+
+#include <map>
namespace Ipc
{
void broadcastSignal(int sig) const; ///< send sig to registered strands
+ const StrandCoords &strands() const; ///< currently registered strands
+
protected:
virtual void start(); // Port (AsyncJob) API
virtual void receive(const TypedMsgHdr& message); // Port API
/// returns cached socket or calls openListenSocket()
void handleSharedListenRequest(const SharedListenRequest& request);
+ void handleCacheMgrRequest(const Mgr::Request& request);
+ void handleCacheMgrResponse(const Mgr::Response& response);
/// calls comm_open_listener()
int openListenSocket(const SharedListenRequest& request, int &errNo);
private:
- typedef Vector<StrandCoord> Strands; ///< unsorted strands
- Strands strands; ///< registered processes and threads
+ StrandCoords strands_; ///< registered processes and threads
typedef std::map<OpenListenerParams, int> Listeners; ///< params:fd map
Listeners listeners; ///< cached comm_open_listener() results
Kid.h \
Kids.cc \
Kids.h \
- Messages.cc \
Messages.h \
StartListening.cc \
StartListening.h \
+ StrandCoord.cc \
+ StrandCoord.h \
+ StrandCoords.h \
SharedListen.cc \
SharedListen.h \
TypedMsgHdr.cc \
Port.cc \
Port.h \
Strand.cc \
- Strand.h
+ Strand.h \
+ \
+ forward.h
DEFS += -DDEFAULT_PREFIX=\"$(prefix)\"
#ifndef SQUID_IPC_MESSAGES_H
#define SQUID_IPC_MESSAGES_H
+#include "ipc/forward.h"
#include <sys/types.h>
/** Declarations used by varios IPC messages */
namespace Ipc
{
-class TypedMsgHdr;
-
/// message class identifier
typedef enum { mtNone = 0, mtRegistration,
- mtSharedListenRequest, mtSharedListenResponse
+ mtSharedListenRequest, mtSharedListenResponse,
+ mtCacheMgrRequest, mtCacheMgrResponse
} MessageType;
-/// Strand location details
-class StrandCoord
-{
-public:
- StrandCoord(); ///< unknown location
- StrandCoord(int akidId, pid_t aPid); ///< from registrant
- explicit StrandCoord(const TypedMsgHdr &hdrMsg); ///< from recvmsg()
- void pack(TypedMsgHdr &hdrMsg) const; ///< prepare for sendmsg()
-
-public:
- int kidId; ///< internal Squid process number
- pid_t pid; ///< OS process or thread identifier
-};
-
} // namespace Ipc;
{
public:
Port(const String &aListenAddr);
-
-protected:
/// calculates IPC message address for strand #id at path
static String MakeAddr(const char *path, int id);
+protected:
virtual void start() = 0; // UdsOp (AsyncJob) API; has body
virtual bool doneAll() const; // UdsOp (AsyncJob) API
Ipc::SharedListenRequest::SharedListenRequest(const TypedMsgHdr &hdrMsg)
{
- hdrMsg.getData(mtSharedListenRequest, this, sizeof(*this));
+ hdrMsg.checkType(mtSharedListenRequest);
+ hdrMsg.getPod(*this);
}
void Ipc::SharedListenRequest::pack(TypedMsgHdr &hdrMsg) const
{
- hdrMsg.putData(mtSharedListenRequest, this, sizeof(*this));
+ hdrMsg.setType(mtSharedListenRequest);
+ hdrMsg.putPod(*this);
}
Ipc::SharedListenResponse::SharedListenResponse(const TypedMsgHdr &hdrMsg):
fd(-1), errNo(0), mapId(-1)
{
- hdrMsg.getData(mtSharedListenResponse, this, sizeof(*this));
+ hdrMsg.checkType(mtSharedListenResponse);
+ hdrMsg.getPod(*this);
fd = hdrMsg.getFd();
}
void Ipc::SharedListenResponse::pack(TypedMsgHdr &hdrMsg) const
{
- hdrMsg.putData(mtSharedListenResponse, this, sizeof(*this));
+ hdrMsg.setType(mtSharedListenResponse);
+ hdrMsg.putPod(*this);
hdrMsg.putFd(fd);
}
#include "config.h"
#include "base/TextException.h"
#include "ipc/Strand.h"
+#include "ipc/StrandCoord.h"
#include "ipc/Messages.h"
#include "ipc/SharedListen.h"
#include "ipc/Kids.h"
+#include "mgr/Request.h"
+#include "mgr/Response.h"
+#include "mgr/Forwarder.h"
+#include "CacheManager.h"
CBDATA_NAMESPACED_CLASS_INIT(Ipc, Strand);
SharedListenJoined(SharedListenResponse(message));
break;
+ case mtCacheMgrRequest:
+ handleCacheMgrRequest(Mgr::Request(message));
+ break;
+
+ case mtCacheMgrResponse:
+ handleCacheMgrResponse(Mgr::Response(message));
+ break;
+
default:
debugs(54, 1, HERE << "Unhandled message type: " << message.type());
break;
}
}
+void Ipc::Strand::handleCacheMgrRequest(const Mgr::Request& request)
+{
+ Mgr::Action::Pointer action =
+ CacheManager::GetInstance()->createRequestedAction(request.params);
+ action->respond(request);
+}
+
+void Ipc::Strand::handleCacheMgrResponse(const Mgr::Response& response)
+{
+ Mgr::Forwarder::HandleRemoteAck(response.requestId);
+}
+
void Ipc::Strand::timedout()
{
debugs(54, 6, HERE << isRegistered);
#define SQUID_IPC_STRAND_H
#include "ipc/Port.h"
+#include "mgr/forward.h"
namespace Ipc
{
class StrandCoord;
-class Descriptor;
/// Receives coordination messages on behalf of its process or thread
class Strand: public Port
private:
void registerSelf(); /// let Coordinator know this strand exists
void handleRegistrationResponse(const StrandCoord &strand);
- void putDescriptor(const Descriptor &message);
+ void handleCacheMgrRequest(const Mgr::Request& request);
+ void handleCacheMgrResponse(const Mgr::Response& response);
private:
bool isRegistered; ///< whether Coordinator ACKed registration (unused)
#include "config.h"
#include "ipc/Messages.h"
+#include "ipc/StrandCoord.h"
#include "ipc/TypedMsgHdr.h"
Ipc::StrandCoord::StrandCoord(const TypedMsgHdr &hdrMsg): kidId(-1), pid(0)
{
- hdrMsg.getData(mtRegistration, this, sizeof(*this));
+ hdrMsg.checkType(mtRegistration);
+ hdrMsg.getPod(*this);
}
void Ipc::StrandCoord::pack(TypedMsgHdr &hdrMsg) const
{
- hdrMsg.putData(mtRegistration, this, sizeof(*this));
+ hdrMsg.setType(mtRegistration);
+ hdrMsg.putPod(*this);
}
--- /dev/null
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_STRAND_COORD_H
+#define SQUID_IPC_STRAND_COORD_H
+
+#include "ipc/forward.h"
+#include <sys/types.h>
+
+namespace Ipc
+{
+
+/// Strand location details
+class StrandCoord
+{
+public:
+ StrandCoord(); ///< unknown location
+ StrandCoord(int akidId, pid_t aPid); ///< from registrant
+ explicit StrandCoord(const TypedMsgHdr &hdrMsg); ///< from recvmsg()
+ void pack(TypedMsgHdr &hdrMsg) const; ///< prepare for sendmsg()
+
+public:
+ int kidId; ///< internal Squid process number
+ pid_t pid; ///< OS process or thread identifier
+};
+
+} // namespace Ipc;
+
+#endif /* SQUID_IPC_STRAND_COORD_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ */
+
+#ifndef SQUID_IPC_STRAND_COORDS_H
+#define SQUID_IPC_STRAND_COORDS_H
+
+#include "ipc/StrandCoord.h"
+#include <vector>
+
+namespace Ipc {
+
+/// a collection of strand coordinates; the order, if any, is owner-dependent
+typedef std::vector<StrandCoord> StrandCoords;
+
+}; // namespace Ipc
+
+#endif /* SQUID_IPC_STRAND_COORDS_H */
} else {
Must(!msg_controllen && !msg_control);
}
+ offset = 0;
}
}
void
-Ipc::TypedMsgHdr::getData(int destType, void *raw, size_t size) const
+Ipc::TypedMsgHdr::checkType(int destType) const
{
Must(type() == destType);
- Must(size == data.size);
- xmemcpy(raw, data.raw, size);
}
void
-Ipc::TypedMsgHdr::putData(int aType, const void *raw, size_t size)
+Ipc::TypedMsgHdr::setType(int aType)
{
- Must(size <= sizeof(data.raw));
- allocData();
- data.type_ = aType;
- data.size = size;
- xmemcpy(data.raw, raw, size);
+ if (data.type_) {
+ Must(data.type_ == aType);
+ } else {
+ allocData();
+ data.type_ = aType;
+ }
+}
+
+int
+Ipc::TypedMsgHdr::getInt() const
+{
+ int n = 0;
+ getPod(n);
+ return n;
+}
+
+void
+Ipc::TypedMsgHdr::putInt(const int n)
+{
+ putPod(n);
+}
+
+void
+Ipc::TypedMsgHdr::getString(String &s) const
+{
+ const int length = getInt();
+ Must(length >= 0);
+ // String uses memcpy uncoditionally; TODO: SBuf eliminates this check
+ if (!length) {
+ s.clean();
+ return;
+ }
+
+ Must(length <= maxSize);
+ // TODO: use SBuf.reserve() instead of a temporary buffer
+ char buf[length];
+ getRaw(&buf, length);
+ s.limitInit(buf, length);
+}
+
+void
+Ipc::TypedMsgHdr::putString(const String &s)
+{
+ Must(s.psize() <= maxSize);
+ putInt(s.psize());
+ putRaw(s.rawBuf(), s.psize());
+}
+
+void
+Ipc::TypedMsgHdr::getFixed(void *raw, size_t size) const
+{
+ // no need to load size because it is constant
+ getRaw(raw, size);
+}
+
+void
+Ipc::TypedMsgHdr::putFixed(const void *raw, size_t size)
+{
+ // no need to store size because it is constant
+ putRaw(raw, size);
+}
+
+/// low-level loading of exactly size bytes of raw data
+void
+Ipc::TypedMsgHdr::getRaw(void *raw, size_t size) const
+{
+ Must(size >= 0);
+ if (size > 0) {
+ Must(size <= data.size - offset);
+ xmemcpy(raw, data.raw + offset, size);
+ offset += size;
+ }
+}
+
+/// low-level storage of exactly size bytes of raw data
+void
+Ipc::TypedMsgHdr::putRaw(const void *raw, size_t size)
+{
+ Must(size >= 0);
+ if (size > 0) {
+ Must(size <= sizeof(data.raw) - data.size);
+ xmemcpy(data.raw + data.size, raw, size);
+ data.size += size;
+ }
}
void
#include <sys/un.h>
#endif
+class String;
+
namespace Ipc
{
/// struct msghdr with a known type, fixed-size I/O and control buffers
class TypedMsgHdr: public msghdr
{
+public:
+ enum {maxSize = 4096};
+
public:
TypedMsgHdr();
TypedMsgHdr(const TypedMsgHdr &tmh);
TypedMsgHdr &operator =(const TypedMsgHdr &tmh);
- // type-safe access to message details
+ void address(const struct sockaddr_un &addr); ///< sets [dest.] address
+
+ /* message type manipulation; these must be called before put/get*() */
+ void setType(int aType); ///< sets message type; use MessageType enum
+ void checkType(int aType) const; ///< throws if stored type is not aType
int type() const; ///< returns stored type or zero if none
- void address(const struct sockaddr_un& addr); ///< sets [dest.] address
- void getData(int ofType, void *raw, size_t size) const; ///< checks type
- void putData(int aType, const void *raw, size_t size); ///< stores type
+
+ /* access for Plain Old Data (POD)-based message parts */
+ template <class Pod>
+ void getPod(Pod &pod) const { getFixed(&pod, sizeof(pod)); } ///< load POD
+ template <class Pod>
+ void putPod(const Pod &pod) { putFixed(&pod, sizeof(pod)); } ///< store POD
+
+ /* access to message parts for selected commonly-used part types */
+ void getString(String &s) const; ///< load variable-length string
+ void putString(const String &s); ///< store variable-length string
+ int getInt() const; ///< load an integer
+ void putInt(int n); ///< store an integer
+ void getFixed(void *raw, size_t size) const; ///< always load size bytes
+ void putFixed(const void *raw, size_t size); ///< always store size bytes
+
+ /// returns true if there is data to extract; handy for optional parts
+ bool hasMoreData() const { return offset < data.size; }
+
+ /* access to a "file" descriptor that can be passed between processes */
void putFd(int aFd); ///< stores descriptor
int getFd() const; ///< returns descriptor
- /// raw, type-independent access for I/O
+ /* raw, type-independent access for I/O */
void prepForReading(); ///< reset and provide all buffers
char *raw() { return reinterpret_cast<char*>(this); }
const char *raw() const { return reinterpret_cast<const char*>(this); }
void allocName();
void allocControl();
+ /* raw, type-independent manipulation used by type-specific methods */
+ void getRaw(void *raw, size_t size) const;
+ void putRaw(const void *raw, size_t size);
+
private:
struct sockaddr_un name; ///< same as .msg_name
struct DataBuffer {
int type_; ///< Message kind, uses MessageType values
size_t size; ///< actual raw data size (for sanity checks)
- char raw[250]; ///< buffer with type-specific data
+ char raw[maxSize]; ///< buffer with type-specific data
} data; ///< same as .msg_iov[0].iov_base
struct CtrlBuffer {
char raw[CMSG_SPACE(sizeof(int))]; ///< control buffer space for one fd
} ctrl; ///< same as .msg_control
+
+ /// data offset for the next get/put*() to start with
+ mutable unsigned int offset;
};
} // namespace Ipc
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 54 Interprocess Communication
+ *
+ */
+
+#ifndef SQUID_IPC_FORWARD_H
+#define SQUID_IPC_FORWARD_H
+
+#include "config.h"
+
+namespace Ipc
+{
+
+class TypedMsgHdr;
+class StrandCoord;
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_FORWARD_H */
*/
#include "squid.h"
-#include "CacheManager.h"
#include "cbdata.h"
#include "event.h"
#include "ip/Address.h"
#include "ip/tools.h"
+#include "mgr/Registration.h"
#include "SquidTime.h"
#include "Store.h"
#include "wordlist.h"
static void
ipcacheRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("ipcache",
+ Mgr::RegisterAction("ipcache",
"IP Cache Stats and Contents",
stat_ipcache_get, 0, 1);
}
#include "errorpage.h"
#include "err_detail_type.h"
#include "acl/Checklist.h"
-#include "CacheManager.h"
+#include "errorpage.h"
#if USE_SQUID_EUI
#include "eui/Eui48.h"
#include "eui/Eui64.h"
#include "HttpRequest.h"
#include "log/File.h"
#include "MemBuf.h"
+#include "mgr/Registration.h"
#include "rfc1738.h"
#include "SquidTime.h"
static void
fvdbRegisterWithCacheManager(void)
{
- CacheManager *manager=CacheManager::GetInstance();
- manager->registerAction("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1);
- manager->registerAction("forw_headers", "X-Forwarded-For Request Headers",
+ Mgr::RegisterAction("via_headers", "Via Request Headers", fvdbDumpVia, 0, 1);
+ Mgr::RegisterAction("forw_headers", "X-Forwarded-For Request Headers",
fvdbDumpForw, 0, 1);
}
#include "squid.h"
#include "event.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "ClientInfo.h"
#include "Mem.h"
#include "memMeter.h"
void
Mem::RegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->registerAction("mem", "Memory Utilization",
- Mem::Stats, 0, 1);
+ Mgr::RegisterAction("mem", "Memory Utilization", Mem::Stats, 0, 1);
}
mem_type &operator++ (mem_type &aMem)
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "HttpReply.h"
+#include "ipc/Port.h"
+#include "mgr/ActionCreator.h"
+#include "mgr/Action.h"
+#include "mgr/ActionParams.h"
+#include "mgr/ActionProfile.h"
+#include "mgr/Command.h"
+#include "mgr/Request.h"
+#include "mgr/Response.h"
+#include "SquidTime.h"
+#include "Store.h"
+
+
+Mgr::Action::Action(const Command::Pointer &aCmd): cmd(aCmd)
+{
+ Must(cmd != NULL);
+ Must(cmd->profile != NULL);
+}
+
+Mgr::Action::~Action()
+{
+}
+
+const Mgr::Command &
+Mgr::Action::command() const
+{
+ Must(cmd != NULL);
+ return *cmd;
+}
+
+bool
+Mgr::Action::atomic() const
+{
+ return command().profile->isAtomic;
+}
+
+const char*
+Mgr::Action::name() const
+{
+ return command().profile->name;
+}
+
+StoreEntry*
+Mgr::Action::createStoreEntry() const
+{
+ const ActionParams ¶ms = command().params;
+ const char *uri = params.httpUri.termedBuf();
+ return storeCreateEntry(uri, uri, params.httpFlags, params.httpMethod);
+}
+
+void
+Mgr::Action::add(const Action& action)
+{
+}
+
+void
+Mgr::Action::respond(const Request& request)
+{
+ debugs(16, 5, HERE);
+
+ // Assume most kid classes are fully aggregatable (i.e., they do not dump
+ // local info at all). Do not import the remote HTTP fd into our Comm
+ // space; collect and send an IPC msg with collected info to Coordinator.
+ ::close(request.fd);
+ collect();
+ sendResponse(request.requestId);
+}
+
+void
+Mgr::Action::sendResponse(unsigned int requestId)
+{
+ Response response(requestId, this);
+ Ipc::TypedMsgHdr message;
+ response.pack(message);
+ Ipc::SendMessage(Ipc::coordinatorAddr, message);
+}
+
+void
+Mgr::Action::run(StoreEntry* entry, bool writeHttpHeader)
+{
+ debugs(16, 5, HERE);
+ collect();
+ fillEntry(entry, writeHttpHeader);
+}
+
+void
+Mgr::Action::fillEntry(StoreEntry* entry, bool writeHttpHeader)
+{
+ debugs(16, 5, HERE);
+ entry->buffer();
+
+ if (writeHttpHeader) {
+ HttpReply *rep = new HttpReply;
+ rep->setHeaders(HTTP_OK, NULL, "text/plain", -1, squid_curtime, squid_curtime);
+ entry->replaceHttpReply(rep);
+ }
+
+ dump(entry);
+
+ entry->flush();
+
+ if (atomic())
+ entry->complete();
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_ACTION_H
+#define SQUID_MGR_ACTION_H
+
+#include "ipc/forward.h"
+#include "mgr/forward.h"
+
+class StoreEntry;
+
+namespace Mgr
+{
+
+/// Base API for organizing the processing of a compiled cache manager command.
+/// Not a job because all methods are synchronous (but they may start jobs).
+class Action: public RefCountable
+{
+public:
+ typedef RefCount<Action> Pointer;
+
+public:
+ Action(const CommandPointer &aCmd);
+ virtual ~Action();
+
+
+ /* for local Cache Manager use */
+
+ /// collect + fillEntry: collect local information and fill the store entry
+ void run(StoreEntry *entry, bool writeHttpHeader);
+
+ /// prepare store entry, dump info, close store entry (if possible)
+ void fillEntry(StoreEntry *entry, bool writeHttpHeader);
+
+
+ /* for global Coordinator use */
+
+ /// incrementally merge in remote information (of the same action type)
+ virtual void add(const Action &action);
+
+
+ /* global-local communication */
+
+ /// respond to Coordinator request; default is to collect and sendResponse
+ virtual void respond(const Request &request);
+
+ /// pack collected action info into a message to be sent to Coordinator
+ virtual void pack(Ipc::TypedMsgHdr &msg) const {}
+ /// unpack action info from the message received by Coordinator
+ virtual void unpack(const Ipc::TypedMsgHdr &msg) {}
+
+ /// notify Coordinator that this action is done with local processing
+ void sendResponse(unsigned int requestId);
+
+
+ /* Action properties */
+
+ /// whether at least some local kid info can be combined and, hence, the
+ /// combined data should be written at the end of the coordinated response
+ virtual bool aggregatable() const { return true; } // most kid classes are
+
+ bool atomic() const; ///< dump() call writes everything before returning
+ const char *name() const; ///< label as seen in the cache manager menu
+ const Command &command() const; ///< the cause of this action
+
+ StoreEntry *createStoreEntry() const; ///< creates store entry from params
+
+protected:
+ /// calculate and keep local action-specific information
+ virtual void collect() {}
+
+ /** start writing action-specific info to Store entry;
+ * may collect info during dump, especially if collect() did nothing
+ * non-atomic() actions may continue writing asynchronously after returning
+ */
+ virtual void dump(StoreEntry *entry) {}
+
+
+private:
+ const CommandPointer cmd; ///< the command that caused this action
+
+
+private:
+ Action(const Action &); // not implemented
+ Action &operator= (const Action &); // not implemented
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_ACTION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_ACTION_CREATOR_H
+#define SQUID_MGR_ACTION_CREATOR_H
+
+#include "mgr/forward.h"
+
+namespace Mgr
+{
+
+/** Creates objects of the right Action class, parameterized with Command.
+ * A part of the Action profile that allows Cache Manager be ignorant about
+ * specific Action classes (\see Mgr::ActionProfile).
+ */
+class ActionCreator: public RefCountable
+{
+public:
+ typedef RefCount<ActionCreator> Pointer;
+
+ virtual ~ActionCreator() {}
+
+ /// returns a pointer to the new Action object for cmd; never nil
+ virtual ActionPointer create(const CommandPointer &cmd) const = 0;
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_ACTION_CREATOR_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/ActionParams.h"
+
+Mgr::ActionParams::ActionParams(): httpMethod(METHOD_NONE) {
+}
+
+Mgr::ActionParams::ActionParams(const Ipc::TypedMsgHdr &msg)
+{
+ msg.getString(httpUri);
+
+ const int m = msg.getInt();
+ Must(METHOD_NONE <= m && m < METHOD_ENUM_END);
+ httpMethod = static_cast<_method_t>(m);
+
+ msg.getPod(httpFlags);
+
+ msg.getString(actionName);
+ msg.getString(userName);
+ msg.getString(password);
+}
+
+void
+Mgr::ActionParams::pack(Ipc::TypedMsgHdr &msg) const
+{
+ msg.putString(httpUri);
+ msg.putInt(httpMethod);
+ msg.putPod(httpFlags);
+
+ msg.putString(actionName);
+ msg.putString(userName);
+ msg.putString(password);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_ACTION_PARAMS_H
+#define SQUID_MGR_ACTION_PARAMS_H
+
+#include "HttpRequestMethod.h"
+#include "ipc/forward.h"
+
+namespace Mgr
+{
+
+/// Cache Manager Action parameters extracted from the user request
+class ActionParams
+{
+public:
+ ActionParams();
+
+ explicit ActionParams(const Ipc::TypedMsgHdr &msg); ///< load from msg
+ void pack(Ipc::TypedMsgHdr &msg) const; ///< store into msg
+
+public:
+ /* details of the client HTTP request that caused the action */
+ String httpUri; ///< HTTP request URI
+ _method_t httpMethod; ///< HTTP request method
+ request_flags httpFlags; ///< HTTP request flags
+
+ /* action parameters extracted from the client HTTP request */
+ String actionName; ///< action name (and credentials realm)
+ String userName; ///< user login name; currently only used for logging
+ String password; ///< user password; used for acceptance check and cleared
+
+};
+
+} // namespace Mgr
+
+std::ostream &operator <<(std::ostream &os, const Mgr::ActionParams ¶ms);
+
+#endif /* SQUID_MGR_ACTION_PARAMS_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_ACTION_PROFILE_H
+#define SQUID_MGR_ACTION_PROFILE_H
+
+#include "mgr/ActionCreator.h"
+#include "mgr/forward.h"
+
+namespace Mgr
+{
+
+/// hard-coded Cache Manager action configuration, including Action creator
+class ActionProfile: public RefCountable
+{
+public:
+ typedef RefCount<ActionProfile> Pointer;
+
+public:
+ ActionProfile(const char* aName, const char* aDesc, bool aPwReq,
+ bool anAtomic, const ActionCreatorPointer &aCreator):
+ name(aName), desc(aDesc), isPwReq(aPwReq), isAtomic(anAtomic),
+ creator(aCreator)
+ {
+ }
+
+public:
+ const char *name; ///< action label to uniquely identify this action
+ const char *desc; ///< action description to build an action menu list
+ bool isPwReq; ///< whether password is required to perform the action
+ bool isAtomic; ///< whether action dumps everything in one dump() call
+ ActionCreatorPointer creator; ///< creates Action objects with this profile
+};
+
+} // namespace Mgr
+
+inline std::ostream &
+operator <<(std::ostream &os, const Mgr::ActionProfile &profile)
+{
+ return os << profile.name;
+}
+
+#endif /* SQUID_MGR_ACTION_PROFILE_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "mgr/ActionWriter.h"
+#include "Store.h"
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Mgr, ActionWriter);
+
+Mgr::ActionWriter::ActionWriter(const Action::Pointer &anAction, int aFd):
+ StoreToCommWriter(aFd, anAction->createStoreEntry()),
+ action(anAction)
+{
+ debugs(16, 5, HERE << "FD " << aFd << " action: " << action);
+}
+
+void
+Mgr::ActionWriter::start()
+{
+ debugs(16, 5, HERE);
+ Must(action != NULL);
+
+ StoreToCommWriter::start();
+ action->fillEntry(entry, false);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_ACTION_WRITER_H
+#define SQUID_MGR_ACTION_WRITER_H
+
+#include "HttpRequestMethod.h"
+#include "mgr/StoreToCommWriter.h"
+
+
+namespace Mgr
+{
+
+/// Creates Store entry, fills it using action's fillEntry(), and
+/// Comm-writes it using parent StoreToCommWriter.
+class ActionWriter: public StoreToCommWriter
+{
+public:
+ ActionWriter(const Action::Pointer &anAction, int aFd);
+
+protected:
+ /* AsyncJob API */
+ virtual void start();
+
+private:
+ Action::Pointer action; ///< action that fills the entry
+
+ CBDATA_CLASS2(ActionWriter);
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_ACTION_WRITER_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "CacheManager.h"
+#include "mgr/ActionCreator.h"
+#include "mgr/ActionProfile.h"
+#include "mgr/BasicActions.h"
+#include "mgr/Registration.h"
+#include "Store.h"
+
+
+Mgr::MenuAction::Pointer
+Mgr::MenuAction::Create(const Command::Pointer &cmd)
+{
+ return new MenuAction(cmd);
+}
+
+Mgr::MenuAction::MenuAction(const Command::Pointer &cmd): Action(cmd)
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::MenuAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+
+ typedef CacheManager::Menu::const_iterator Iterator;
+ const CacheManager::Menu& menu = CacheManager::GetInstance()->menu();
+
+ for (Iterator a = menu.begin(); a != menu.end(); ++a) {
+ storeAppendPrintf(entry, " %-22s\t%-32s\t%s\n",
+ (*a)->name, (*a)->desc,
+ CacheManager::GetInstance()->ActionProtection(*a));
+ }
+}
+
+Mgr::ShutdownAction::Pointer
+Mgr::ShutdownAction::Create(const Command::Pointer &cmd)
+{
+ return new ShutdownAction(cmd);
+}
+
+Mgr::ShutdownAction::ShutdownAction(const Command::Pointer &cmd): Action(cmd)
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::ShutdownAction::dump(StoreEntry* entry)
+{
+ debugs(16, DBG_CRITICAL, "Shutdown by Cache Manager command.");
+ shut_down(SIGTERM);
+}
+
+Mgr::ReconfigureAction::Pointer
+Mgr::ReconfigureAction::Create(const Command::Pointer &cmd)
+{
+ return new ReconfigureAction(cmd);
+}
+
+Mgr::ReconfigureAction::ReconfigureAction(const Command::Pointer &cmd):
+ Action(cmd)
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::ReconfigureAction::dump(StoreEntry* entry)
+{
+ debugs(16, DBG_IMPORTANT, "Reconfigure by Cache Manager command.");
+ storeAppendPrintf(entry, "Reconfiguring Squid Process ....");
+ reconfigure(SIGHUP);
+}
+
+Mgr::RotateAction::Pointer
+Mgr::RotateAction::Create(const Command::Pointer &cmd)
+{
+ return new RotateAction(cmd);
+}
+
+Mgr::RotateAction::RotateAction(const Command::Pointer &cmd): Action(cmd)
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::RotateAction::dump(StoreEntry* entry)
+{
+ debugs(16, DBG_IMPORTANT, "Rotate Logs by Cache Manager command.");
+ storeAppendPrintf(entry, "Rotating Squid Process Logs ....");
+#ifdef _SQUID_LINUX_THREADS_
+ rotate_logs(SIGQUIT);
+#else
+ rotate_logs(SIGUSR1);
+#endif
+}
+
+Mgr::OfflineToggleAction::Pointer
+Mgr::OfflineToggleAction::Create(const Command::Pointer &cmd)
+{
+ return new OfflineToggleAction(cmd);
+}
+
+Mgr::OfflineToggleAction::OfflineToggleAction(const Command::Pointer &cmd):
+ Action(cmd)
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::OfflineToggleAction::dump(StoreEntry* entry)
+{
+ Config.onoff.offline = !Config.onoff.offline;
+ debugs(16, DBG_IMPORTANT, "offline_mode now " << (Config.onoff.offline ? "ON" : "OFF") << " by Cache Manager request.");
+
+ storeAppendPrintf(entry, "offline_mode is now %s\n",
+ Config.onoff.offline ? "ON" : "OFF");
+}
+
+void
+Mgr::RegisterBasics()
+{
+ RegisterAction("offline_toggle", "Toggle offline_mode setting", &Mgr::OfflineToggleAction::Create, 1, 1);
+ RegisterAction("shutdown", "Shut Down the Squid Process", &Mgr::ShutdownAction::Create, 1, 1);
+ RegisterAction("reconfigure", "Reconfigure Squid", &Mgr::ReconfigureAction::Create, 1, 1);
+ RegisterAction("rotate", "Rotate Squid Logs", &Mgr::RotateAction::Create, 1, 1);
+ RegisterAction("menu", "Cache Manager Menu", &Mgr::MenuAction::Create, 0, 1);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_BASIC_ACTIONS_H
+#define SQUID_MGR_BASIC_ACTIONS_H
+
+#include "mgr/Action.h"
+
+/* a collection of simple, mostly stateless actions */
+
+
+namespace Mgr
+{
+
+/// returns available Cache Manager actions and their access requirements
+class MenuAction: public Action
+{
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void dump(StoreEntry *entry);
+
+protected:
+ MenuAction(const CommandPointer &cmd);
+};
+
+
+/// shuts Squid down
+class ShutdownAction: public Action
+{
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void dump(StoreEntry *entry);
+
+protected:
+ ShutdownAction(const CommandPointer &cmd);
+};
+
+/// reconfigures Squid
+class ReconfigureAction: public Action
+{
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void dump(StoreEntry *entry);
+
+protected:
+ ReconfigureAction(const CommandPointer &cmd);
+};
+
+/// starts log rotation
+class RotateAction: public Action
+{
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void dump(StoreEntry *entry);
+
+protected:
+ RotateAction(const CommandPointer &cmd);
+};
+
+/// changes offline mode
+class OfflineToggleAction: public Action
+{
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void dump(StoreEntry *entry);
+
+protected:
+ OfflineToggleAction(const CommandPointer &cmd);
+};
+
+/// Registeres profiles for the actions above; \todo move elsewhere?
+void RegisterBasics();
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_BASIC_ACTIONS_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "mgr/ActionProfile.h"
+#include "mgr/Command.h"
+
+std::ostream &
+operator <<(std::ostream &os, const Mgr::Command &cmd)
+{
+ if (cmd.profile != NULL)
+ return os << *cmd.profile;
+ return os << "undef";
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_COMMAND_H
+#define SQUID_MGR_COMMAND_H
+
+#include "mgr/ActionParams.h"
+#include "mgr/forward.h"
+
+namespace Mgr
+{
+
+/// combined hard-coded action profile with user-supplied action parameters
+class Command: public RefCountable {
+public:
+ typedef RefCount<Command> Pointer;
+
+public:
+ ActionProfilePointer profile; ///< hard-coded action specification
+ ActionParams params; ///< user-supplied action arguments
+};
+
+} // namespace Mgr
+
+std::ostream &operator <<(std::ostream &os, const Mgr::Command &cmd);
+
+#endif /* SQUID_MGR_COMMAND_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/CountersAction.h"
+#include "SquidTime.h"
+#include "Store.h"
+
+
+extern void GetCountersStats(Mgr::CountersActionData& stats);
+extern void DumpCountersStats(Mgr::CountersActionData& stats, StoreEntry* sentry);
+
+Mgr::CountersActionData::CountersActionData()
+{
+ xmemset(this, 0, sizeof(*this));
+}
+
+Mgr::CountersActionData&
+Mgr::CountersActionData::operator += (const CountersActionData& stats)
+{
+ if (timercmp(&sample_time, &stats.sample_time, <))
+ sample_time = stats.sample_time;
+ client_http_requests += stats.client_http_requests;
+ client_http_hits += stats.client_http_hits;
+ client_http_errors += stats.client_http_errors;
+ client_http_kbytes_in += stats.client_http_kbytes_in;
+ client_http_kbytes_out += stats.client_http_kbytes_out;
+ client_http_hit_kbytes_out += stats.client_http_hit_kbytes_out;
+ server_all_requests += stats.server_all_requests;
+ server_all_errors += stats.server_all_errors;
+ server_all_kbytes_in += stats.server_all_kbytes_in;
+ server_all_kbytes_out += stats.server_all_kbytes_out;
+ server_http_requests += stats.server_http_requests;
+ server_http_errors += stats.server_http_errors;
+ server_http_kbytes_in += stats.server_http_kbytes_in;
+ server_http_kbytes_out += stats.server_http_kbytes_out;
+ server_ftp_requests += stats.server_ftp_requests;
+ server_ftp_errors += stats.server_ftp_errors;
+ server_ftp_kbytes_in += stats.server_ftp_kbytes_in;
+ server_ftp_kbytes_out += stats.server_ftp_kbytes_out;
+ server_other_requests += stats.server_other_requests;
+ server_other_errors += stats.server_other_errors;
+ server_other_kbytes_in += stats.server_other_kbytes_in;
+ server_other_kbytes_out += stats.server_other_kbytes_out;
+ icp_pkts_sent += stats.icp_pkts_sent;
+ icp_pkts_recv += stats.icp_pkts_recv;
+ icp_queries_sent += stats.icp_queries_sent;
+ icp_replies_sent += stats.icp_replies_sent;
+ icp_queries_recv += stats.icp_queries_recv;
+ icp_replies_recv += stats.icp_replies_recv;
+ icp_replies_queued += stats.icp_replies_queued;
+ icp_query_timeouts += stats.icp_query_timeouts;
+ icp_kbytes_sent += stats.icp_kbytes_sent;
+ icp_kbytes_recv += stats.icp_kbytes_recv;
+ icp_q_kbytes_sent += stats.icp_q_kbytes_sent;
+ icp_r_kbytes_sent += stats.icp_r_kbytes_sent;
+ icp_q_kbytes_recv += stats.icp_q_kbytes_recv;
+ icp_r_kbytes_recv += stats.icp_r_kbytes_recv;
+#if USE_CACHE_DIGESTS
+ icp_times_used += stats.icp_times_used;
+ cd_times_used += stats.cd_times_used;
+ cd_msgs_sent += stats.cd_msgs_sent;
+ cd_msgs_recv += stats.cd_msgs_recv;
+ cd_memory += stats.cd_memory;
+ cd_local_memory += stats.cd_local_memory;
+ cd_kbytes_sent += stats.cd_kbytes_sent;
+ cd_kbytes_recv += stats.cd_kbytes_recv;
+#endif
+ unlink_requests += stats.unlink_requests;
+ page_faults += stats.page_faults;
+ select_loops += stats.select_loops;
+ cpu_time += stats.cpu_time;
+ wall_time += stats.wall_time;
+ swap_outs += stats.swap_outs;
+ swap_ins += stats.swap_ins;
+ swap_files_cleaned += stats.swap_files_cleaned;
+ aborted_requests += stats.aborted_requests;
+
+ return *this;
+}
+
+Mgr::CountersAction::Pointer
+Mgr::CountersAction::Create(const CommandPointer &cmd)
+{
+ return new CountersAction(cmd);
+}
+
+Mgr::CountersAction::CountersAction(const CommandPointer &cmd):
+ Action(cmd), data()
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::CountersAction::add(const Action& action)
+{
+ debugs(16, 5, HERE);
+ data += dynamic_cast<const CountersAction&>(action).data;
+}
+
+void
+Mgr::CountersAction::collect()
+{
+ debugs(16, 5, HERE);
+ GetCountersStats(data);
+}
+
+void
+Mgr::CountersAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+ DumpCountersStats(data, entry);
+}
+
+void
+Mgr::CountersAction::pack(Ipc::TypedMsgHdr& msg) const
+{
+ msg.setType(Ipc::mtCacheMgrResponse);
+ msg.putPod(data);
+}
+
+void
+Mgr::CountersAction::unpack(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrResponse);
+ msg.getPod(data);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_COUNTERS_ACTION_H
+#define SQUID_MGR_COUNTERS_ACTION_H
+
+#include "mgr/Action.h"
+#include <sys/time.h>
+
+
+namespace Mgr
+{
+
+/// store traffic and resource counters
+class CountersActionData
+{
+public:
+ CountersActionData();
+ CountersActionData& operator += (const CountersActionData& stats);
+
+public:
+ struct timeval sample_time;
+ double client_http_requests;
+ double client_http_hits;
+ double client_http_errors;
+ double client_http_kbytes_in;
+ double client_http_kbytes_out;
+ double client_http_hit_kbytes_out;
+ double server_all_requests;
+ double server_all_errors;
+ double server_all_kbytes_in;
+ double server_all_kbytes_out;
+ double server_http_requests;
+ double server_http_errors;
+ double server_http_kbytes_in;
+ double server_http_kbytes_out;
+ double server_ftp_requests;
+ double server_ftp_errors;
+ double server_ftp_kbytes_in;
+ double server_ftp_kbytes_out;
+ double server_other_requests;
+ double server_other_errors;
+ double server_other_kbytes_in;
+ double server_other_kbytes_out;
+ double icp_pkts_sent;
+ double icp_pkts_recv;
+ double icp_queries_sent;
+ double icp_replies_sent;
+ double icp_queries_recv;
+ double icp_replies_recv;
+ double icp_replies_queued;
+ double icp_query_timeouts;
+ double icp_kbytes_sent;
+ double icp_kbytes_recv;
+ double icp_q_kbytes_sent;
+ double icp_r_kbytes_sent;
+ double icp_q_kbytes_recv;
+ double icp_r_kbytes_recv;
+#if USE_CACHE_DIGESTS
+ double icp_times_used;
+ double cd_times_used;
+ double cd_msgs_sent;
+ double cd_msgs_recv;
+ double cd_memory;
+ double cd_local_memory;
+ double cd_kbytes_sent;
+ double cd_kbytes_recv;
+#endif
+ double unlink_requests;
+ double page_faults;
+ double select_loops;
+ double cpu_time;
+ double wall_time;
+ double swap_outs;
+ double swap_ins;
+ double swap_files_cleaned;
+ double aborted_requests;
+};
+
+/// implement aggregated 'counters' action
+class CountersAction: public Action
+{
+protected:
+ CountersAction(const CommandPointer &cmd);
+
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void add(const Action& action);
+ virtual void pack(Ipc::TypedMsgHdr& msg) const;
+ virtual void unpack(const Ipc::TypedMsgHdr& msg);
+
+protected:
+ /* Action API */
+ virtual void collect();
+ virtual void dump(StoreEntry* entry);
+
+private:
+ CountersActionData data;
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_COUNTERS_ACTION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "mgr/Filler.h"
+#include "mgr/Response.h"
+#include "Store.h"
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Mgr, Filler);
+
+Mgr::Filler::Filler(const Action::Pointer &anAction, int aFd,
+ unsigned int aRequestId):
+ StoreToCommWriter(aFd, anAction->createStoreEntry()),
+ action(anAction),
+ requestId(aRequestId)
+{
+ debugs(16, 5, HERE << "FD " << aFd << " action: " << action);
+}
+
+void
+Mgr::Filler::start()
+{
+ debugs(16, 5, HERE);
+ Must(requestId != 0);
+ Must(action != NULL);
+
+ StoreToCommWriter::start();
+ action->run(entry, false);
+}
+
+void
+Mgr::Filler::swanSong()
+{
+ debugs(16, 5, HERE);
+ action->sendResponse(requestId);
+ StoreToCommWriter::swanSong();
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_FILLER_H
+#define SQUID_MGR_FILLER_H
+
+#include "HttpRequestMethod.h"
+#include "mgr/Action.h"
+#include "mgr/StoreToCommWriter.h"
+
+namespace Mgr
+{
+
+/// provides Coordinator with a local cache manager response
+class Filler: public StoreToCommWriter
+{
+public:
+ Filler(const Action::Pointer &anAction, int aFd, unsigned int aRequestId);
+
+protected:
+ /* AsyncJob API */
+ virtual void start();
+ virtual void swanSong();
+
+private:
+ Action::Pointer action; ///< action that will run() and sendResponse()
+ unsigned int requestId; ///< the ID of the Request we are responding to
+
+ CBDATA_CLASS2(Filler);
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_FILLER_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/AsyncJobCalls.h"
+#include "base/TextException.h"
+#include "CommCalls.h"
+#include "errorpage.h"
+#include "HttpReply.h"
+#include "HttpRequest.h"
+#include "ipc/Port.h"
+#include "mgr/Forwarder.h"
+#include "mgr/Request.h"
+#include "SquidTime.h"
+#include "Store.h"
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Mgr, Forwarder);
+
+Mgr::Forwarder::RequestsMap Mgr::Forwarder::TheRequestsMap;
+unsigned int Mgr::Forwarder::LastRequestId = 0;
+
+Mgr::Forwarder::Forwarder(int aFd, const ActionParams &aParams,
+ HttpRequest* aRequest, StoreEntry* anEntry):
+ AsyncJob("Mgr::Forwarder"),
+ params(aParams),
+ request(aRequest), entry(anEntry), fd(aFd), requestId(0), closer(NULL)
+{
+ debugs(16, 5, HERE << "FD " << aFd);
+ Must(fd >= 0);
+ Must(request != NULL);
+ Must(entry != NULL);
+
+ HTTPMSGLOCK(request);
+ entry->lock();
+ EBIT_SET(entry->flags, ENTRY_FWD_HDR_WAIT);
+
+ closer = asyncCall(16, 5, "Mgr::Forwarder::noteCommClosed",
+ CommCbMemFunT<Forwarder, CommCloseCbParams>(this, &Forwarder::noteCommClosed));
+ comm_add_close_handler(fd, closer);
+}
+
+Mgr::Forwarder::~Forwarder()
+{
+ debugs(16, 5, HERE);
+ Must(request != NULL);
+ Must(entry != NULL);
+ Must(requestId == 0);
+
+ HTTPMSGUNLOCK(request);
+ entry->unregisterAbort();
+ entry->unlock();
+ close();
+}
+
+/// closes our copy of the client HTTP connection socket
+void
+Mgr::Forwarder::close() {
+ if (fd >= 0) {
+ if (closer != NULL) {
+ comm_remove_close_handler(fd, closer);
+ closer = NULL;
+ }
+ comm_close(fd);
+ fd = -1;
+ }
+}
+
+void
+Mgr::Forwarder::start()
+{
+ debugs(16, 3, HERE);
+ entry->registerAbort(&Forwarder::Abort, this);
+
+ typedef NullaryMemFunT<Mgr::Forwarder> Dialer;
+ AsyncCall::Pointer callback = JobCallback(16, 5, Dialer, this,
+ Forwarder::handleRemoteAck);
+ if (++LastRequestId == 0) // don't use zero value as requestId
+ ++LastRequestId;
+ requestId = LastRequestId;
+ TheRequestsMap[requestId] = callback;
+ Request mgrRequest(KidIdentifier, requestId, fd, params);
+ Ipc::TypedMsgHdr message;
+
+ try {
+ mgrRequest.pack(message);
+ }
+ catch (...) {
+ // assume the pack() call failed because the message did not fit
+ // TODO: add a more specific exception?
+ debugs(16, DBG_CRITICAL, "ERROR: uri " << entry->url() << " exceeds buffer size");
+ quitOnError("long URI", errorCon(ERR_INVALID_URL, HTTP_REQUEST_URI_TOO_LARGE, request));
+ }
+
+ Ipc::SendMessage(Ipc::coordinatorAddr, message);
+ const double timeout = 10; // in seconds
+ eventAdd("Mgr::Forwarder::requestTimedOut", &Forwarder::RequestTimedOut,
+ this, timeout, 0, false);
+}
+
+void
+Mgr::Forwarder::swanSong()
+{
+ debugs(16, 5, HERE);
+ removeTimeoutEvent();
+ if (requestId > 0) {
+ DequeueRequest(requestId);
+ requestId = 0;
+ }
+ close();
+}
+
+bool
+Mgr::Forwarder::doneAll() const
+{
+ debugs(16, 5, HERE);
+ return requestId == 0;
+}
+
+/// called when the client socket gets closed by some external force
+void
+Mgr::Forwarder::noteCommClosed(const CommCloseCbParams& params)
+{
+ debugs(16, 5, HERE);
+ Must(fd == params.fd);
+ fd = -1;
+ mustStop("commClosed");
+}
+
+/// called when Coordinator starts processing the request
+void
+Mgr::Forwarder::handleRemoteAck()
+{
+ debugs(16, 3, HERE);
+ Must(entry != NULL);
+
+ requestId = 0;
+ EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
+ entry->complete();
+}
+
+/// Mgr::Forwarder::requestTimedOut wrapper
+void
+Mgr::Forwarder::RequestTimedOut(void* param)
+{
+ debugs(16, 3, HERE);
+ Must(param != NULL);
+ Forwarder* mgrFwdr = static_cast<Forwarder*>(param);
+ // use async call to enable job call protection that time events lack
+ CallJobHere(16, 5, mgrFwdr, Mgr::Forwarder, requestTimedOut);
+}
+
+/// called when Coordinator fails to start processing the request [in time]
+void
+Mgr::Forwarder::requestTimedOut()
+{
+ debugs(16, 3, HERE);
+ quitOnError("timeout", errorCon(ERR_LIFETIME_EXP, HTTP_REQUEST_TIMEOUT, request));
+}
+
+/// terminate with an error
+void
+Mgr::Forwarder::quitOnError(const char *reason, ErrorState *error)
+{
+ debugs(16, 3, HERE);
+ Must(reason != NULL);
+ Must(error != NULL);
+ Must(entry != NULL);
+ Must(request != NULL);
+
+ EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
+ entry->buffer();
+ entry->replaceHttpReply(error->BuildHttpReply());
+ entry->expires = squid_curtime;
+ errorStateFree(error);
+ entry->flush();
+ entry->complete();
+
+ mustStop(reason);
+}
+
+void
+Mgr::Forwarder::callException(const std::exception& e)
+{
+ try {
+ if (entry != NULL && request != NULL && fd >= 0)
+ quitOnError("exception", errorCon(ERR_INVALID_RESP, HTTP_INTERNAL_SERVER_ERROR, request));
+ } catch (const std::exception& ex) {
+ debugs(16, DBG_CRITICAL, HERE << ex.what());
+ }
+ AsyncJob::callException(e);
+}
+
+/// returns and forgets the right Forwarder callback for the request
+AsyncCall::Pointer
+Mgr::Forwarder::DequeueRequest(unsigned int requestId)
+{
+ debugs(16, 3, HERE);
+ Must(requestId != 0);
+ AsyncCall::Pointer call;
+ RequestsMap::iterator request = TheRequestsMap.find(requestId);
+ if (request != TheRequestsMap.end()) {
+ call = request->second;
+ Must(call != NULL);
+ TheRequestsMap.erase(request);
+ }
+ return call;
+}
+
+/// called when we are no longer waiting for Coordinator to respond
+void
+Mgr::Forwarder::removeTimeoutEvent()
+{
+ if (eventFind(&Forwarder::RequestTimedOut, this))
+ eventDelete(&Forwarder::RequestTimedOut, this);
+}
+
+void
+Mgr::Forwarder::HandleRemoteAck(unsigned int requestId)
+{
+ debugs(16, 3, HERE);
+ Must(requestId != 0);
+
+ AsyncCall::Pointer call = DequeueRequest(requestId);
+ if (call != NULL)
+ ScheduleCallHere(call);
+}
+
+/// called when something goes wrong with the Store entry
+void
+Mgr::Forwarder::Abort(void* param)
+{
+ Forwarder* mgrFwdr = static_cast<Forwarder*>(param);
+ if (mgrFwdr->fd >= 0)
+ comm_close(mgrFwdr->fd);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_FORWARDER_H
+#define SQUID_MGR_FORWARDER_H
+
+#include "base/AsyncJob.h"
+#include "mgr/ActionParams.h"
+#include <map>
+
+
+class CommCloseCbParams;
+class HttpRequest;
+class StoreEntry;
+class ErrorState;
+
+namespace Mgr
+{
+
+/** Forwards a single client cache manager request to Coordinator.
+ * Waits for an ACK from Coordinator while holding the Store entry.
+ * Fills the store entry with an error response if forwarding fails.
+ */
+class Forwarder: public AsyncJob
+{
+public:
+ Forwarder(int aFd, const ActionParams &aParams, HttpRequest* aRequest,
+ StoreEntry* anEntry);
+ virtual ~Forwarder();
+
+ /// finds and calls the right Forwarder upon Coordinator's response
+ static void HandleRemoteAck(unsigned int requestId);
+
+ /* has-to-be-public AsyncJob API */
+ virtual void callException(const std::exception& e);
+
+protected:
+ /* AsyncJob API */
+ virtual void start();
+ virtual void swanSong();
+ virtual bool doneAll() const;
+
+private:
+ void handleRemoteAck();
+ static void RequestTimedOut(void* param);
+ void requestTimedOut();
+ void quitOnError(const char *reason, ErrorState *error);
+ void noteCommClosed(const CommCloseCbParams& params);
+ void removeTimeoutEvent();
+ static AsyncCall::Pointer DequeueRequest(unsigned int requestId);
+ static void Abort(void* param);
+ void close();
+
+private:
+ ActionParams params; ///< action parameters to pass to the other side
+ HttpRequest* request; ///< HTTP client request for detailing errors
+ StoreEntry* entry; ///< Store entry expecting the response
+ int fd; ///< HTTP client connection descriptor
+ unsigned int requestId; ///< request id
+ AsyncCall::Pointer closer; ///< comm_close handler for the HTTP connection
+
+ /// maps requestId to Forwarder::handleRemoteAck callback
+ typedef std::map<unsigned int, AsyncCall::Pointer> RequestsMap;
+ static RequestsMap TheRequestsMap; ///< pending Coordinator requests
+
+ static unsigned int LastRequestId; ///< last requestId used
+
+ CBDATA_CLASS2(Forwarder);
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_FORWARDER_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "mgr/Command.h"
+#include "mgr/Filler.h"
+#include "mgr/FunAction.h"
+#include "mgr/Request.h"
+#include "Store.h"
+
+
+Mgr::FunAction::Pointer
+Mgr::FunAction::Create(const Command::Pointer &aCmd, OBJH* aHandler)
+{
+ return new FunAction(aCmd, aHandler);
+}
+
+Mgr::FunAction::FunAction(const Command::Pointer &aCmd, OBJH* aHandler):
+ Action(aCmd), handler(aHandler)
+{
+ Must(handler != NULL);
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::FunAction::respond(const Request& request)
+{
+ debugs(16, 5, HERE);
+ const int fd = ImportHttpFdIntoComm(request.fd);
+ Must(fd >= 0);
+ Must(request.requestId != 0);
+ AsyncJob::Start(new Mgr::Filler(this, fd, request.requestId));
+}
+
+void
+Mgr::FunAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+ if (UsingSmp() && IamWorkerProcess())
+ storeAppendPrintf(entry, "by kid%d {\n", KidIdentifier);
+ handler(entry);
+ if (atomic() && UsingSmp() && IamWorkerProcess())
+ storeAppendPrintf(entry, "} by kid%d\n\n", KidIdentifier);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_FUN_ACTION_H
+#define SQUID_MGR_FUN_ACTION_H
+
+#include "mgr/Action.h"
+#include "mgr/ActionCreator.h"
+
+
+namespace Mgr
+{
+
+/// function-based cache manager Action; a wrapper for so called legacy actions
+/// that do everything using a single OBJH function
+class FunAction: public Action
+{
+protected:
+ FunAction(const CommandPointer &cmd, OBJH *aHandler);
+
+public:
+ static Pointer Create(const CommandPointer &cmd, OBJH *aHandler);
+
+ /* Action API */
+ virtual void respond(const Request& request);
+ // we cannot aggregate because we do not even know what the handler does
+ virtual bool aggregatable() const { return false; }
+
+protected:
+ /* Action API */
+ virtual void dump(StoreEntry *entry);
+
+private:
+ OBJH *handler; ///< legacy function that collects and dumps info
+};
+
+
+/// creates FunAction using ActionCreator API
+class FunActionCreator: public ActionCreator
+{
+public:
+ explicit FunActionCreator(OBJH *aHandler): handler(aHandler) {}
+
+ /* ActionCreator API */
+ virtual Action::Pointer create(const CommandPointer &cmd) const
+ {
+ return FunAction::Create(cmd, handler);
+ }
+
+private:
+ OBJH *handler; ///< legacy function to pass to the FunAction wrapper
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_FUN_ACTION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "HttpReply.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/Filler.h"
+#include "mgr/InfoAction.h"
+#include "mgr/Request.h"
+#include "mgr/Response.h"
+#include "SquidTime.h"
+#include "Store.h"
+
+
+extern void GetInfo(Mgr::InfoActionData& stats);
+extern void DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry);
+extern void DumpMallocStatistics(StoreEntry* sentry);
+
+Mgr::InfoActionData::InfoActionData()
+{
+ xmemset(this, 0, sizeof(*this));
+}
+
+Mgr::InfoActionData&
+Mgr::InfoActionData::operator += (const InfoActionData& stats)
+{
+ if (!timerisset(&squid_start) || timercmp(&squid_start, &stats.squid_start, >))
+ squid_start = stats.squid_start;
+ if (timercmp(¤t_time, &stats.current_time, <))
+ current_time = stats.current_time;
+ client_http_clients += stats.client_http_clients;
+ client_http_requests += stats.client_http_requests;
+ icp_pkts_recv += stats.icp_pkts_recv;
+ icp_pkts_sent += stats.icp_pkts_sent;
+ icp_replies_queued += stats.icp_replies_queued;
+#if USE_HTCP
+ htcp_pkts_recv += stats.htcp_pkts_recv;
+ htcp_pkts_sent += stats.htcp_pkts_sent;
+#endif
+ request_failure_ratio += stats.request_failure_ratio;
+ avg_client_http_requests += stats.avg_client_http_requests;
+ avg_icp_messages += stats.avg_icp_messages;
+ select_loops += stats.select_loops;
+ avg_loop_time += stats.avg_loop_time;
+ request_hit_ratio5 += stats.request_hit_ratio5;
+ request_hit_ratio60 += stats.request_hit_ratio60;
+ byte_hit_ratio5 += stats.byte_hit_ratio5;
+ byte_hit_ratio60 += stats.byte_hit_ratio60;
+ request_hit_mem_ratio5 += stats.request_hit_mem_ratio5;
+ request_hit_mem_ratio60 += stats.request_hit_mem_ratio60;
+ request_hit_disk_ratio5 += stats.request_hit_disk_ratio5;
+ request_hit_disk_ratio60 += stats.request_hit_disk_ratio60;
+ store_swap_size += stats.store_swap_size;
+ store_swap_max_size += stats.store_swap_max_size;
+ store_mem_size += stats.store_mem_size;
+ store_pages_max += stats.store_pages_max;
+ store_mem_used += stats.store_mem_used;
+ objects_size += stats.objects_size;
+ unlink_requests += stats.unlink_requests;
+ http_requests5 += stats.http_requests5;
+ http_requests60 += stats.http_requests60;
+ cache_misses5 += stats.cache_misses5;
+ cache_misses60 += stats.cache_misses60;
+ cache_hits5 += stats.cache_hits5;
+ cache_hits60 += stats.cache_hits60;
+ near_hits5 += stats.near_hits5;
+ near_hits60 += stats.near_hits60;
+ not_modified_replies5 += stats.not_modified_replies5;
+ not_modified_replies60 += stats.not_modified_replies60;
+ dns_lookups5 += stats.dns_lookups5;
+ dns_lookups60 += stats.dns_lookups60;
+ icp_queries5 += stats.icp_queries5;
+ icp_queries60 += stats.icp_queries60;
+ if (stats.up_time > up_time)
+ up_time = stats.up_time;
+ cpu_time += stats.cpu_time;
+ cpu_usage += stats.cpu_usage;
+ cpu_usage5 += stats.cpu_usage5;
+ cpu_usage60 += stats.cpu_usage60;
+#if HAVE_SBRK
+ proc_data_seg += stats.proc_data_seg;
+#endif
+ maxrss += stats.maxrss;
+ page_faults += stats.page_faults;
+#if HAVE_MSTATS && HAVE_GNUMALLOC_H
+ ms_bytes_total += stats.ms_bytes_total;
+ ms_bytes_free += stats.ms_bytes_free;
+#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
+ mp_arena += stats.mp_arena;
+ mp_uordblks += stats.mp_uordblks;
+ mp_ordblks += stats.mp_ordblks;
+ mp_usmblks += stats.mp_usmblks;
+ mp_smblks += stats.mp_smblks;
+ mp_hblkhd += stats.mp_hblkhd;
+ mp_hblks += stats.mp_hblks;
+ mp_fsmblks += stats.mp_fsmblks;
+ mp_fordblks += stats.mp_fordblks;
+#if HAVE_STRUCT_MALLINFO_MXFAST
+ mp_mxfast += stats.mp_mxfast;
+ mp_nlblks += stats.mp_nlblks;
+ mp_grain += stats.mp_grain;
+ mp_uordbytes += stats.mp_uordbytes;
+ mp_allocated += stats.mp_allocated;
+ mp_treeoverhead += stats.mp_treeoverhead;
+#endif
+#endif
+ total_accounted += stats.total_accounted;
+#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
+ mem_pool_allocated += stats.mem_pool_allocated;
+#endif
+ gb_saved_count += stats.gb_saved_count;
+ gb_freed_count += stats.gb_freed_count;
+ max_fd += stats.max_fd;
+ biggest_fd += stats.biggest_fd;
+ number_fd += stats.number_fd;
+ opening_fd += stats.opening_fd;
+ num_fd_free += stats.num_fd_free;
+ reserved_fd += stats.reserved_fd;
+ store_open_disk_fd += stats.store_open_disk_fd;
+ store_entries += stats.store_entries;
+ store_mem_entries += stats.store_mem_entries;
+ hot_obj_count += stats.hot_obj_count;
+ n_disk_objects += stats.n_disk_objects;
+ ++count;
+
+ return *this;
+}
+
+Mgr::InfoAction::Pointer
+Mgr::InfoAction::Create(const CommandPointer &cmd)
+{
+ return new InfoAction(cmd);
+}
+
+Mgr::InfoAction::InfoAction(const CommandPointer &cmd):
+ Action(cmd), data()
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::InfoAction::add(const Action& action)
+{
+ debugs(16, 5, HERE);
+ data += dynamic_cast<const InfoAction&>(action).data;
+}
+
+void
+Mgr::InfoAction::respond(const Request& request)
+{
+ debugs(16, 5, HERE);
+ int fd = ImportHttpFdIntoComm(request.fd);
+ Must(fd >= 0);
+ Must(request.requestId != 0);
+ AsyncJob::Start(new Mgr::Filler(this, fd, request.requestId));
+}
+
+void
+Mgr::InfoAction::collect()
+{
+ GetInfo(data);
+}
+
+void
+Mgr::InfoAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+
+#if XMALLOC_STATISTICS
+ if (UsingSmp() && IamWorkerProcess())
+ storeAppendPrintf(entry, "by kid%d {\n", KidIdentifier);
+ DumpMallocStatistics(entry);
+ if (UsingSmp() && IamWorkerProcess())
+ storeAppendPrintf(entry, "} by kid%d\n\n", KidIdentifier);
+#endif
+ if (IamPrimaryProcess())
+ DumpInfo(data, entry);
+}
+
+void
+Mgr::InfoAction::pack(Ipc::TypedMsgHdr& msg) const
+{
+ msg.setType(Ipc::mtCacheMgrResponse);
+ msg.putPod(data);
+}
+
+void
+Mgr::InfoAction::unpack(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrResponse);
+ msg.getPod(data);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_INFO_ACTION_H
+#define SQUID_MGR_INFO_ACTION_H
+
+#include "mgr/Action.h"
+#include <sys/time.h>
+
+
+namespace Mgr
+{
+
+/// store general runtime information
+/// and memory usage
+class InfoActionData
+{
+public:
+ InfoActionData();
+ InfoActionData& operator += (const InfoActionData& stats);
+
+public:
+ struct timeval squid_start;
+ struct timeval current_time;
+ double client_http_clients;
+ double client_http_requests;
+ double icp_pkts_recv;
+ double icp_pkts_sent;
+ double icp_replies_queued;
+#if USE_HTCP
+ double htcp_pkts_recv;
+ double htcp_pkts_sent;
+#endif
+ double request_failure_ratio;
+ double avg_client_http_requests;
+ double avg_icp_messages;
+ double select_loops;
+ double avg_loop_time;
+ double request_hit_ratio5;
+ double request_hit_ratio60;
+ double byte_hit_ratio5;
+ double byte_hit_ratio60;
+ double request_hit_mem_ratio5;
+ double request_hit_mem_ratio60;
+ double request_hit_disk_ratio5;
+ double request_hit_disk_ratio60;
+ double store_swap_size;
+ double store_swap_max_size;
+ double store_mem_size;
+ double store_pages_max;
+ double store_mem_used;
+ double objects_size;
+ double unlink_requests;
+ double http_requests5;
+ double http_requests60;
+ double cache_misses5;
+ double cache_misses60;
+ double cache_hits5;
+ double cache_hits60;
+ double near_hits5;
+ double near_hits60;
+ double not_modified_replies5;
+ double not_modified_replies60;
+ double dns_lookups5;
+ double dns_lookups60;
+ double icp_queries5;
+ double icp_queries60;
+ double up_time;
+ double cpu_time;
+ double cpu_usage;
+ double cpu_usage5;
+ double cpu_usage60;
+#if HAVE_SBRK
+ double proc_data_seg;
+#endif
+ double maxrss;
+ double page_faults;
+#if HAVE_MSTATS && HAVE_GNUMALLOC_H
+ double ms_bytes_total;
+ double ms_bytes_free;
+#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
+ double mp_arena;
+ double mp_uordblks;
+ double mp_ordblks;
+ double mp_usmblks;
+ double mp_smblks;
+ double mp_hblkhd;
+ double mp_hblks;
+ double mp_fsmblks;
+ double mp_fordblks;
+#if HAVE_STRUCT_MALLINFO_MXFAST
+ double mp_mxfast;
+ double mp_nlblks;
+ double mp_grain;
+ double mp_uordbytes;
+ double mp_allocated;
+ double mp_treeoverhead;
+#endif
+#endif
+ double total_accounted;
+#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
+ double mem_pool_allocated;
+#endif
+ double gb_saved_count;
+ double gb_freed_count;
+ double max_fd;
+ double biggest_fd;
+ double number_fd;
+ double opening_fd;
+ double num_fd_free;
+ double reserved_fd;
+ double store_open_disk_fd;
+ double store_entries;
+ double store_mem_entries;
+ double hot_obj_count;
+ double n_disk_objects;
+ unsigned int count;
+};
+
+/// implement aggregated 'info' action
+class InfoAction: public Action
+{
+protected:
+ InfoAction(const CommandPointer &cmd);
+
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void add(const Action& action);
+ virtual void respond(const Request& request);
+ virtual void pack(Ipc::TypedMsgHdr& msg) const;
+ virtual void unpack(const Ipc::TypedMsgHdr& msg);
+
+protected:
+ /* Action API */
+ virtual void collect();
+ virtual void dump(StoreEntry* entry);
+
+private:
+ InfoActionData data;
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_INFO_ACTION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "CommCalls.h"
+#include "HttpReply.h"
+#include "ipc/Coordinator.h"
+#include "mgr/ActionWriter.h"
+#include "mgr/Command.h"
+#include "mgr/Inquirer.h"
+#include "mgr/Request.h"
+#include "mgr/Response.h"
+#include "SquidTime.h"
+#include <memory>
+#include <algorithm>
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Mgr, Inquirer);
+
+Mgr::Inquirer::RequestsMap Mgr::Inquirer::TheRequestsMap;
+unsigned int Mgr::Inquirer::LastRequestId = 0;
+
+/// compare Ipc::StrandCoord using kidId, for std::sort() below
+static bool
+LesserStrandByKidId(const Ipc::StrandCoord &c1, const Ipc::StrandCoord &c2) {
+ return c1.kidId < c2.kidId;
+}
+
+Mgr::Inquirer::Inquirer(Action::Pointer anAction, int aFd,
+ const Request &aCause, const Ipc::StrandCoords &coords):
+ AsyncJob("Mgr::Inquirer"),
+ aggrAction(anAction),
+ cause(aCause),
+ fd(aFd),
+ strands(coords), pos(strands.begin()),
+ requestId(0), closer(NULL), timeout(aggrAction->atomic() ? 10 : 100)
+{
+ debugs(16, 5, HERE << "FD " << aFd << " action: " << aggrAction);
+
+ // order by ascending kid IDs; useful for non-aggregatable stats
+ std::sort(strands.begin(), strands.end(), LesserStrandByKidId);
+
+ closer = asyncCall(16, 5, "Mgr::Inquirer::noteCommClosed",
+ CommCbMemFunT<Inquirer, CommCloseCbParams>(this, &Inquirer::noteCommClosed));
+ comm_add_close_handler(fd, closer);
+}
+
+Mgr::Inquirer::~Inquirer()
+{
+ debugs(16, 5, HERE);
+ close();
+}
+
+/// closes our copy of the client HTTP connection socket
+void
+Mgr::Inquirer::close() {
+ if (fd >= 0) {
+ removeCloseHandler();
+ comm_close(fd);
+ fd = -1;
+ }
+}
+
+void
+Mgr::Inquirer::removeCloseHandler()
+{
+ if (closer != NULL) {
+ comm_remove_close_handler(fd, closer);
+ closer = NULL;
+ }
+}
+
+void
+Mgr::Inquirer::start()
+{
+ debugs(16, 5, HERE);
+ Must(fd >= 0);
+ Must(aggrAction != NULL);
+
+ std::auto_ptr<HttpReply> reply(new HttpReply);
+ reply->setHeaders(HTTP_OK, NULL, "text/plain", -1, squid_curtime, squid_curtime);
+ reply->header.putStr(HDR_CONNECTION, "close"); // until we chunk response
+ std::auto_ptr<MemBuf> replyBuf(reply->pack());
+ writer = asyncCall(16, 5, "Mgr::Inquirer::noteWroteHeader",
+ CommCbMemFunT<Inquirer, CommIoCbParams>(this, &Inquirer::noteWroteHeader));
+ comm_write_mbuf(fd, replyBuf.get(), writer);
+}
+
+/// called when we wrote the response header
+void
+Mgr::Inquirer::noteWroteHeader(const CommIoCbParams& params)
+{
+ debugs(16, 5, HERE);
+ writer = NULL;
+ Must(params.flag == COMM_OK);
+ Must(params.fd == fd);
+ Must(params.size != 0);
+ // start inquiries at the initial pos
+ inquire();
+}
+
+void
+Mgr::Inquirer::inquire()
+{
+ if (pos == strands.end()) {
+ Must(done());
+ return;
+ }
+
+ Must(requestId == 0);
+ AsyncCall::Pointer callback = asyncCall(16, 5, "Mgr::Inquirer::handleRemoteAck",
+ HandleAckDialer(this, &Inquirer::handleRemoteAck, Response()));
+ if (++LastRequestId == 0) // don't use zero value as requestId
+ ++LastRequestId;
+ requestId = LastRequestId;
+ const int kidId = pos->kidId;
+ debugs(16, 4, HERE << "inquire kid: " << kidId << status());
+ TheRequestsMap[requestId] = callback;
+ Request mgrRequest(KidIdentifier, requestId, fd,
+ aggrAction->command().params);
+ Ipc::TypedMsgHdr message;
+ mgrRequest.pack(message);
+ Ipc::SendMessage(Ipc::Port::MakeAddr(Ipc::strandAddrPfx, kidId), message);
+ eventAdd("Mgr::Inquirer::requestTimedOut", &Inquirer::RequestTimedOut,
+ this, timeout, 0, false);
+}
+
+/// called when a strand is done writing its output
+void
+Mgr::Inquirer::handleRemoteAck(const Response& response)
+{
+ debugs(16, 4, HERE << status());
+ requestId = 0;
+ removeTimeoutEvent();
+ if (response.hasAction())
+ aggrAction->add(response.getAction());
+ Must(!done()); // or we should not be called
+ ++pos; // advance after a successful inquiry
+ inquire();
+}
+
+/// called when the HTTP client or some external force closed our socket
+void
+Mgr::Inquirer::noteCommClosed(const CommCloseCbParams& params)
+{
+ debugs(16, 5, HERE);
+ Must(fd < 0 || fd == params.fd);
+ fd = -1;
+ mustStop("commClosed");
+}
+
+void
+Mgr::Inquirer::swanSong()
+{
+ debugs(16, 5, HERE);
+ removeTimeoutEvent();
+ if (requestId > 0) {
+ DequeueRequest(requestId);
+ requestId = 0;
+ }
+ if (aggrAction->aggregatable()) {
+ removeCloseHandler();
+ AsyncJob::Start(new ActionWriter(aggrAction, fd));
+ fd = -1; // should not close fd because we passed it to ActionWriter
+ }
+ close();
+}
+
+bool
+Mgr::Inquirer::doneAll() const
+{
+ return !writer && pos == strands.end();
+}
+
+/// returns and forgets the right Inquirer callback for strand request
+AsyncCall::Pointer
+Mgr::Inquirer::DequeueRequest(unsigned int requestId)
+{
+ debugs(16, 3, HERE << " requestId " << requestId);
+ Must(requestId != 0);
+ AsyncCall::Pointer call;
+ RequestsMap::iterator request = TheRequestsMap.find(requestId);
+ if (request != TheRequestsMap.end()) {
+ call = request->second;
+ Must(call != NULL);
+ TheRequestsMap.erase(request);
+ }
+ return call;
+}
+
+void
+Mgr::Inquirer::HandleRemoteAck(const Mgr::Response& response)
+{
+ Must(response.requestId != 0);
+ AsyncCall::Pointer call = DequeueRequest(response.requestId);
+ if (call != NULL) {
+ HandleAckDialer* dialer = dynamic_cast<HandleAckDialer*>(call->getDialer());
+ Must(dialer);
+ dialer->arg1 = response;
+ ScheduleCallHere(call);
+ }
+}
+
+/// called when we are no longer waiting for the strand to respond
+void
+Mgr::Inquirer::removeTimeoutEvent()
+{
+ if (eventFind(&Inquirer::RequestTimedOut, this))
+ eventDelete(&Inquirer::RequestTimedOut, this);
+}
+
+/// Mgr::Inquirer::requestTimedOut wrapper
+void
+Mgr::Inquirer::RequestTimedOut(void* param)
+{
+ debugs(16, 3, HERE);
+ Must(param != NULL);
+ Inquirer* cmi = static_cast<Inquirer*>(param);
+ // use async call to enable job call protection that time events lack
+ CallJobHere(16, 5, cmi, Mgr::Inquirer, requestTimedOut);
+}
+
+/// called when the strand failed to respond (or finish responding) in time
+void
+Mgr::Inquirer::requestTimedOut()
+{
+ debugs(16, 3, HERE);
+ if (requestId != 0) {
+ DequeueRequest(requestId);
+ requestId = 0;
+ Must(!done()); // or we should not be called
+ ++pos; // advance after a failed inquiry
+ inquire();
+ }
+}
+
+const char*
+Mgr::Inquirer::status() const
+{
+ static MemBuf buf;
+ buf.reset();
+ buf.Printf(" [FD %d, requestId %u]", fd, requestId);
+ buf.terminate();
+ return buf.content();
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_INQUIRER_H
+#define SQUID_MGR_INQUIRER_H
+
+#include "base/AsyncJobCalls.h"
+#include "base/AsyncJob.h"
+#include "ipc/StrandCoords.h"
+#include "MemBuf.h"
+#include "mgr/Action.h"
+#include "mgr/Request.h"
+#include <map>
+
+class CommIoCbParams;
+class CommCloseCbParams;
+
+namespace Mgr
+{
+
+/// Coordinator's job that sends a cache manage request to each strand,
+/// aggregating individual strand responses and dumping the result if needed
+class Inquirer: public AsyncJob
+{
+public:
+ Inquirer(Action::Pointer anAction, int aFd, const Request &aCause,
+ const Ipc::StrandCoords &coords);
+ virtual ~Inquirer();
+
+ /// finds and calls the right Inquirer upon strand's response
+ static void HandleRemoteAck(const Mgr::Response& response);
+
+protected:
+ /* AsyncJob API */
+ virtual void start();
+ virtual void swanSong();
+ virtual bool doneAll() const;
+ virtual const char *status() const;
+
+private:
+ typedef UnaryMemFunT<Inquirer, Response, const Response&> HandleAckDialer;
+
+ void inquire();
+ void noteWroteHeader(const CommIoCbParams& params);
+ void noteCommClosed(const CommCloseCbParams& params);
+
+ void handleRemoteAck(const Response& response);
+
+ static AsyncCall::Pointer DequeueRequest(unsigned int requestId);
+
+ static void RequestTimedOut(void* param);
+ void requestTimedOut();
+ void removeTimeoutEvent();
+
+ void close();
+ void removeCloseHandler();
+
+private:
+ Action::Pointer aggrAction; //< action to aggregate
+
+ Request cause; ///< cache manager request received from HTTP client
+ int fd; ///< HTTP client socket descriptor
+
+ Ipc::StrandCoords strands; ///< all strands we want to query, in order
+ Ipc::StrandCoords::const_iterator pos; ///< strand we should query now
+
+ unsigned int requestId; ///< ID of our outstanding request to strand
+ AsyncCall::Pointer writer; ///< comm_write callback
+ AsyncCall::Pointer closer; ///< comm_close handler
+ const double timeout; ///< number of seconds to wait for strand response
+
+ /// maps requestId to Inquirer::handleRemoteAck callback
+ typedef std::map<unsigned int, AsyncCall::Pointer> RequestsMap;
+ static RequestsMap TheRequestsMap; ///< pending strand requests
+
+ static unsigned int LastRequestId; ///< last requestId used
+
+ CBDATA_CLASS2(Inquirer);
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_INQUIRER_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/IntervalAction.h"
+#include "SquidMath.h"
+#include "Store.h"
+
+
+extern void GetAvgStat(Mgr::IntervalActionData& stats, int minutes, int hours);
+extern void DumpAvgStat(Mgr::IntervalActionData& stats, StoreEntry* sentry);
+
+Mgr::IntervalActionData::IntervalActionData()
+{
+ xmemset(this, 0, sizeof(*this));
+}
+
+Mgr::IntervalActionData&
+Mgr::IntervalActionData::operator += (const IntervalActionData& stats)
+{
+ if (!timerisset(&sample_start_time) || timercmp(&sample_start_time, &stats.sample_start_time, >))
+ sample_start_time = stats.sample_start_time;
+ if (timercmp(&sample_end_time, &stats.sample_end_time, <))
+ sample_end_time = stats.sample_end_time;
+ client_http_requests += stats.client_http_requests;
+ client_http_hits += stats.client_http_hits;
+ client_http_errors += stats.client_http_errors;
+ client_http_kbytes_in += stats.client_http_kbytes_in;
+ client_http_kbytes_out += stats.client_http_kbytes_out;
+ client_http_all_median_svc_time += stats.client_http_all_median_svc_time;
+ client_http_miss_median_svc_time += stats.client_http_miss_median_svc_time;
+ client_http_nm_median_svc_time += stats.client_http_nm_median_svc_time;
+ client_http_nh_median_svc_time += stats.client_http_nh_median_svc_time;
+ client_http_hit_median_svc_time += stats.client_http_hit_median_svc_time;
+ server_all_requests += stats.server_all_requests;
+ server_all_errors += stats.server_all_errors;
+ server_all_kbytes_in += stats.server_all_kbytes_in;
+ server_all_kbytes_out += stats.server_all_kbytes_out;
+ server_http_requests += stats.server_http_requests;
+ server_http_errors += stats.server_http_errors;
+ server_http_kbytes_in += stats.server_http_kbytes_in;
+ server_http_kbytes_out += stats.server_http_kbytes_out;
+ server_ftp_requests += stats.server_ftp_requests;
+ server_ftp_errors += stats.server_ftp_errors;
+ server_ftp_kbytes_in += stats.server_ftp_kbytes_in;
+ server_ftp_kbytes_out += stats.server_ftp_kbytes_out;
+ server_other_requests += stats.server_other_requests;
+ server_other_errors += stats.server_other_errors;
+ server_other_kbytes_in += stats.server_other_kbytes_in;
+ server_other_kbytes_out += stats.server_other_kbytes_out;
+ icp_pkts_sent += stats.icp_pkts_sent;
+ icp_pkts_recv += stats.icp_pkts_recv;
+ icp_queries_sent += stats.icp_queries_sent;
+ icp_replies_sent += stats.icp_replies_sent;
+ icp_queries_recv += stats.icp_queries_recv;
+ icp_replies_recv += stats.icp_replies_recv;
+ icp_replies_queued += stats.icp_replies_queued;
+ icp_query_timeouts += stats.icp_query_timeouts;
+ icp_kbytes_sent += stats.icp_kbytes_sent;
+ icp_kbytes_recv += stats.icp_kbytes_recv;
+ icp_q_kbytes_sent += stats.icp_q_kbytes_sent;
+ icp_r_kbytes_sent += stats.icp_r_kbytes_sent;
+ icp_q_kbytes_recv += stats.icp_q_kbytes_recv;
+ icp_r_kbytes_recv += stats.icp_r_kbytes_recv;
+ icp_query_median_svc_time += stats.icp_query_median_svc_time;
+ icp_reply_median_svc_time += stats.icp_reply_median_svc_time;
+ dns_median_svc_time += stats.dns_median_svc_time;
+ unlink_requests += stats.unlink_requests;
+ page_faults += stats.page_faults;
+ select_loops += stats.select_loops;
+ select_fds += stats.select_fds;
+ average_select_fd_period += stats.average_select_fd_period;
+ median_select_fds += stats.median_select_fds;
+ swap_outs += stats.swap_outs;
+ swap_ins += stats.swap_ins;
+ swap_files_cleaned += stats.swap_files_cleaned;
+ aborted_requests += stats.aborted_requests;
+ syscalls_disk_opens += stats.syscalls_disk_opens;
+ syscalls_disk_closes += stats.syscalls_disk_closes;
+ syscalls_disk_reads += stats.syscalls_disk_reads;
+ syscalls_disk_writes += stats.syscalls_disk_writes;
+ syscalls_disk_seeks += stats.syscalls_disk_seeks;
+ syscalls_disk_unlinks += stats.syscalls_disk_unlinks;
+ syscalls_sock_accepts += stats.syscalls_sock_accepts;
+ syscalls_sock_sockets += stats.syscalls_sock_sockets;
+ syscalls_sock_connects += stats.syscalls_sock_connects;
+ syscalls_sock_binds += stats.syscalls_sock_binds;
+ syscalls_sock_closes += stats.syscalls_sock_closes;
+ syscalls_sock_reads += stats.syscalls_sock_reads;
+ syscalls_sock_writes += stats.syscalls_sock_writes;
+ syscalls_sock_recvfroms += stats.syscalls_sock_recvfroms;
+ syscalls_sock_sendtos += stats.syscalls_sock_sendtos;
+ syscalls_selects += stats.syscalls_selects;
+ cpu_time += stats.cpu_time;
+ wall_time += stats.wall_time;
+ ++count;
+
+ return *this;
+}
+
+Mgr::IntervalAction::Pointer
+Mgr::IntervalAction::Create5min(const CommandPointer &cmd)
+{
+ return new IntervalAction(cmd, 5, 0);
+}
+
+Mgr::IntervalAction::Pointer
+Mgr::IntervalAction::Create60min(const CommandPointer &cmd)
+{
+ return new IntervalAction(cmd, 60, 0);
+}
+
+Mgr::IntervalAction::IntervalAction(const CommandPointer &cmd, int aMinutes, int aHours):
+ Action(cmd), minutes(aMinutes), hours(aHours), data()
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::IntervalAction::add(const Action& action)
+{
+ debugs(16, 5, HERE);
+ data += dynamic_cast<const IntervalAction&>(action).data;
+}
+
+void
+Mgr::IntervalAction::collect()
+{
+ GetAvgStat(data, minutes, hours);
+}
+
+void
+Mgr::IntervalAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+ DumpAvgStat(data, entry);
+}
+
+void
+Mgr::IntervalAction::pack(Ipc::TypedMsgHdr& msg) const
+{
+ msg.setType(Ipc::mtCacheMgrResponse);
+ msg.putPod(data);
+}
+
+void
+Mgr::IntervalAction::unpack(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrResponse);
+ msg.getPod(data);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_INTERVAL_ACTION_H
+#define SQUID_MGR_INTERVAL_ACTION_H
+
+#include "mgr/Action.h"
+#include <sys/time.h>
+
+
+namespace Mgr
+{
+
+/// auxiliary class which store stats computed
+/// from StatCounters for specified interval
+class IntervalActionData
+{
+public:
+ IntervalActionData();
+ IntervalActionData& operator += (const IntervalActionData& stats);
+
+public:
+ struct timeval sample_start_time;
+ struct timeval sample_end_time;
+ double client_http_requests;
+ double client_http_hits;
+ double client_http_errors;
+ double client_http_kbytes_in;
+ double client_http_kbytes_out;
+ double client_http_all_median_svc_time;
+ double client_http_miss_median_svc_time;
+ double client_http_nm_median_svc_time;
+ double client_http_nh_median_svc_time;
+ double client_http_hit_median_svc_time;
+ double server_all_requests;
+ double server_all_errors;
+ double server_all_kbytes_in;
+ double server_all_kbytes_out;
+ double server_http_requests;
+ double server_http_errors;
+ double server_http_kbytes_in;
+ double server_http_kbytes_out;
+ double server_ftp_requests;
+ double server_ftp_errors;
+ double server_ftp_kbytes_in;
+ double server_ftp_kbytes_out;
+ double server_other_requests;
+ double server_other_errors;
+ double server_other_kbytes_in;
+ double server_other_kbytes_out;
+ double icp_pkts_sent;
+ double icp_pkts_recv;
+ double icp_queries_sent;
+ double icp_replies_sent;
+ double icp_queries_recv;
+ double icp_replies_recv;
+ double icp_replies_queued;
+ double icp_query_timeouts;
+ double icp_kbytes_sent;
+ double icp_kbytes_recv;
+ double icp_q_kbytes_sent;
+ double icp_r_kbytes_sent;
+ double icp_q_kbytes_recv;
+ double icp_r_kbytes_recv;
+ double icp_query_median_svc_time;
+ double icp_reply_median_svc_time;
+ double dns_median_svc_time;
+ double unlink_requests;
+ double page_faults;
+ double select_loops;
+ double select_fds;
+ double average_select_fd_period;
+ double median_select_fds;
+ double swap_outs;
+ double swap_ins;
+ double swap_files_cleaned;
+ double aborted_requests;
+ double syscalls_disk_opens;
+ double syscalls_disk_closes;
+ double syscalls_disk_reads;
+ double syscalls_disk_writes;
+ double syscalls_disk_seeks;
+ double syscalls_disk_unlinks;
+ double syscalls_sock_accepts;
+ double syscalls_sock_sockets;
+ double syscalls_sock_connects;
+ double syscalls_sock_binds;
+ double syscalls_sock_closes;
+ double syscalls_sock_reads;
+ double syscalls_sock_writes;
+ double syscalls_sock_recvfroms;
+ double syscalls_sock_sendtos;
+ double syscalls_selects;
+ double cpu_time;
+ double wall_time;
+ unsigned int count;
+};
+
+/// implement aggregated interval actions
+class IntervalAction: public Action
+{
+protected:
+ IntervalAction(const CommandPointer &cmd, int aMinutes, int aHours);
+
+public:
+ static Pointer Create5min(const CommandPointer &cmd);
+ static Pointer Create60min(const CommandPointer &cmd);
+ /* Action API */
+ virtual void add(const Action& action);
+ virtual void pack(Ipc::TypedMsgHdr& msg) const;
+ virtual void unpack(const Ipc::TypedMsgHdr& msg);
+
+protected:
+ /* Action API */
+ virtual void collect();
+ virtual void dump(StoreEntry* entry);
+
+private:
+ int minutes;
+ int hours;
+ IntervalActionData data;
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_INTERVAL_ACTION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/IoAction.h"
+#include "SquidMath.h"
+#include "Store.h"
+
+
+extern void GetIoStats(Mgr::IoActionData& stats);
+extern void DumpIoStats(Mgr::IoActionData& stats, StoreEntry* sentry);
+
+Mgr::IoActionData::IoActionData()
+{
+ xmemset(this, 0, sizeof(*this));
+}
+
+Mgr::IoActionData&
+Mgr::IoActionData::operator += (const IoActionData& stats)
+{
+ http_reads += stats.http_reads;
+ for (int i = 0; i < _iostats::histSize; ++i)
+ http_read_hist[i] += stats.http_read_hist[i];
+ ftp_reads += stats.ftp_reads;
+ for (int i = 0; i < _iostats::histSize; ++i)
+ ftp_read_hist[i] += stats.ftp_read_hist[i];
+ gopher_reads += stats.gopher_reads;
+ for (int i = 0; i < _iostats::histSize; ++i)
+ gopher_read_hist[i] += stats.gopher_read_hist[i];
+
+ return *this;
+}
+
+Mgr::IoAction::Pointer
+Mgr::IoAction::Create(const CommandPointer &cmd)
+{
+ return new IoAction(cmd);
+}
+
+Mgr::IoAction::IoAction(const CommandPointer &cmd):
+ Action(cmd), data()
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::IoAction::add(const Action& action)
+{
+ debugs(16, 5, HERE);
+ data += dynamic_cast<const IoAction&>(action).data;
+}
+
+void
+Mgr::IoAction::collect()
+{
+ GetIoStats(data);
+}
+
+void
+Mgr::IoAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+ DumpIoStats(data, entry);
+}
+
+void
+Mgr::IoAction::pack(Ipc::TypedMsgHdr& msg) const
+{
+ msg.setType(Ipc::mtCacheMgrResponse);
+ msg.putPod(data);
+}
+
+void
+Mgr::IoAction::unpack(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrResponse);
+ msg.getPod(data);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_IO_ACTION_H
+#define SQUID_MGR_IO_ACTION_H
+
+#include "mgr/Action.h"
+#include "structs.h" /* _iostats::histSize */
+
+namespace Mgr
+{
+
+/// store server-side network read() size histograms
+class IoActionData
+{
+public:
+ IoActionData();
+ IoActionData& operator += (const IoActionData& stats);
+
+public:
+ double http_reads;
+ double ftp_reads;
+ double gopher_reads;
+ double http_read_hist[_iostats::histSize];
+ double ftp_read_hist[_iostats::histSize];
+ double gopher_read_hist[_iostats::histSize];
+};
+
+/// implement aggregated 'io' action
+class IoAction: public Action
+{
+protected:
+ IoAction(const CommandPointer &cmd);
+
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void add(const Action& action);
+ virtual void pack(Ipc::TypedMsgHdr& msg) const;
+ virtual void unpack(const Ipc::TypedMsgHdr& msg);
+
+protected:
+ /* Action API */
+ virtual void collect();
+ virtual void dump(StoreEntry* entry);
+
+private:
+ IoActionData data;
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_IO_ACTION_H */
--- /dev/null
+include $(top_srcdir)/src/Common.am
+include $(top_srcdir)/src/TestHeaders.am
+
+noinst_LTLIBRARIES = libmgr.la
+
+libmgr_la_SOURCES = \
+ Action.cc \
+ ActionCreator.h \
+ Action.h \
+ ActionParams.cc \
+ ActionParams.h \
+ ActionProfile.h \
+ ActionWriter.cc \
+ ActionWriter.h \
+ BasicActions.cc \
+ BasicActions.h \
+ Command.cc \
+ Command.h \
+ CountersAction.cc \
+ CountersAction.h \
+ Filler.cc \
+ Filler.h \
+ Forwarder.cc \
+ Forwarder.h \
+ forward.h \
+ FunAction.cc \
+ FunAction.h \
+ InfoAction.cc \
+ InfoAction.h \
+ Inquirer.cc \
+ Inquirer.h \
+ IntervalAction.cc \
+ IntervalAction.h \
+ IoAction.cc \
+ IoAction.h \
+ Registration.cc \
+ Registration.h \
+ Request.cc \
+ Request.h \
+ Response.cc \
+ Response.h \
+ ServiceTimesAction.cc \
+ ServiceTimesAction.h \
+ StoreIoAction.cc \
+ StoreIoAction.h \
+ StoreToCommWriter.cc \
+ StoreToCommWriter.h
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "CacheManager.h"
+#include "mgr/Registration.h"
+
+void
+Mgr::RegisterAction(char const * action, char const * desc,
+ OBJH * handler,
+ int pw_req_flag, int atomic)
+{
+ CacheManager::GetInstance()->registerProfile(action, desc, handler,
+ pw_req_flag, atomic);
+}
+
+void
+Mgr::RegisterAction(char const * action, char const * desc,
+ ClassActionCreationHandler *handler,
+ int pw_req_flag, int atomic)
+{
+ CacheManager::GetInstance()->registerProfile(action, desc, handler,
+ pw_req_flag, atomic);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_REGISTRATION_H
+#define SQUID_MGR_REGISTRATION_H
+
+#include "mgr/forward.h"
+#include "typedefs.h" /* for OBJH */
+
+namespace Mgr
+{
+
+void RegisterAction(char const * action, char const * desc,
+ OBJH * handler,
+ int pw_req_flag, int atomic);
+
+void RegisterAction(char const * action, char const * desc,
+ ClassActionCreationHandler *handler,
+ int pw_req_flag, int atomic);
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_REGISTRATION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/Messages.h"
+#include "mgr/ActionParams.h"
+#include "mgr/Request.h"
+
+
+Mgr::Request::Request(int aRequestorId, unsigned int aRequestId, int aFd,
+ const ActionParams &aParams):
+ requestorId(aRequestorId), requestId(aRequestId),
+ fd(aFd), params(aParams)
+{
+ Must(requestorId > 0);
+ Must(requestId != 0);
+}
+
+Mgr::Request::Request(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrRequest);
+ msg.getPod(requestorId);
+ msg.getPod(requestId);
+ params = ActionParams(msg);
+
+ fd = msg.getFd();
+}
+
+void
+Mgr::Request::pack(Ipc::TypedMsgHdr& msg) const
+{
+ msg.setType(Ipc::mtCacheMgrRequest);
+ msg.putPod(requestorId);
+ msg.putPod(requestId);
+ params.pack(msg);
+
+ msg.putFd(fd);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_REQUEST_H
+#define SQUID_MGR_REQUEST_H
+
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/ActionParams.h"
+
+
+namespace Mgr
+{
+
+/// cache manager request
+class Request
+{
+public:
+ Request(int aRequestorId, unsigned int aRequestId, int aFd,
+ const ActionParams &aParams);
+
+ explicit Request(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
+ void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
+
+public:
+ int requestorId; ///< kidId of the requestor; used for response destination
+ unsigned int requestId; ///< unique for sender; matches request w/ response
+ int fd; ///< HTTP client connection descriptor
+
+ ActionParams params; ///< action name and parameters
+};
+
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_REQUEST_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "CacheManager.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/ActionCreator.h"
+#include "mgr/ActionProfile.h"
+#include "mgr/Response.h"
+
+
+std::ostream& Mgr::operator << (std::ostream &os, const Response& response)
+{
+ os << "response: {requestId: " << response.requestId << '}';
+ return os;
+}
+
+Mgr::Response::Response(unsigned int aRequestId, Action::Pointer anAction):
+ requestId(aRequestId), action(anAction)
+{
+ Must(!action || action->name()); // if there is an action, it must be named
+}
+
+Mgr::Response::Response(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrResponse);
+ msg.getPod(requestId);
+ Must(requestId != 0);
+
+ if (msg.hasMoreData()) {
+ String actionName;
+ msg.getString(actionName);
+ action = CacheManager::GetInstance()->createNamedAction(actionName.termedBuf());
+ Must(hasAction());
+ action->unpack(msg);
+ }
+}
+
+void
+Mgr::Response::pack(Ipc::TypedMsgHdr& msg) const
+{
+ Must(requestId != 0);
+ msg.setType(Ipc::mtCacheMgrResponse);
+ msg.putPod(requestId);
+ if (hasAction()) {
+ msg.putString(action->name());
+ action->pack(msg);
+ }
+}
+
+bool
+Mgr::Response::hasAction() const
+{
+ return action != NULL;
+}
+
+const Mgr::Action&
+Mgr::Response::getAction() const
+{
+ Must(hasAction());
+ return *action;
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_RESPONSE_H
+#define SQUID_MGR_RESPONSE_H
+
+#include "mgr/Action.h"
+
+
+namespace Mgr
+{
+
+/// A response to Mgr::Request.
+/// May carry strand action data to be aggregated with data from other strands.
+class Response
+{
+public:
+ Response(unsigned int aRequestId = 0, Action::Pointer anAction = NULL);
+
+ explicit Response(const Ipc::TypedMsgHdr& msg); ///< from recvmsg()
+ void pack(Ipc::TypedMsgHdr& msg) const; ///< prepare for sendmsg()
+ bool hasAction() const; ///< whether response contain action object
+ const Action& getAction() const; ///< returns action object
+
+public:
+ unsigned int requestId; ///< ID of request we are responding to
+ Action::Pointer action; ///< action relating to response
+};
+
+extern std::ostream& operator <<(std::ostream &os, const Response &response);
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_RESPONSE_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/ServiceTimesAction.h"
+#include "Store.h"
+
+
+extern void GetServiceTimesStats(Mgr::ServiceTimesActionData& stats);
+extern void DumpServiceTimesStats(Mgr::ServiceTimesActionData& stats, StoreEntry* sentry);
+
+Mgr::ServiceTimesActionData::ServiceTimesActionData()
+{
+ xmemset(this, 0, sizeof(*this));
+}
+
+Mgr::ServiceTimesActionData&
+Mgr::ServiceTimesActionData::operator += (const ServiceTimesActionData& stats)
+{
+ for (int i = 0; i < seriesSize; ++i) {
+ http_requests5[i] += stats.http_requests5[i];
+ http_requests60[i] += stats.http_requests60[i];
+
+ cache_misses5[i] += stats.cache_misses5[i];
+ cache_misses60[i] += stats.cache_misses60[i];
+
+ cache_hits5[i] += stats.cache_hits5[i];
+ cache_hits60[i] += stats.cache_hits60[i];
+
+ near_hits5[i] += stats.near_hits5[i];
+ near_hits60[i] += stats.near_hits60[i];
+
+ not_modified_replies5[i] += stats.not_modified_replies5[i];
+ not_modified_replies60[i] += stats.not_modified_replies60[i];
+
+ dns_lookups5[i] += stats.dns_lookups5[i];
+ dns_lookups60[i] += stats.dns_lookups60[i];
+
+ icp_queries5[i] += stats.icp_queries5[i];
+ icp_queries60[i] += stats.icp_queries60[i];
+ }
+ ++count;
+
+ return *this;
+}
+
+Mgr::ServiceTimesAction::Pointer
+Mgr::ServiceTimesAction::Create(const CommandPointer &cmd)
+{
+ return new ServiceTimesAction(cmd);
+}
+
+Mgr::ServiceTimesAction::ServiceTimesAction(const CommandPointer &cmd):
+ Action(cmd), data()
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::ServiceTimesAction::add(const Action& action)
+{
+ debugs(16, 5, HERE);
+ data += dynamic_cast<const ServiceTimesAction&>(action).data;
+}
+
+void
+Mgr::ServiceTimesAction::collect()
+{
+ debugs(16, 5, HERE);
+ GetServiceTimesStats(data);
+}
+
+void
+Mgr::ServiceTimesAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+ DumpServiceTimesStats(data, entry);
+}
+
+void
+Mgr::ServiceTimesAction::pack(Ipc::TypedMsgHdr& msg) const
+{
+ msg.setType(Ipc::mtCacheMgrResponse);
+ msg.putPod(data);
+}
+
+void
+Mgr::ServiceTimesAction::unpack(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrResponse);
+ msg.getPod(data);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_SERVICE_TIMES_ACTION_H
+#define SQUID_MGR_SERVICE_TIMES_ACTION_H
+
+#include "mgr/Action.h"
+
+
+namespace Mgr
+{
+
+/// store service times for 5 and 60 min
+class ServiceTimesActionData
+{
+public:
+ enum { seriesSize = 19 };
+
+public:
+ ServiceTimesActionData();
+ ServiceTimesActionData& operator += (const ServiceTimesActionData& stats);
+
+public:
+ double http_requests5[seriesSize];
+ double http_requests60[seriesSize];
+ double cache_misses5[seriesSize];
+ double cache_misses60[seriesSize];
+ double cache_hits5[seriesSize];
+ double cache_hits60[seriesSize];
+ double near_hits5[seriesSize];
+ double near_hits60[seriesSize];
+ double not_modified_replies5[seriesSize];
+ double not_modified_replies60[seriesSize];
+ double dns_lookups5[seriesSize];
+ double dns_lookups60[seriesSize];
+ double icp_queries5[seriesSize];
+ double icp_queries60[seriesSize];
+ unsigned int count;
+};
+
+/// implement aggregated 'service_times' action
+class ServiceTimesAction: public Action
+{
+protected:
+ ServiceTimesAction(const CommandPointer &cmd);
+
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void add(const Action& action);
+ virtual void pack(Ipc::TypedMsgHdr& msg) const;
+ virtual void unpack(const Ipc::TypedMsgHdr& msg);
+
+protected:
+ /* Action API */
+ virtual void collect();
+ virtual void dump(StoreEntry* entry);
+
+private:
+ ServiceTimesActionData data;
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_SERVICE_TIMES_ACTION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "ipc/Messages.h"
+#include "ipc/TypedMsgHdr.h"
+#include "mgr/StoreIoAction.h"
+#include "Store.h"
+
+
+Mgr::StoreIoActionData::StoreIoActionData()
+{
+ xmemset(this, 0, sizeof(*this));
+}
+
+Mgr::StoreIoActionData&
+Mgr::StoreIoActionData::operator += (const StoreIoActionData& stats)
+{
+ create_calls += stats.create_calls;
+ create_select_fail += stats.create_select_fail;
+ create_create_fail += stats.create_create_fail;
+ create_success += stats.create_success;
+
+ return *this;
+}
+
+Mgr::StoreIoAction::Pointer
+Mgr::StoreIoAction::Create(const CommandPointer &cmd)
+{
+ return new StoreIoAction(cmd);
+}
+
+Mgr::StoreIoAction::StoreIoAction(const CommandPointer &cmd):
+ Action(cmd), data()
+{
+ debugs(16, 5, HERE);
+}
+
+void
+Mgr::StoreIoAction::add(const Action& action)
+{
+ debugs(16, 5, HERE);
+ data += dynamic_cast<const StoreIoAction&>(action).data;
+}
+
+void
+Mgr::StoreIoAction::collect()
+{
+ data.create_calls = store_io_stats.create.calls;
+ data.create_select_fail = store_io_stats.create.select_fail;
+ data.create_create_fail = store_io_stats.create.create_fail;
+ data.create_success = store_io_stats.create.success;
+}
+
+void
+Mgr::StoreIoAction::dump(StoreEntry* entry)
+{
+ debugs(16, 5, HERE);
+ Must(entry != NULL);
+ storeAppendPrintf(entry, "Store IO Interface Stats\n");
+ storeAppendPrintf(entry, "create.calls %.0f\n", data.create_calls);
+ storeAppendPrintf(entry, "create.select_fail %.0f\n", data.create_select_fail);
+ storeAppendPrintf(entry, "create.create_fail %.0f\n", data.create_create_fail);
+ storeAppendPrintf(entry, "create.success %.0f\n", data.create_success);
+}
+
+void
+Mgr::StoreIoAction::pack(Ipc::TypedMsgHdr& msg) const
+{
+ msg.setType(Ipc::mtCacheMgrResponse);
+ msg.putPod(data);
+}
+
+void
+Mgr::StoreIoAction::unpack(const Ipc::TypedMsgHdr& msg)
+{
+ msg.checkType(Ipc::mtCacheMgrResponse);
+ msg.getPod(data);
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_STORE_IO_ACTION_H
+#define SQUID_MGR_STORE_IO_ACTION_H
+
+#include "mgr/Action.h"
+
+
+namespace Mgr
+{
+
+/// Store IO interface data
+class StoreIoActionData
+{
+public:
+ StoreIoActionData();
+ StoreIoActionData& operator += (const StoreIoActionData& stats);
+
+public:
+ double create_calls;
+ double create_select_fail;
+ double create_create_fail;
+ double create_success;
+};
+
+/// implement aggregated 'store_io' action
+class StoreIoAction: public Action
+{
+protected:
+ StoreIoAction(const CommandPointer &cmd);
+
+public:
+ static Pointer Create(const CommandPointer &cmd);
+ /* Action API */
+ virtual void add(const Action& action);
+ virtual void pack(Ipc::TypedMsgHdr& msg) const;
+ virtual void unpack(const Ipc::TypedMsgHdr& msg);
+
+protected:
+ /* Action API */
+ virtual void collect();
+ virtual void dump(StoreEntry* entry);
+
+private:
+ StoreIoActionData data;
+};
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_STORE_IO_ACTION_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#include "config.h"
+#include "base/TextException.h"
+#include "CommCalls.h"
+#include "ipc/FdNotes.h"
+#include "mgr/StoreToCommWriter.h"
+#include "StoreClient.h"
+#include "Store.h"
+
+
+CBDATA_NAMESPACED_CLASS_INIT(Mgr, StoreToCommWriter);
+
+
+Mgr::StoreToCommWriter::StoreToCommWriter(int aFd, StoreEntry* anEntry):
+ AsyncJob("Mgr::StoreToCommWriter"),
+ fd(aFd), entry(anEntry), sc(NULL), writeOffset(0), closer(NULL)
+{
+ debugs(16, 6, HERE << "FD " << fd);
+ closer = asyncCall(16, 5, "Mgr::StoreToCommWriter::noteCommClosed",
+ CommCbMemFunT<StoreToCommWriter, CommCloseCbParams>(this, &StoreToCommWriter::noteCommClosed));
+ comm_add_close_handler(fd, closer);
+}
+
+Mgr::StoreToCommWriter::~StoreToCommWriter()
+{
+ debugs(16, 6, HERE);
+ assert(!entry);
+ assert(!sc);
+ close();
+}
+
+/// closes our copy of the client HTTP connection socket
+void
+Mgr::StoreToCommWriter::close()
+{
+ if (fd >= 0) {
+ if (closer != NULL) {
+ comm_remove_close_handler(fd, closer);
+ closer = NULL;
+ }
+ comm_close(fd);
+ fd = -1;
+ }
+}
+
+void
+Mgr::StoreToCommWriter::start()
+{
+ debugs(16, 6, HERE);
+ Must(fd >= 0);
+ Must(entry != NULL);
+ entry->registerAbort(&StoreToCommWriter::Abort, this);
+ sc = storeClientListAdd(entry, this);
+ Must(sc != NULL);
+
+ // initiate the receive-from-store, write-to-comm sequence
+ scheduleStoreCopy();
+}
+
+void
+Mgr::StoreToCommWriter::scheduleStoreCopy()
+{
+ debugs(16, 6, HERE);
+ Must(entry != NULL);
+ Must(sc != NULL);
+ StoreIOBuffer readBuf(sizeof(buffer), writeOffset, buffer);
+ storeClientCopy(sc, entry, readBuf, &NoteStoreCopied, this);
+}
+
+void
+Mgr::StoreToCommWriter::NoteStoreCopied(void* data, StoreIOBuffer ioBuf)
+{
+ Must(data != NULL);
+ // make sync Store call async to get async call protections and features
+ StoreToCommWriter* writer = static_cast<StoreToCommWriter*>(data);
+ typedef UnaryMemFunT<StoreToCommWriter, StoreIOBuffer> MyDialer;
+ AsyncCall::Pointer call =
+ asyncCall(16, 5, "Mgr::StoreToCommWriter::noteStoreCopied",
+ MyDialer(writer, &StoreToCommWriter::noteStoreCopied, ioBuf));
+ ScheduleCallHere(call);
+}
+
+void
+Mgr::StoreToCommWriter::noteStoreCopied(StoreIOBuffer ioBuf)
+{
+ debugs(16, 6, HERE);
+ Must(!ioBuf.flags.error);
+ if (ioBuf.length > 0)
+ scheduleCommWrite(ioBuf); // write received action results to client
+ else
+ Must(doneAll()); // otherwise, why would Store call us with no data?
+}
+
+void
+Mgr::StoreToCommWriter::scheduleCommWrite(const StoreIOBuffer& ioBuf)
+{
+ debugs(16, 6, HERE);
+ Must(fd >= 0);
+ Must(ioBuf.data != NULL);
+ // write filled buffer
+ typedef CommCbMemFunT<StoreToCommWriter, CommIoCbParams> MyDialer;
+ AsyncCall::Pointer writer =
+ asyncCall(16, 5, "Mgr::StoreToCommWriter::noteCommWrote",
+ MyDialer(this, &StoreToCommWriter::noteCommWrote));
+ comm_write(fd, ioBuf.data, ioBuf.length, writer);
+}
+
+void
+Mgr::StoreToCommWriter::noteCommWrote(const CommIoCbParams& params)
+{
+ debugs(16, 6, HERE);
+ Must(params.flag == COMM_OK);
+ Must(params.fd == fd);
+ Must(params.size != 0);
+ writeOffset += params.size;
+ if (!doneAll())
+ scheduleStoreCopy(); // retrieve the next data portion
+}
+
+void
+Mgr::StoreToCommWriter::noteCommClosed(const CommCloseCbParams& params)
+{
+ debugs(16, 6, HERE);
+ Must(fd == params.fd);
+ fd = -1;
+ mustStop("commClosed");
+}
+
+void
+Mgr::StoreToCommWriter::swanSong()
+{
+ debugs(16, 6, HERE);
+ if (entry != NULL) {
+ if (sc != NULL) {
+ storeUnregister(sc, entry, this);
+ sc = NULL;
+ }
+ entry->unregisterAbort();
+ entry->unlock();
+ entry = NULL;
+ }
+ close();
+}
+
+bool
+Mgr::StoreToCommWriter::doneAll() const
+{
+ return entry &&
+ entry->store_status == STORE_OK && // the action is over
+ writeOffset >= entry->objectLen(); // we wrote all the results
+}
+
+void
+Mgr::StoreToCommWriter::Abort(void* param)
+{
+ StoreToCommWriter* mgrWriter = static_cast<StoreToCommWriter*>(param);
+ if (mgrWriter->fd >= 0)
+ comm_close(mgrWriter->fd);
+}
+
+
+int
+Mgr::ImportHttpFdIntoComm(int fd)
+{
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(addr);
+ if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &len) == 0) {
+ Ip::Address ipAddr(addr);
+ struct addrinfo* addr_info = NULL;
+ ipAddr.GetAddrInfo(addr_info);
+ addr_info->ai_socktype = SOCK_STREAM;
+ addr_info->ai_protocol = IPPROTO_TCP;
+ comm_import_opened(fd, ipAddr, COMM_NONBLOCKING, Ipc::FdNote(Ipc::fdnHttpSocket), addr_info);
+ ipAddr.FreeAddrInfo(addr_info);
+ } else {
+ debugs(16, DBG_CRITICAL, HERE << "ERROR: FD " << fd << ' ' << xstrerror());
+ ::close(fd);
+ fd = -1;
+ }
+ return fd;
+}
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_STORE_TO_COMM_WRITER_H
+#define SQUID_MGR_STORE_TO_COMM_WRITER_H
+
+#include "base/AsyncJob.h"
+#include "mgr/Action.h"
+#include "StoreIOBuffer.h"
+
+
+class store_client;
+class CommIoCbParams;
+class CommCloseCbParams;
+
+namespace Mgr
+{
+
+/// manages receive-from-store, write-to-comm, receive-... sequence
+/// for the given StoreEntry and client FD
+class StoreToCommWriter: public AsyncJob
+{
+public:
+ StoreToCommWriter(int aFd, StoreEntry *anEntry);
+ virtual ~StoreToCommWriter();
+
+protected:
+ /* AsyncJob API */
+ virtual void start();
+ virtual void swanSong();
+ virtual bool doneAll() const;
+
+ /// request more action results from the store
+ void scheduleStoreCopy();
+ /// receive some action results from the store
+ void noteStoreCopied(StoreIOBuffer ioBuf);
+ static void NoteStoreCopied(void* data, StoreIOBuffer ioBuf);
+ /// called by Store if the entry is no longer usable
+ static void Abort(void* param);
+
+ /// tell Comm to write action results
+ void scheduleCommWrite(const StoreIOBuffer& ioBuf);
+ /// called by Comm after the action results are written
+ void noteCommWrote(const CommIoCbParams& params);
+ /// called by Comm if the client socket got closed
+ void noteCommClosed(const CommCloseCbParams& params);
+
+ /// closes the local connection to the HTTP client, if any
+ void close();
+
+protected:
+ int fd; ///< HTTP client descriptor
+
+ StoreEntry* entry; ///< store entry with the cache manager response
+ store_client* sc; ///< our registration with the store
+ int64_t writeOffset; ///< number of bytes written to the client
+
+ AsyncCall::Pointer closer; ///< comm_close handler
+ char buffer[HTTP_REQBUF_SZ]; ///< action results; Store fills, Comm writes
+
+ CBDATA_CLASS2(StoreToCommWriter);
+};
+
+/// import HTTP socket fd from another strand into our Comm state
+extern int ImportHttpFdIntoComm(int fd);
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_STORE_TO_COMM_WRITER_H */
--- /dev/null
+/*
+ * $Id$
+ *
+ * DEBUG: section 16 Cache Manager API
+ *
+ */
+
+#ifndef SQUID_MGR_FORWARD_H
+#define SQUID_MGR_FORWARD_H
+
+#include "RefCount.h"
+
+namespace Mgr
+{
+
+class Action;
+class ActionCreator;
+class ActionProfile;
+class ActionWriter;
+class Command;
+class Request;
+class Response;
+
+typedef RefCount<Action> ActionPointer;
+typedef RefCount<ActionProfile> ActionProfilePointer;
+typedef RefCount<ActionCreator> ActionCreatorPointer;
+typedef RefCount<Command> CommandPointer;
+
+typedef ActionPointer (ClassActionCreationHandler)(const CommandPointer &cmd);
+
+} // namespace Mgr
+
+#endif /* SQUID_MGR_FORWARD_H */
#include "ProtoPort.h"
#include "acl/FilledChecklist.h"
#include "event.h"
-#include "CacheManager.h"
#include "htcp.h"
#include "HttpRequest.h"
#include "ICP.h"
#include "icmp/net_db.h"
#include "ip/Address.h"
#include "ip/tools.h"
+#include "mgr/Registration.h"
/* count mcast group peers every 15 minutes */
#define MCAST_COUNT_RATE 900
static void
neighborsRegisterWithCacheManager()
{
- CacheManager *manager = CacheManager::GetInstance();
- manager->registerAction("server_list",
+ Mgr::RegisterAction("server_list",
"Peer Cache Statistics",
neighborDumpPeers, 0, 1);
if (theInIcpConnection >= 0) {
- manager->registerAction("non_peers",
+ Mgr::RegisterAction("non_peers",
"List of Unknown sites sending ICP messages",
neighborDumpNonPeers, 0, 1);
}
*/
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "comm.h"
#include "pconn.h"
void
PconnModule::registerWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("pconn",
+ Mgr::RegisterAction("pconn",
"Persistent Connection Utilization Histograms",
DumpWrapper, 0, 1);
}
*/
#include "squid.h"
-#include "CacheManager.h"
#include "Store.h"
#include "HttpRequest.h"
+#include "mgr/Registration.h"
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
static void
peerSourceHashRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("sourcehash", "peer sourcehash information",
+ Mgr::RegisterAction("sourcehash", "peer sourcehash information",
peerSourceHashCachemgr, 0, 1);
}
*/
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "HttpRequest.h"
#include "auth/UserRequest.h"
static void
peerUserHashRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("userhash", "peer userhash information", peerUserHashCachemgr,
+ Mgr::RegisterAction("userhash", "peer userhash information", peerUserHashCachemgr,
0, 1);
}
#include "squid.h"
#include "auth/UserRequest.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "fde.h"
#include "client_side_request.h"
static void
redirectRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("redirector", "URL Redirector Stats", redirectStats, 0, 1);
+ Mgr::RegisterAction("redirector", "URL Redirector Stats", redirectStats, 0, 1);
}
void
#endif
#include "squid.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "MemObject.h"
#include "HttpRequest.h"
static void
refreshRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("refresh", "Refresh Algorithm Statistics", refreshStats, 0, 1);
+ Mgr::RegisterAction("refresh", "Refresh Algorithm Statistics", refreshStats, 0, 1);
}
void
#include "event.h"
#include "StoreClient.h"
#include "auth/UserRequest.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "HttpRequest.h"
#include "MemObject.h"
#include "MemBuf.h"
#include "SquidMath.h"
#include "SquidTime.h"
+#include "mgr/CountersAction.h"
+#include "mgr/FunAction.h"
+#include "mgr/InfoAction.h"
+#include "mgr/IntervalAction.h"
+#include "mgr/IoAction.h"
+#include "mgr/ServiceTimesAction.h"
/* these are included because they expose stats calls */
/* TODO: provide a self registration mechanism for those classes
static double statPctileSvc(double, int, int);
static void statStoreEntry(MemBuf * mb, StoreEntry * e);
static double statCPUUsage(int minutes);
-static OBJH stat_io_get;
static OBJH stat_objects_get;
static OBJH stat_vmobjects_get;
#if DEBUG_OPENFD
static OBJH statOpenfdObj;
#endif
static EVH statObjects;
-static OBJH info_get;
static OBJH statCountersDump;
static OBJH statPeerSelect;
static OBJH statDigestBlob;
-static OBJH statAvg5min;
-static OBJH statAvg60min;
static OBJH statUtilization;
static OBJH statCountersHistograms;
static OBJH statClientRequests;
+void GetAvgStat(Mgr::IntervalActionData& stats, int minutes, int hours);
+void DumpAvgStat(Mgr::IntervalActionData& stats, StoreEntry* sentry);
+void GetInfo(Mgr::InfoActionData& stats);
+void DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry);
+void DumpMallocStatistics(StoreEntry* sentry);
+void GetCountersStats(Mgr::CountersActionData& stats);
+void DumpCountersStats(Mgr::CountersActionData& stats, StoreEntry* sentry);
+void GetServiceTimesStats(Mgr::ServiceTimesActionData& stats);
+void DumpServiceTimesStats(Mgr::ServiceTimesActionData& stats, StoreEntry* sentry);
+void GetIoStats(Mgr::IoActionData& stats);
+void DumpIoStats(Mgr::IoActionData& stats, StoreEntry* sentry);
#if XMALLOC_STATISTICS
static void info_get_mallstat(int, int, int, void *);
statCountersDump(e);
}
-static void
-stat_io_get(StoreEntry * sentry)
+void
+GetIoStats(Mgr::IoActionData& stats)
+{
+ int i;
+
+ stats.http_reads = IOStats.Http.reads;
+
+ for (i = 0; i < _iostats::histSize; i++) {
+ stats.http_read_hist[i] = IOStats.Http.read_hist[i];
+ }
+
+ stats.ftp_reads = IOStats.Ftp.reads;
+
+ for (i = 0; i < _iostats::histSize; i++) {
+ stats.ftp_read_hist[i] = IOStats.Ftp.read_hist[i];
+ }
+
+ stats.gopher_reads = IOStats.Gopher.reads;
+
+ for (i = 0; i < _iostats::histSize; i++) {
+ stats.gopher_read_hist[i] = IOStats.Gopher.read_hist[i];
+ }
+}
+
+void
+DumpIoStats(Mgr::IoActionData& stats, StoreEntry* sentry)
{
int i;
storeAppendPrintf(sentry, "HTTP I/O\n");
- storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Http.reads);
+ storeAppendPrintf(sentry, "number of reads: %.0f\n", stats.http_reads);
storeAppendPrintf(sentry, "Read Histogram:\n");
- for (i = 0; i < 16; i++) {
- storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
- i ? (1 << (i - 1)) + 1 : 1,
- 1 << i,
- IOStats.Http.read_hist[i],
- Math::intPercent(IOStats.Http.read_hist[i], IOStats.Http.reads));
+ for (i = 0; i < _iostats::histSize; i++) {
+ storeAppendPrintf(sentry, "%5d-%5d: %9.0f %2.0f%%\n",
+ i ? (1 << (i - 1)) + 1 : 1,
+ 1 << i,
+ stats.http_read_hist[i],
+ Math::doublePercent(stats.http_read_hist[i], stats.http_reads));
}
storeAppendPrintf(sentry, "\n");
storeAppendPrintf(sentry, "FTP I/O\n");
- storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Ftp.reads);
+ storeAppendPrintf(sentry, "number of reads: %.0f\n", stats.ftp_reads);
storeAppendPrintf(sentry, "Read Histogram:\n");
- for (i = 0; i < 16; i++) {
- storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
- i ? (1 << (i - 1)) + 1 : 1,
- 1 << i,
- IOStats.Ftp.read_hist[i],
- Math::intPercent(IOStats.Ftp.read_hist[i], IOStats.Ftp.reads));
+ for (i = 0; i < _iostats::histSize; i++) {
+ storeAppendPrintf(sentry, "%5d-%5d: %9.0f %2.0f%%\n",
+ i ? (1 << (i - 1)) + 1 : 1,
+ 1 << i,
+ stats.ftp_read_hist[i],
+ Math::doublePercent(stats.ftp_read_hist[i], stats.ftp_reads));
}
storeAppendPrintf(sentry, "\n");
storeAppendPrintf(sentry, "Gopher I/O\n");
- storeAppendPrintf(sentry, "number of reads: %d\n", IOStats.Gopher.reads);
+ storeAppendPrintf(sentry, "number of reads: %.0f\n", stats.gopher_reads);
storeAppendPrintf(sentry, "Read Histogram:\n");
- for (i = 0; i < 16; i++) {
- storeAppendPrintf(sentry, "%5d-%5d: %9d %2d%%\n",
- i ? (1 << (i - 1)) + 1 : 1,
- 1 << i,
- IOStats.Gopher.read_hist[i],
- Math::intPercent(IOStats.Gopher.read_hist[i], IOStats.Gopher.reads));
+ for (i = 0; i < _iostats::histSize; i++) {
+ storeAppendPrintf(sentry, "%5d-%5d: %9.0f %2.0f%%\n",
+ i ? (1 << (i - 1)) + 1 : 1,
+ 1 << i,
+ stats.gopher_read_hist[i],
+ Math::doublePercent(stats.gopher_read_hist[i], stats.gopher_reads));
}
storeAppendPrintf(sentry, "\n");
StoreEntry *e;
if (state->theSearch->isDone()) {
+ if (UsingSmp())
+ storeAppendPrintf(state->sentry, "} by kid%d\n\n", KidIdentifier);
state->sentry->complete();
state->sentry->unlock();
cbdataFree(state);
#endif
-static void
-info_get(StoreEntry * sentry)
+void
+GetInfo(Mgr::InfoActionData& stats)
{
struct rusage rusage;
#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
struct mallinfo mp;
- long t;
#endif
runtime = tvSubDsec(squid_start, current_time);
if (runtime == 0.0)
runtime = 1.0;
+ stats.squid_start = squid_start;
+
+ stats.current_time = current_time;
+
+ stats.client_http_clients = statCounter.client_http.clients;
+
+ stats.client_http_requests = statCounter.client_http.requests;
+
+ stats.icp_pkts_recv = statCounter.icp.pkts_recv;
+
+ stats.icp_pkts_sent = statCounter.icp.pkts_sent;
+
+ stats.icp_replies_queued = statCounter.icp.replies_queued;
+
+#if USE_HTCP
+
+ stats.htcp_pkts_recv = statCounter.htcp.pkts_recv;
+
+ stats.htcp_pkts_sent = statCounter.htcp.pkts_sent;
+
+#endif
+
+ stats.request_failure_ratio = request_failure_ratio;
+
+ stats.avg_client_http_requests = statCounter.client_http.requests / (runtime / 60.0);
+
+ stats.avg_icp_messages = (statCounter.icp.pkts_sent + statCounter.icp.pkts_recv) / (runtime / 60.0);
+
+ stats.select_loops = statCounter.select_loops;
+ stats.avg_loop_time = 1000.0 * runtime / statCounter.select_loops;
+
+ stats.request_hit_ratio5 = statRequestHitRatio(5);
+ stats.request_hit_ratio60 = statRequestHitRatio(60);
+
+ stats.byte_hit_ratio5 = statByteHitRatio(5);
+ stats.byte_hit_ratio60 = statByteHitRatio(60);
+
+ stats.request_hit_mem_ratio5 = statRequestHitMemoryRatio(5);
+ stats.request_hit_mem_ratio60 = statRequestHitMemoryRatio(60);
+
+ stats.request_hit_disk_ratio5 = statRequestHitDiskRatio(5);
+ stats.request_hit_disk_ratio60 = statRequestHitDiskRatio(60);
+
+ stats.store_swap_size = store_swap_size;
+ stats.store_swap_max_size = Store::Root().maxSize();
+
+ stats.store_mem_size = mem_node::StoreMemSize();
+ stats.store_pages_max = store_pages_max;
+ stats.store_mem_used = mem_node::InUseCount();
+
+ stats.objects_size = n_disk_objects ? (double) store_swap_size / n_disk_objects : 0.0;
+
+ stats.unlink_requests = statCounter.unlink.requests;
+
+ stats.http_requests5 = statPctileSvc(0.5, 5, PCTILE_HTTP);
+ stats.http_requests60 = statPctileSvc(0.5, 60, PCTILE_HTTP);
+
+ stats.cache_misses5 = statPctileSvc(0.5, 5, PCTILE_MISS);
+ stats.cache_misses60 = statPctileSvc(0.5, 60, PCTILE_MISS);
+
+ stats.cache_hits5 = statPctileSvc(0.5, 5, PCTILE_HIT);
+ stats.cache_hits60 = statPctileSvc(0.5, 60, PCTILE_HIT);
+
+ stats.near_hits5 = statPctileSvc(0.5, 5, PCTILE_NH);
+ stats.near_hits60 = statPctileSvc(0.5, 60, PCTILE_NH);
+
+ stats.not_modified_replies5 = statPctileSvc(0.5, 5, PCTILE_NM);
+ stats.not_modified_replies60 = statPctileSvc(0.5, 60, PCTILE_NM);
+
+ stats.dns_lookups5 = statPctileSvc(0.5, 5, PCTILE_DNS);
+ stats.dns_lookups60 = statPctileSvc(0.5, 60, PCTILE_DNS);
+
+ stats.icp_queries5 = statPctileSvc(0.5, 5, PCTILE_ICP_QUERY);
+ stats.icp_queries60 = statPctileSvc(0.5, 60, PCTILE_ICP_QUERY);
+
+ squid_getrusage(&rusage);
+ cputime = rusage_cputime(&rusage);
+
+ stats.up_time = runtime;
+ stats.cpu_time = cputime;
+ stats.cpu_usage = Math::doublePercent(cputime, runtime);
+ stats.cpu_usage5 = statCPUUsage(5);
+ stats.cpu_usage60 = statCPUUsage(60);
+
+#if HAVE_SBRK
+
+ stats.proc_data_seg = ((char *) sbrk(0) - (char *) sbrk_start);
+
+#endif
+
+ stats.maxrss = rusage_maxrss(&rusage);
+
+ stats.page_faults = rusage_pagefaults(&rusage);
+
+#if HAVE_MSTATS && HAVE_GNUMALLOC_H
+
+ ms = mstats();
+
+ stats.ms_bytes_total = ms.bytes_total;
+
+ stats.ms_bytes_free = ms.bytes_free;
+
+#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
+
+ mp = mallinfo();
+
+ stats.mp_arena = mp.arena;
+
+ stats.mp_uordblks = mp.uordblks;
+ stats.mp_ordblks = mp.ordblks;
+
+ stats.mp_usmblks = mp.usmblks;
+ stats.mp_smblks = mp.smblks;
+
+ stats.mp_hblkhd = mp.hblkhd;
+ stats.mp_hblks = mp.hblks;
+
+ stats.mp_fsmblks = mp.fsmblks;
+
+ stats.mp_fordblks = mp.fordblks;
+
+#if HAVE_STRUCT_MALLINFO_MXFAST
+
+ stats.mp_mxfast = mp.mxfast;
+
+ stats.mp_nlblks = mp.nlblks;
+
+ stats.mp_grain = mp.grain;
+
+ stats.mp_uordbytes = mp.uordbytes;
+
+ stats.mp_allocated = mp.allocated;
+
+ stats.mp_treeoverhead = mp.treeoverhead;
+
+#endif /* HAVE_STRUCT_MALLINFO_MXFAST */
+#endif /* HAVE_MALLINFO */
+
+ stats.total_accounted = statMemoryAccounted();
+
+ {
+ MemPoolGlobalStats mp_stats;
+ memPoolGetGlobalStats(&mp_stats);
+#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
+
+ stats.mem_pool_allocated = mp_stats.TheMeter->alloc.level;
+#endif
+
+ stats.gb_freed_count = mp_stats.TheMeter->gb_saved.count;
+ stats.gb_freed_count = mp_stats.TheMeter->gb_freed.count;
+ }
+
+ stats.max_fd = Squid_MaxFD;
+ stats.biggest_fd = Biggest_FD;
+ stats.number_fd = Number_FD;
+ stats.opening_fd = Opening_FD;
+ stats.num_fd_free = fdNFree();
+ stats.reserved_fd = RESERVED_FD;
+ stats.store_open_disk_fd = store_open_disk_fd;
+
+ stats.store_entries = StoreEntry::inUseCount();
+ stats.store_mem_entries = MemObject::inUseCount();
+ stats.hot_obj_count = hot_obj_count;
+ stats.n_disk_objects = n_disk_objects;
+}
+
+void
+DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry)
+{
storeAppendPrintf(sentry, "Squid Object Cache: Version %s\n",
version_string);
#endif
storeAppendPrintf(sentry, "Start Time:\t%s\n",
- mkrfc1123(squid_start.tv_sec));
+ mkrfc1123(stats.squid_start.tv_sec));
storeAppendPrintf(sentry, "Current Time:\t%s\n",
- mkrfc1123(current_time.tv_sec));
+ mkrfc1123(stats.current_time.tv_sec));
storeAppendPrintf(sentry, "Connection information for %s:\n",APP_SHORTNAME);
- storeAppendPrintf(sentry, "\tNumber of clients accessing cache:\t%u\n",
- statCounter.client_http.clients);
+ storeAppendPrintf(sentry, "\tNumber of clients accessing cache:\t%.0f\n",
+ stats.client_http_clients);
- storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%u\n",
- statCounter.client_http.requests);
+ storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%.0f\n",
+ stats.client_http_requests);
- storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%u\n",
- statCounter.icp.pkts_recv);
+ storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%.0f\n",
+ stats.icp_pkts_recv);
- storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%u\n",
- statCounter.icp.pkts_sent);
+ storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%.0f\n",
+ stats.icp_pkts_sent);
- storeAppendPrintf(sentry, "\tNumber of queued ICP replies:\t%u\n",
- statCounter.icp.replies_queued);
+ storeAppendPrintf(sentry, "\tNumber of queued ICP replies:\t%.0f\n",
+ stats.icp_replies_queued);
#if USE_HTCP
- storeAppendPrintf(sentry, "\tNumber of HTCP messages received:\t%u\n",
- statCounter.htcp.pkts_recv);
+ storeAppendPrintf(sentry, "\tNumber of HTCP messages received:\t%.0f\n",
+ stats.htcp_pkts_recv);
- storeAppendPrintf(sentry, "\tNumber of HTCP messages sent:\t%u\n",
- statCounter.htcp.pkts_sent);
+ storeAppendPrintf(sentry, "\tNumber of HTCP messages sent:\t%.0f\n",
+ stats.htcp_pkts_sent);
#endif
+ double fct = stats.count > 1 ? stats.count : 1.0;
storeAppendPrintf(sentry, "\tRequest failure ratio:\t%5.2f\n",
- request_failure_ratio);
+ stats.request_failure_ratio / fct);
storeAppendPrintf(sentry, "\tAverage HTTP requests per minute since start:\t%.1f\n",
- statCounter.client_http.requests / (runtime / 60.0));
+ stats.avg_client_http_requests / fct);
storeAppendPrintf(sentry, "\tAverage ICP messages per minute since start:\t%.1f\n",
- (statCounter.icp.pkts_sent + statCounter.icp.pkts_recv) / (runtime / 60.0));
+ stats.avg_icp_messages / fct);
- storeAppendPrintf(sentry, "\tSelect loop called: %ld times, %0.3f ms avg\n",
- statCounter.select_loops, 1000.0 * runtime / statCounter.select_loops);
+ storeAppendPrintf(sentry, "\tSelect loop called: %.0f times, %0.3f ms avg\n",
+ stats.select_loops, stats.avg_loop_time / fct);
storeAppendPrintf(sentry, "Cache information for %s:\n",APP_SHORTNAME);
storeAppendPrintf(sentry, "\tHits as %% of all requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
- statRequestHitRatio(5),
- statRequestHitRatio(60));
+ stats.request_hit_ratio5 / fct,
+ stats.request_hit_ratio60 / fct);
storeAppendPrintf(sentry, "\tHits as %% of bytes sent:\t5min: %3.1f%%, 60min: %3.1f%%\n",
- statByteHitRatio(5),
- statByteHitRatio(60));
+ stats.byte_hit_ratio5 / fct,
+ stats.byte_hit_ratio60 / fct);
storeAppendPrintf(sentry, "\tMemory hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
- statRequestHitMemoryRatio(5),
- statRequestHitMemoryRatio(60));
+ stats.request_hit_mem_ratio5 / fct,
+ stats.request_hit_mem_ratio60 / fct);
storeAppendPrintf(sentry, "\tDisk hits as %% of hit requests:\t5min: %3.1f%%, 60min: %3.1f%%\n",
- statRequestHitDiskRatio(5),
- statRequestHitDiskRatio(60));
+ stats.request_hit_disk_ratio5 / fct,
+ stats.request_hit_disk_ratio60 / fct);
- storeAppendPrintf(sentry, "\tStorage Swap size:\t%lu KB\n",
- store_swap_size);
+ storeAppendPrintf(sentry, "\tStorage Swap size:\t%.0f KB\n",
+ stats.store_swap_size / 1024);
storeAppendPrintf(sentry, "\tStorage Swap capacity:\t%4.1f%% used, %4.1f%% free\n",
- Math::doublePercent(store_swap_size, Store::Root().maxSize()),
- Math::doublePercent((Store::Root().maxSize() - store_swap_size), Store::Root().maxSize()));
-
+ Math::doublePercent(stats.store_swap_size, stats.store_swap_max_size),
+ Math::doublePercent(stats.store_swap_max_size - stats.store_swap_size, stats.store_swap_max_size));
- storeAppendPrintf(sentry, "\tStorage Mem size:\t%lu KB\n",
- (unsigned long)(mem_node::StoreMemSize() >> 10));
+ storeAppendPrintf(sentry, "\tStorage Mem size:\t%.0f KB\n",
+ stats.store_mem_size / 1024);
- double mFree = 0.0;
- if (mem_node::InUseCount() <= store_pages_max)
- mFree = Math::doublePercent((store_pages_max - mem_node::InUseCount()), store_pages_max);
+ const double mFree = max(0.0, stats.store_pages_max-stats.store_mem_used);
storeAppendPrintf(sentry, "\tStorage Mem capacity:\t%4.1f%% used, %4.1f%% free\n",
- Math::doublePercent(mem_node::InUseCount(), store_pages_max),
- mFree);
+ Math::doublePercent(stats.store_mem_used, stats.store_pages_max),
+ Math::doublePercent(mFree, stats.store_pages_max));
storeAppendPrintf(sentry, "\tMean Object Size:\t%0.2f KB\n",
- n_disk_objects ? (double) store_swap_size / n_disk_objects : 0.0);
+ stats.objects_size / fct);
- storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%ld\n",
- (long)statCounter.unlink.requests);
+ storeAppendPrintf(sentry, "\tRequests given to unlinkd:\t%.0f\n",
+ stats.unlink_requests);
storeAppendPrintf(sentry, "Median Service Times (seconds) 5 min 60 min:\n");
+ fct = stats.count > 1 ? stats.count * 1000.0 : 1000.0;
storeAppendPrintf(sentry, "\tHTTP Requests (All): %8.5f %8.5f\n",
- statPctileSvc(0.5, 5, PCTILE_HTTP) / 1000.0,
- statPctileSvc(0.5, 60, PCTILE_HTTP) / 1000.0);
+ stats.http_requests5 / fct,
+ stats.http_requests60 / fct);
storeAppendPrintf(sentry, "\tCache Misses: %8.5f %8.5f\n",
- statPctileSvc(0.5, 5, PCTILE_MISS) / 1000.0,
- statPctileSvc(0.5, 60, PCTILE_MISS) / 1000.0);
+ stats.cache_misses5 / fct,
+ stats.cache_misses60 / fct);
storeAppendPrintf(sentry, "\tCache Hits: %8.5f %8.5f\n",
- statPctileSvc(0.5, 5, PCTILE_HIT) / 1000.0,
- statPctileSvc(0.5, 60, PCTILE_HIT) / 1000.0);
+ stats.cache_hits5 / fct,
+ stats.cache_hits60 / fct);
storeAppendPrintf(sentry, "\tNear Hits: %8.5f %8.5f\n",
- statPctileSvc(0.5, 5, PCTILE_NH) / 1000.0,
- statPctileSvc(0.5, 60, PCTILE_NH) / 1000.0);
+ stats.near_hits5 / fct,
+ stats.near_hits60 / fct);
storeAppendPrintf(sentry, "\tNot-Modified Replies: %8.5f %8.5f\n",
- statPctileSvc(0.5, 5, PCTILE_NM) / 1000.0,
- statPctileSvc(0.5, 60, PCTILE_NM) / 1000.0);
+ stats.not_modified_replies5 / fct,
+ stats.not_modified_replies60 / fct);
storeAppendPrintf(sentry, "\tDNS Lookups: %8.5f %8.5f\n",
- statPctileSvc(0.5, 5, PCTILE_DNS) / 1000.0,
- statPctileSvc(0.5, 60, PCTILE_DNS) / 1000.0);
+ stats.dns_lookups5 / fct,
+ stats.dns_lookups60 / fct);
+ fct = stats.count > 1 ? stats.count * 1000000.0 : 1000000.0;
storeAppendPrintf(sentry, "\tICP Queries: %8.5f %8.5f\n",
- statPctileSvc(0.5, 5, PCTILE_ICP_QUERY) / 1000000.0,
- statPctileSvc(0.5, 60, PCTILE_ICP_QUERY) / 1000000.0);
-
- squid_getrusage(&rusage);
-
- cputime = rusage_cputime(&rusage);
+ stats.icp_queries5 / fct,
+ stats.icp_queries60 / fct);
storeAppendPrintf(sentry, "Resource usage for %s:\n", APP_SHORTNAME);
- storeAppendPrintf(sentry, "\tUP Time:\t%.3f seconds\n", runtime);
+ storeAppendPrintf(sentry, "\tUP Time:\t%.3f seconds\n", stats.up_time);
- storeAppendPrintf(sentry, "\tCPU Time:\t%.3f seconds\n", cputime);
+ storeAppendPrintf(sentry, "\tCPU Time:\t%.3f seconds\n", stats.cpu_time);
storeAppendPrintf(sentry, "\tCPU Usage:\t%.2f%%\n",
- Math::doublePercent(cputime, runtime));
+ stats.cpu_usage);
storeAppendPrintf(sentry, "\tCPU Usage, 5 minute avg:\t%.2f%%\n",
- statCPUUsage(5));
+ stats.cpu_usage5);
storeAppendPrintf(sentry, "\tCPU Usage, 60 minute avg:\t%.2f%%\n",
- statCPUUsage(60));
+ stats.cpu_usage60);
#if HAVE_SBRK
- storeAppendPrintf(sentry, "\tProcess Data Segment Size via sbrk(): %lu KB\n",
- (unsigned long) (((char *) sbrk(0) - (char *) sbrk_start) >> 10));
+ storeAppendPrintf(sentry, "\tProcess Data Segment Size via sbrk(): %.0f KB\n",
+ stats.proc_data_seg / 1024);
#endif
- storeAppendPrintf(sentry, "\tMaximum Resident Size: %ld KB\n",
- (long)rusage_maxrss(&rusage));
+ storeAppendPrintf(sentry, "\tMaximum Resident Size: %.0f KB\n",
+ stats.maxrss);
- storeAppendPrintf(sentry, "\tPage faults with physical i/o: %ld\n",
- (long)rusage_pagefaults(&rusage));
+ storeAppendPrintf(sentry, "\tPage faults with physical i/o: %.0f\n",
+ stats.page_faults);
#if HAVE_MSTATS && HAVE_GNUMALLOC_H
- ms = mstats();
-
storeAppendPrintf(sentry, "Memory usage for %s via mstats():\n",APP_SHORTNAME);
- storeAppendPrintf(sentry, "\tTotal space in arena: %6ld KB\n",
- (long)(ms.bytes_total >> 10));
+ storeAppendPrintf(sentry, "\tTotal space in arena: %6.0f KB\n",
+ stats.ms_bytes_total / 1024);
- storeAppendPrintf(sentry, "\tTotal free: %6ld KB %d%%\n",
- (long)(ms.bytes_free >> 10), Math::intPercent(ms.bytes_free, ms.bytes_total));
+ storeAppendPrintf(sentry, "\tTotal free: %6.0f KB %.0f%%\n",
+ stats.ms_bytes_free / 1024,
+ Math::doublePercent(stats.ms_bytes_free, stats.ms_bytes_total));
#elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
- mp = mallinfo();
-
storeAppendPrintf(sentry, "Memory usage for %s via mallinfo():\n",APP_SHORTNAME);
- storeAppendPrintf(sentry, "\tTotal space in arena: %6ld KB\n",
- (long)(mp.arena >> 10));
+ storeAppendPrintf(sentry, "\tTotal space in arena: %6.0f KB\n",
+ stats.mp_arena / 1024);
- storeAppendPrintf(sentry, "\tOrdinary blocks: %6ld KB %6ld blks\n",
- (long)(mp.uordblks >> 10), (long)mp.ordblks);
+ storeAppendPrintf(sentry, "\tOrdinary blocks: %6.0f KB %6.0f blks\n",
+ stats.mp_uordblks / 1024, stats.mp_ordblks);
- storeAppendPrintf(sentry, "\tSmall blocks: %6ld KB %6ld blks\n",
- (long)(mp.usmblks >> 10), (long)mp.smblks);
+ storeAppendPrintf(sentry, "\tSmall blocks: %6.0f KB %6.0f blks\n",
+ stats.mp_usmblks / 1024, stats.mp_smblks);
- storeAppendPrintf(sentry, "\tHolding blocks: %6ld KB %6ld blks\n",
- (long)(mp.hblkhd >> 10), (long)mp.hblks);
+ storeAppendPrintf(sentry, "\tHolding blocks: %6.0f KB %6.0f blks\n",
+ stats.mp_hblkhd / 1024, stats.mp_hblks);
- storeAppendPrintf(sentry, "\tFree Small blocks: %6ld KB\n",
- (long)(mp.fsmblks >> 10));
+ storeAppendPrintf(sentry, "\tFree Small blocks: %6.0f KB\n",
+ stats.mp_fsmblks / 1024);
- storeAppendPrintf(sentry, "\tFree Ordinary blocks: %6ld KB\n",
- (long)(mp.fordblks >> 10));
+ storeAppendPrintf(sentry, "\tFree Ordinary blocks: %6.0f KB\n",
+ stats.mp_fordblks / 1024);
- t = mp.uordblks + mp.usmblks + mp.hblkhd;
+ double t = stats.mp_fsmblks + stats.mp_fordblks;
- storeAppendPrintf(sentry, "\tTotal in use: %6ld KB %d%%\n",
- (long)(t >> 10), Math::intPercent(t, mp.arena + mp.hblkhd));
+ storeAppendPrintf(sentry, "\tTotal in use: %6.0f KB %.0f%%\n",
+ t / 1024, Math::doublePercent(t, stats.mp_arena + stats.mp_hblkhd));
- t = mp.fsmblks + mp.fordblks;
+ t = stats.mp_fsmblks + stats.mp_fordblks;
- storeAppendPrintf(sentry, "\tTotal free: %6ld KB %d%%\n",
- (long)(t >> 10), Math::intPercent(t, mp.arena + mp.hblkhd));
+ storeAppendPrintf(sentry, "\tTotal free: %6.0f KB %.0f%%\n",
+ t / 1024, Math::doublePercent(t, stats.mp_arena + stats.mp_hblkhd));
- t = mp.arena + mp.hblkhd;
+ t = stats.mp_arena + stats.mp_hblkhd;
- storeAppendPrintf(sentry, "\tTotal size: %6ld KB\n",
- (long)(t >> 10));
+ storeAppendPrintf(sentry, "\tTotal size: %6.0f KB\n",
+ t / 1024);
#if HAVE_STRUCT_MALLINFO_MXFAST
- storeAppendPrintf(sentry, "\tmax size of small blocks:\t%d\n", mp.mxfast);
+ storeAppendPrintf(sentry, "\tmax size of small blocks:\t%.0f\n", stats.mp_mxfast);
- storeAppendPrintf(sentry, "\tnumber of small blocks in a holding block:\t%ld\n",
- (long)mp.nlblks);
+ storeAppendPrintf(sentry, "\tnumber of small blocks in a holding block:\t%.0f\n",
+ stats.mp_nlblks);
- storeAppendPrintf(sentry, "\tsmall block rounding factor:\t%ld\n", (long)mp.grain);
+ storeAppendPrintf(sentry, "\tsmall block rounding factor:\t%.0f\n", stats.mp_grain);
- storeAppendPrintf(sentry, "\tspace (including overhead) allocated in ord. blks:\t%ld\n",
- (long)mp.uordbytes);
+ storeAppendPrintf(sentry, "\tspace (including overhead) allocated in ord. blks:\t%.0f\n"
+ ,stats.mp_uordbytes);
- storeAppendPrintf(sentry, "\tnumber of ordinary blocks allocated:\t%ld\n",
- (long)mp.allocated);
+ storeAppendPrintf(sentry, "\tnumber of ordinary blocks allocated:\t%.0f\n",
+ stats.mp_allocated);
- storeAppendPrintf(sentry, "\tbytes used in maintaining the free tree:\t%ld\n",
- (long)mp.treeoverhead);
+ storeAppendPrintf(sentry, "\tbytes used in maintaining the free tree:\t%.0f\n",
+ stats.mp_treeoverhead);
#endif /* HAVE_STRUCT_MALLINFO_MXFAST */
#endif /* HAVE_MALLINFO */
#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
- storeAppendPrintf(sentry, "\tTotal accounted: %6ld KB %3d%%\n",
- (long)(statMemoryAccounted() >> 10), Math::intPercent(statMemoryAccounted(), t));
+ storeAppendPrintf(sentry, "\tTotal accounted: %6.0f KB %3.0f%%\n",
+ stats.total_accounted / 1024, Math::doublePercent(stats.total_accounted, t));
#else
- storeAppendPrintf(sentry, "\tTotal accounted: %6ld KB\n",
- (long)(statMemoryAccounted() >> 10));
+ storeAppendPrintf(sentry, "\tTotal accounted: %6.0f KB\n",
+ stats.total_accounted / 1024);
#endif
{
memPoolGetGlobalStats(&mp_stats);
#if !(HAVE_MSTATS && HAVE_GNUMALLOC_H) && HAVE_MALLINFO && HAVE_STRUCT_MALLINFO
- storeAppendPrintf(sentry, "\tmemPool accounted: %6ld KB %3d%%\n",
- (long)(mp_stats.TheMeter->alloc.level >> 10),
- Math::intPercent(mp_stats.TheMeter->alloc.level, t));
+ storeAppendPrintf(sentry, "\tmemPool accounted: %6.0f KB %3.0f%%\n",
+ stats.mem_pool_allocated / 1024,
+ Math::doublePercent(stats.mem_pool_allocated, t));
- int iFree = 0;
- if (t >= mp_stats.TheMeter->alloc.level)
- iFree = Math::intPercent((t - mp_stats.TheMeter->alloc.level), t);
- storeAppendPrintf(sentry, "\tmemPool unaccounted: %6ld KB %3d%%\n",
- (long)((t - mp_stats.TheMeter->alloc.level) >> 10), iFree);
+ const double iFree = max(0.0, t - stats.mem_pool_allocated);
+ storeAppendPrintf(sentry, "\tmemPool unaccounted: %6.0f KB %3.0f%%\n",
+ (t - stats.mem_pool_allocated) / 1024,
+ Math::doublePercent(iFree, t));
#endif
storeAppendPrintf(sentry, "\tmemPoolAlloc calls: %9.0f\n",
- mp_stats.TheMeter->gb_saved.count);
+ stats.gb_saved_count);
storeAppendPrintf(sentry, "\tmemPoolFree calls: %9.0f\n",
- mp_stats.TheMeter->gb_freed.count);
+ stats.gb_freed_count);
}
storeAppendPrintf(sentry, "File descriptor usage for %s:\n", APP_SHORTNAME);
- storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4d\n",
- Squid_MaxFD);
- storeAppendPrintf(sentry, "\tLargest file desc currently in use: %4d\n",
- Biggest_FD);
- storeAppendPrintf(sentry, "\tNumber of file desc currently in use: %4d\n",
- Number_FD);
- storeAppendPrintf(sentry, "\tFiles queued for open: %4d\n",
- Opening_FD);
- storeAppendPrintf(sentry, "\tAvailable number of file descriptors: %4d\n",
- fdNFree());
- storeAppendPrintf(sentry, "\tReserved number of file descriptors: %4d\n",
- RESERVED_FD);
- storeAppendPrintf(sentry, "\tStore Disk files open: %4d\n",
- store_open_disk_fd);
+ storeAppendPrintf(sentry, "\tMaximum number of file descriptors: %4.0f\n",
+ stats.max_fd);
+ storeAppendPrintf(sentry, "\tLargest file desc currently in use: %4.0f\n",
+ stats.biggest_fd);
+ storeAppendPrintf(sentry, "\tNumber of file desc currently in use: %4.0f\n",
+ stats.number_fd);
+ storeAppendPrintf(sentry, "\tFiles queued for open: %4.0f\n",
+ stats.opening_fd);
+ storeAppendPrintf(sentry, "\tAvailable number of file descriptors: %4.0f\n",
+ stats.num_fd_free);
+ storeAppendPrintf(sentry, "\tReserved number of file descriptors: %4.0f\n",
+ stats.reserved_fd);
+ storeAppendPrintf(sentry, "\tStore Disk files open: %4.0f\n",
+ stats.store_open_disk_fd);
storeAppendPrintf(sentry, "Internal Data Structures:\n");
- storeAppendPrintf(sentry, "\t%6lu StoreEntries\n",
- (unsigned long)StoreEntry::inUseCount());
- storeAppendPrintf(sentry, "\t%6lu StoreEntries with MemObjects\n",
- (unsigned long)MemObject::inUseCount());
- storeAppendPrintf(sentry, "\t%6ld Hot Object Cache Items\n",
- (long)hot_obj_count);
- storeAppendPrintf(sentry, "\t%6ld on-disk objects\n",
- (long)n_disk_objects);
+ storeAppendPrintf(sentry, "\t%6.0f StoreEntries\n",
+ stats.store_entries);
+ storeAppendPrintf(sentry, "\t%6.0f StoreEntries with MemObjects\n",
+ stats.store_mem_entries);
+ storeAppendPrintf(sentry, "\t%6.0f Hot Object Cache Items\n",
+ stats.hot_obj_count);
+ storeAppendPrintf(sentry, "\t%6.0f on-disk objects\n",
+ stats.n_disk_objects);
+}
+void
+DumpMallocStatistics(StoreEntry* sentry)
+{
#if XMALLOC_STATISTICS
xm_deltat = current_dtime - xm_time;
#endif
}
-static void
-service_times(StoreEntry * sentry)
+void
+GetServiceTimesStats(Mgr::ServiceTimesActionData& stats)
+{
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
+ double p = (i + 1) * 5 / 100.0;
+ stats.http_requests5[i] = statPctileSvc(p, 5, PCTILE_HTTP);
+ stats.http_requests60[i] = statPctileSvc(p, 60, PCTILE_HTTP);
+
+ stats.cache_misses5[i] = statPctileSvc(p, 5, PCTILE_MISS);
+ stats.cache_misses60[i] = statPctileSvc(p, 60, PCTILE_MISS);
+
+ stats.cache_hits5[i] = statPctileSvc(p, 5, PCTILE_HIT);
+ stats.cache_hits60[i] = statPctileSvc(p, 60, PCTILE_HIT);
+
+ stats.near_hits5[i] = statPctileSvc(p, 5, PCTILE_NH);
+ stats.near_hits60[i] = statPctileSvc(p, 60, PCTILE_NH);
+
+ stats.not_modified_replies5[i] = statPctileSvc(p, 5, PCTILE_NM);
+ stats.not_modified_replies60[i] = statPctileSvc(p, 60, PCTILE_NM);
+
+ stats.dns_lookups5[i] = statPctileSvc(p, 5, PCTILE_DNS);
+ stats.dns_lookups60[i] = statPctileSvc(p, 60, PCTILE_DNS);
+
+ stats.icp_queries5[i] = statPctileSvc(p, 5, PCTILE_ICP_QUERY);
+ stats.icp_queries60[i] = statPctileSvc(p, 60, PCTILE_ICP_QUERY);
+ }
+}
+
+void
+DumpServiceTimesStats(Mgr::ServiceTimesActionData& stats, StoreEntry* sentry)
{
- int p;
storeAppendPrintf(sentry, "Service Time Percentiles 5 min 60 min:\n");
- for (p = 5; p < 100; p += 5) {
+ double fct = stats.count > 1 ? stats.count * 1000.0 : 1000.0;
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
storeAppendPrintf(sentry, "\tHTTP Requests (All): %2d%% %8.5f %8.5f\n",
- p,
- statPctileSvc((double) p / 100.0, 5, PCTILE_HTTP) / 1000.0,
- statPctileSvc((double) p / 100.0, 60, PCTILE_HTTP) / 1000.0);
+ (i + 1) * 5,
+ stats.http_requests5[i] / fct,
+ stats.http_requests60[i] / fct);
}
- for (p = 5; p < 100; p += 5) {
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
storeAppendPrintf(sentry, "\tCache Misses: %2d%% %8.5f %8.5f\n",
- p,
- statPctileSvc((double) p / 100.0, 5, PCTILE_MISS) / 1000.0,
- statPctileSvc((double) p / 100.0, 60, PCTILE_MISS) / 1000.0);
+ (i + 1) * 5,
+ stats.cache_misses5[i] / fct,
+ stats.cache_misses60[i] / fct);
}
- for (p = 5; p < 100; p += 5) {
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
storeAppendPrintf(sentry, "\tCache Hits: %2d%% %8.5f %8.5f\n",
- p,
- statPctileSvc((double) p / 100.0, 5, PCTILE_HIT) / 1000.0,
- statPctileSvc((double) p / 100.0, 60, PCTILE_HIT) / 1000.0);
+ (i + 1) * 5,
+ stats.cache_hits5[i] / fct,
+ stats.cache_hits60[i] / fct);
}
- for (p = 5; p < 100; p += 5) {
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
storeAppendPrintf(sentry, "\tNear Hits: %2d%% %8.5f %8.5f\n",
- p,
- statPctileSvc((double) p / 100.0, 5, PCTILE_NH) / 1000.0,
- statPctileSvc((double) p / 100.0, 60, PCTILE_NH) / 1000.0);
+ (i + 1) * 5,
+ stats.near_hits5[i] / fct,
+ stats.near_hits60[i] / fct);
}
- for (p = 5; p < 100; p += 5) {
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
storeAppendPrintf(sentry, "\tNot-Modified Replies: %2d%% %8.5f %8.5f\n",
- p,
- statPctileSvc((double) p / 100.0, 5, PCTILE_NM) / 1000.0,
- statPctileSvc((double) p / 100.0, 60, PCTILE_NM) / 1000.0);
+ (i + 1) * 5,
+ stats.not_modified_replies5[i] / fct,
+ stats.not_modified_replies60[i] / fct);
}
- for (p = 5; p < 100; p += 5) {
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
storeAppendPrintf(sentry, "\tDNS Lookups: %2d%% %8.5f %8.5f\n",
- p,
- statPctileSvc((double) p / 100.0, 5, PCTILE_DNS) / 1000.0,
- statPctileSvc((double) p / 100.0, 60, PCTILE_DNS) / 1000.0);
+ (i + 1) * 5,
+ stats.dns_lookups5[i] / fct,
+ stats.dns_lookups60[i] / fct);
}
- for (p = 5; p < 100; p += 5) {
+ fct = stats.count > 1 ? stats.count * 1000000.0 : 1000000.0;
+ for (int i = 0; i < Mgr::ServiceTimesActionData::seriesSize; ++i) {
storeAppendPrintf(sentry, "\tICP Queries: %2d%% %8.5f %8.5f\n",
- p,
- statPctileSvc((double) p / 100.0, 5, PCTILE_ICP_QUERY) / 1000000.0,
- statPctileSvc((double) p / 100.0, 60, PCTILE_ICP_QUERY) / 1000000.0);
+ (i + 1) * 5,
+ stats.icp_queries5[i] / fct,
+ stats.icp_queries60[i] / fct);
}
}
-#define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
static void
statAvgDump(StoreEntry * sentry, int minutes, int hours)
+{
+ Mgr::IntervalActionData stats;
+ GetAvgStat(stats, minutes, hours);
+ DumpAvgStat(stats, sentry);
+}
+
+#define XAVG(X) (dt ? (double) (f->X - l->X) / dt : 0.0)
+void
+GetAvgStat(Mgr::IntervalActionData& stats, int minutes, int hours)
{
StatCounters *f;
StatCounters *l;
double dt;
double ct;
- double x;
assert(N_COUNT_HIST > 1);
assert(minutes > 0 || hours > 0);
f = &CountHist[0];
dt = tvSubDsec(l->timestamp, f->timestamp);
ct = f->cputime - l->cputime;
+ stats.sample_start_time = l->timestamp;
+ stats.sample_end_time = f->timestamp;
+
+ stats.client_http_requests = XAVG(client_http.requests);
+ stats.client_http_hits = XAVG(client_http.hits);
+ stats.client_http_errors = XAVG(client_http.errors);
+ stats.client_http_kbytes_in = XAVG(client_http.kbytes_in.kb);
+ stats.client_http_kbytes_out = XAVG(client_http.kbytes_out.kb);
+
+ stats.client_http_all_median_svc_time = statHistDeltaMedian(&l->client_http.all_svc_time,
+ &f->client_http.all_svc_time) / 1000.0;
+ stats.client_http_miss_median_svc_time = statHistDeltaMedian(&l->client_http.miss_svc_time,
+ &f->client_http.miss_svc_time) / 1000.0;
+ stats.client_http_nm_median_svc_time = statHistDeltaMedian(&l->client_http.nm_svc_time,
+ &f->client_http.nm_svc_time) / 1000.0;
+ stats.client_http_nh_median_svc_time = statHistDeltaMedian(&l->client_http.nh_svc_time,
+ &f->client_http.nh_svc_time) / 1000.0;
+ stats.client_http_hit_median_svc_time = statHistDeltaMedian(&l->client_http.hit_svc_time,
+ &f->client_http.hit_svc_time) / 1000.0;
+
+ stats.server_all_requests = XAVG(server.all.requests);
+ stats.server_all_errors = XAVG(server.all.errors);
+ stats.server_all_kbytes_in = XAVG(server.all.kbytes_in.kb);
+ stats.server_all_kbytes_out = XAVG(server.all.kbytes_out.kb);
+
+ stats.server_http_requests = XAVG(server.http.requests);
+ stats.server_http_errors = XAVG(server.http.errors);
+ stats.server_http_kbytes_in = XAVG(server.http.kbytes_in.kb);
+ stats.server_http_kbytes_out = XAVG(server.http.kbytes_out.kb);
+
+ stats.server_ftp_requests = XAVG(server.ftp.requests);
+ stats.server_ftp_errors = XAVG(server.ftp.errors);
+ stats.server_ftp_kbytes_in = XAVG(server.ftp.kbytes_in.kb);
+ stats.server_ftp_kbytes_out = XAVG(server.ftp.kbytes_out.kb);
+
+ stats.server_other_requests = XAVG(server.other.requests);
+ stats.server_other_errors = XAVG(server.other.errors);
+ stats.server_other_kbytes_in = XAVG(server.other.kbytes_in.kb);
+ stats.server_other_kbytes_out = XAVG(server.other.kbytes_out.kb);
+
+ stats.icp_pkts_sent = XAVG(icp.pkts_sent);
+ stats.icp_pkts_recv = XAVG(icp.pkts_recv);
+ stats.icp_queries_sent = XAVG(icp.queries_sent);
+ stats.icp_replies_sent = XAVG(icp.replies_sent);
+ stats.icp_queries_recv = XAVG(icp.queries_recv);
+ stats.icp_replies_recv = XAVG(icp.replies_recv);
+ stats.icp_replies_queued = XAVG(icp.replies_queued);
+ stats.icp_query_timeouts = XAVG(icp.query_timeouts);
+ stats.icp_kbytes_sent = XAVG(icp.kbytes_sent.kb);
+ stats.icp_kbytes_recv = XAVG(icp.kbytes_recv.kb);
+ stats.icp_q_kbytes_sent = XAVG(icp.q_kbytes_sent.kb);
+ stats.icp_r_kbytes_sent = XAVG(icp.r_kbytes_sent.kb);
+ stats.icp_q_kbytes_recv = XAVG(icp.q_kbytes_recv.kb);
+ stats.icp_r_kbytes_recv = XAVG(icp.r_kbytes_recv.kb);
+
+ stats.icp_query_median_svc_time = statHistDeltaMedian(&l->icp.query_svc_time,
+ &f->icp.query_svc_time) / 1000000.0;
+ stats.icp_reply_median_svc_time = statHistDeltaMedian(&l->icp.reply_svc_time,
+ &f->icp.reply_svc_time) / 1000000.0;
+ stats.dns_median_svc_time = statHistDeltaMedian(&l->dns.svc_time,
+ &f->dns.svc_time) / 1000.0;
+
+ stats.unlink_requests = XAVG(unlink.requests);
+ stats.page_faults = XAVG(page_faults);
+ stats.select_loops = XAVG(select_loops);
+ stats.select_fds = XAVG(select_fds);
+ stats.average_select_fd_period = f->select_fds > l->select_fds ?
+ (f->select_time - l->select_time) / (f->select_fds - l->select_fds) : 0.0;
+
+ stats.median_select_fds = statHistDeltaMedian(&l->select_fds_hist, &f->select_fds_hist);
+ stats.swap_outs = XAVG(swap.outs);
+ stats.swap_ins = XAVG(swap.ins);
+ stats.swap_files_cleaned = XAVG(swap.files_cleaned);
+ stats.aborted_requests = XAVG(aborted_requests);
+
+ stats.syscalls_disk_opens = XAVG(syscalls.disk.opens);
+ stats.syscalls_disk_closes = XAVG(syscalls.disk.closes);
+ stats.syscalls_disk_reads = XAVG(syscalls.disk.reads);
+ stats.syscalls_disk_writes = XAVG(syscalls.disk.writes);
+ stats.syscalls_disk_seeks = XAVG(syscalls.disk.seeks);
+ stats.syscalls_disk_unlinks = XAVG(syscalls.disk.unlinks);
+ stats.syscalls_sock_accepts = XAVG(syscalls.sock.accepts);
+ stats.syscalls_sock_sockets = XAVG(syscalls.sock.sockets);
+ stats.syscalls_sock_connects = XAVG(syscalls.sock.connects);
+ stats.syscalls_sock_binds = XAVG(syscalls.sock.binds);
+ stats.syscalls_sock_closes = XAVG(syscalls.sock.closes);
+ stats.syscalls_sock_reads = XAVG(syscalls.sock.reads);
+ stats.syscalls_sock_writes = XAVG(syscalls.sock.writes);
+ stats.syscalls_sock_recvfroms = XAVG(syscalls.sock.recvfroms);
+ stats.syscalls_sock_sendtos = XAVG(syscalls.sock.sendtos);
+ stats.syscalls_selects = XAVG(syscalls.selects);
+
+ stats.cpu_time = ct;
+ stats.wall_time = dt;
+}
+
+void
+DumpAvgStat(Mgr::IntervalActionData& stats, StoreEntry* sentry)
+{
storeAppendPrintf(sentry, "sample_start_time = %d.%d (%s)\n",
- (int) l->timestamp.tv_sec,
- (int) l->timestamp.tv_usec,
- mkrfc1123(l->timestamp.tv_sec));
+ (int)stats.sample_start_time.tv_sec,
+ (int)stats.sample_start_time.tv_usec,
+ mkrfc1123(stats.sample_start_time.tv_sec));
storeAppendPrintf(sentry, "sample_end_time = %d.%d (%s)\n",
- (int) f->timestamp.tv_sec,
- (int) f->timestamp.tv_usec,
- mkrfc1123(f->timestamp.tv_sec));
+ (int)stats.sample_end_time.tv_sec,
+ (int)stats.sample_end_time.tv_usec,
+ mkrfc1123(stats.sample_end_time.tv_sec));
storeAppendPrintf(sentry, "client_http.requests = %f/sec\n",
- XAVG(client_http.requests));
+ stats.client_http_requests);
storeAppendPrintf(sentry, "client_http.hits = %f/sec\n",
- XAVG(client_http.hits));
+ stats.client_http_hits);
storeAppendPrintf(sentry, "client_http.errors = %f/sec\n",
- XAVG(client_http.errors));
+ stats.client_http_errors);
storeAppendPrintf(sentry, "client_http.kbytes_in = %f/sec\n",
- XAVG(client_http.kbytes_in.kb));
+ stats.client_http_kbytes_in);
storeAppendPrintf(sentry, "client_http.kbytes_out = %f/sec\n",
- XAVG(client_http.kbytes_out.kb));
+ stats.client_http_kbytes_out);
- x = statHistDeltaMedian(&l->client_http.all_svc_time,
- &f->client_http.all_svc_time);
+ double fct = stats.count > 1 ? stats.count : 1.0;
storeAppendPrintf(sentry, "client_http.all_median_svc_time = %f seconds\n",
- x / 1000.0);
- x = statHistDeltaMedian(&l->client_http.miss_svc_time,
- &f->client_http.miss_svc_time);
+ stats.client_http_all_median_svc_time / fct);
storeAppendPrintf(sentry, "client_http.miss_median_svc_time = %f seconds\n",
- x / 1000.0);
- x = statHistDeltaMedian(&l->client_http.nm_svc_time,
- &f->client_http.nm_svc_time);
+ stats.client_http_miss_median_svc_time / fct);
storeAppendPrintf(sentry, "client_http.nm_median_svc_time = %f seconds\n",
- x / 1000.0);
- x = statHistDeltaMedian(&l->client_http.nh_svc_time,
- &f->client_http.nh_svc_time);
+ stats.client_http_nm_median_svc_time / fct);
storeAppendPrintf(sentry, "client_http.nh_median_svc_time = %f seconds\n",
- x / 1000.0);
- x = statHistDeltaMedian(&l->client_http.hit_svc_time,
- &f->client_http.hit_svc_time);
+ stats.client_http_nh_median_svc_time / fct);
storeAppendPrintf(sentry, "client_http.hit_median_svc_time = %f seconds\n",
- x / 1000.0);
+ stats.client_http_hit_median_svc_time / fct);
storeAppendPrintf(sentry, "server.all.requests = %f/sec\n",
- XAVG(server.all.requests));
+ stats.server_all_requests);
storeAppendPrintf(sentry, "server.all.errors = %f/sec\n",
- XAVG(server.all.errors));
+ stats.server_all_errors);
storeAppendPrintf(sentry, "server.all.kbytes_in = %f/sec\n",
- XAVG(server.all.kbytes_in.kb));
+ stats.server_all_kbytes_in);
storeAppendPrintf(sentry, "server.all.kbytes_out = %f/sec\n",
- XAVG(server.all.kbytes_out.kb));
+ stats.server_all_kbytes_out);
storeAppendPrintf(sentry, "server.http.requests = %f/sec\n",
- XAVG(server.http.requests));
+ stats.server_http_requests);
storeAppendPrintf(sentry, "server.http.errors = %f/sec\n",
- XAVG(server.http.errors));
+ stats.server_http_errors);
storeAppendPrintf(sentry, "server.http.kbytes_in = %f/sec\n",
- XAVG(server.http.kbytes_in.kb));
+ stats.server_http_kbytes_in);
storeAppendPrintf(sentry, "server.http.kbytes_out = %f/sec\n",
- XAVG(server.http.kbytes_out.kb));
+ stats.server_http_kbytes_out);
storeAppendPrintf(sentry, "server.ftp.requests = %f/sec\n",
- XAVG(server.ftp.requests));
+ stats.server_ftp_requests);
storeAppendPrintf(sentry, "server.ftp.errors = %f/sec\n",
- XAVG(server.ftp.errors));
+ stats.server_ftp_errors);
storeAppendPrintf(sentry, "server.ftp.kbytes_in = %f/sec\n",
- XAVG(server.ftp.kbytes_in.kb));
+ stats.server_ftp_kbytes_in);
storeAppendPrintf(sentry, "server.ftp.kbytes_out = %f/sec\n",
- XAVG(server.ftp.kbytes_out.kb));
+ stats.server_ftp_kbytes_out);
storeAppendPrintf(sentry, "server.other.requests = %f/sec\n",
- XAVG(server.other.requests));
+ stats.server_other_requests);
storeAppendPrintf(sentry, "server.other.errors = %f/sec\n",
- XAVG(server.other.errors));
+ stats.server_other_errors);
storeAppendPrintf(sentry, "server.other.kbytes_in = %f/sec\n",
- XAVG(server.other.kbytes_in.kb));
+ stats.server_other_kbytes_in);
storeAppendPrintf(sentry, "server.other.kbytes_out = %f/sec\n",
- XAVG(server.other.kbytes_out.kb));
+ stats.server_other_kbytes_out);
storeAppendPrintf(sentry, "icp.pkts_sent = %f/sec\n",
- XAVG(icp.pkts_sent));
+ stats.icp_pkts_sent);
storeAppendPrintf(sentry, "icp.pkts_recv = %f/sec\n",
- XAVG(icp.pkts_recv));
+ stats.icp_pkts_recv);
storeAppendPrintf(sentry, "icp.queries_sent = %f/sec\n",
- XAVG(icp.queries_sent));
+ stats.icp_queries_sent);
storeAppendPrintf(sentry, "icp.replies_sent = %f/sec\n",
- XAVG(icp.replies_sent));
+ stats.icp_replies_sent);
storeAppendPrintf(sentry, "icp.queries_recv = %f/sec\n",
- XAVG(icp.queries_recv));
+ stats.icp_queries_recv);
storeAppendPrintf(sentry, "icp.replies_recv = %f/sec\n",
- XAVG(icp.replies_recv));
+ stats.icp_replies_recv);
storeAppendPrintf(sentry, "icp.replies_queued = %f/sec\n",
- XAVG(icp.replies_queued));
+ stats.icp_replies_queued);
storeAppendPrintf(sentry, "icp.query_timeouts = %f/sec\n",
- XAVG(icp.query_timeouts));
+ stats.icp_query_timeouts);
storeAppendPrintf(sentry, "icp.kbytes_sent = %f/sec\n",
- XAVG(icp.kbytes_sent.kb));
+ stats.icp_kbytes_sent);
storeAppendPrintf(sentry, "icp.kbytes_recv = %f/sec\n",
- XAVG(icp.kbytes_recv.kb));
+ stats.icp_kbytes_recv);
storeAppendPrintf(sentry, "icp.q_kbytes_sent = %f/sec\n",
- XAVG(icp.q_kbytes_sent.kb));
+ stats.icp_q_kbytes_sent);
storeAppendPrintf(sentry, "icp.r_kbytes_sent = %f/sec\n",
- XAVG(icp.r_kbytes_sent.kb));
+ stats.icp_r_kbytes_sent);
storeAppendPrintf(sentry, "icp.q_kbytes_recv = %f/sec\n",
- XAVG(icp.q_kbytes_recv.kb));
+ stats.icp_q_kbytes_recv);
storeAppendPrintf(sentry, "icp.r_kbytes_recv = %f/sec\n",
- XAVG(icp.r_kbytes_recv.kb));
- x = statHistDeltaMedian(&l->icp.query_svc_time, &f->icp.query_svc_time);
+ stats.icp_r_kbytes_recv);
storeAppendPrintf(sentry, "icp.query_median_svc_time = %f seconds\n",
- x / 1000000.0);
- x = statHistDeltaMedian(&l->icp.reply_svc_time, &f->icp.reply_svc_time);
+ stats.icp_query_median_svc_time / fct);
storeAppendPrintf(sentry, "icp.reply_median_svc_time = %f seconds\n",
- x / 1000000.0);
- x = statHistDeltaMedian(&l->dns.svc_time, &f->dns.svc_time);
+ stats.icp_reply_median_svc_time / fct);
storeAppendPrintf(sentry, "dns.median_svc_time = %f seconds\n",
- x / 1000.0);
+ stats.dns_median_svc_time / fct);
storeAppendPrintf(sentry, "unlink.requests = %f/sec\n",
- XAVG(unlink.requests));
+ stats.unlink_requests);
storeAppendPrintf(sentry, "page_faults = %f/sec\n",
- XAVG(page_faults));
+ stats.page_faults);
storeAppendPrintf(sentry, "select_loops = %f/sec\n",
- XAVG(select_loops));
+ stats.select_loops);
storeAppendPrintf(sentry, "select_fds = %f/sec\n",
- XAVG(select_fds));
+ stats.select_fds);
storeAppendPrintf(sentry, "average_select_fd_period = %f/fd\n",
- f->select_fds > l->select_fds ?
- (f->select_time - l->select_time) / (f->select_fds - l->select_fds)
- : 0.0);
- x = statHistDeltaMedian(&l->select_fds_hist, &f->select_fds_hist);
- storeAppendPrintf(sentry, "median_select_fds = %f\n", x);
+ stats.average_select_fd_period / fct);
+ storeAppendPrintf(sentry, "median_select_fds = %f\n",
+ stats.median_select_fds / fct);
storeAppendPrintf(sentry, "swap.outs = %f/sec\n",
- XAVG(swap.outs));
+ stats.swap_outs);
storeAppendPrintf(sentry, "swap.ins = %f/sec\n",
- XAVG(swap.ins));
+ stats.swap_ins);
storeAppendPrintf(sentry, "swap.files_cleaned = %f/sec\n",
- XAVG(swap.files_cleaned));
+ stats.swap_files_cleaned);
storeAppendPrintf(sentry, "aborted_requests = %f/sec\n",
- XAVG(aborted_requests));
+ stats.aborted_requests);
#if USE_POLL
- storeAppendPrintf(sentry, "syscalls.polls = %f/sec\n", XAVG(syscalls.selects));
+ storeAppendPrintf(sentry, "syscalls.polls = %f/sec\n", stats.syscalls_selects);
#elif defined(USE_SELECT) || defined(USE_SELECT_WIN32)
- storeAppendPrintf(sentry, "syscalls.selects = %f/sec\n", XAVG(syscalls.selects));
+ storeAppendPrintf(sentry, "syscalls.selects = %f/sec\n", stats.syscalls_selects);
#endif
- storeAppendPrintf(sentry, "syscalls.disk.opens = %f/sec\n", XAVG(syscalls.disk.opens));
- storeAppendPrintf(sentry, "syscalls.disk.closes = %f/sec\n", XAVG(syscalls.disk.closes));
- storeAppendPrintf(sentry, "syscalls.disk.reads = %f/sec\n", XAVG(syscalls.disk.reads));
- storeAppendPrintf(sentry, "syscalls.disk.writes = %f/sec\n", XAVG(syscalls.disk.writes));
- storeAppendPrintf(sentry, "syscalls.disk.seeks = %f/sec\n", XAVG(syscalls.disk.seeks));
- storeAppendPrintf(sentry, "syscalls.disk.unlinks = %f/sec\n", XAVG(syscalls.disk.unlinks));
- storeAppendPrintf(sentry, "syscalls.sock.accepts = %f/sec\n", XAVG(syscalls.sock.accepts));
- storeAppendPrintf(sentry, "syscalls.sock.sockets = %f/sec\n", XAVG(syscalls.sock.sockets));
- storeAppendPrintf(sentry, "syscalls.sock.connects = %f/sec\n", XAVG(syscalls.sock.connects));
- storeAppendPrintf(sentry, "syscalls.sock.binds = %f/sec\n", XAVG(syscalls.sock.binds));
- storeAppendPrintf(sentry, "syscalls.sock.closes = %f/sec\n", XAVG(syscalls.sock.closes));
- storeAppendPrintf(sentry, "syscalls.sock.reads = %f/sec\n", XAVG(syscalls.sock.reads));
- storeAppendPrintf(sentry, "syscalls.sock.writes = %f/sec\n", XAVG(syscalls.sock.writes));
- storeAppendPrintf(sentry, "syscalls.sock.recvfroms = %f/sec\n", XAVG(syscalls.sock.recvfroms));
- storeAppendPrintf(sentry, "syscalls.sock.sendtos = %f/sec\n", XAVG(syscalls.sock.sendtos));
-
- storeAppendPrintf(sentry, "cpu_time = %f seconds\n", ct);
- storeAppendPrintf(sentry, "wall_time = %f seconds\n", dt);
- storeAppendPrintf(sentry, "cpu_usage = %f%%\n", Math::doublePercent(ct, dt));
+ storeAppendPrintf(sentry, "syscalls.disk.opens = %f/sec\n", stats.syscalls_disk_opens);
+ storeAppendPrintf(sentry, "syscalls.disk.closes = %f/sec\n", stats.syscalls_disk_closes);
+ storeAppendPrintf(sentry, "syscalls.disk.reads = %f/sec\n", stats.syscalls_disk_reads);
+ storeAppendPrintf(sentry, "syscalls.disk.writes = %f/sec\n", stats.syscalls_disk_writes);
+ storeAppendPrintf(sentry, "syscalls.disk.seeks = %f/sec\n", stats.syscalls_disk_seeks);
+ storeAppendPrintf(sentry, "syscalls.disk.unlinks = %f/sec\n", stats.syscalls_disk_unlinks);
+ storeAppendPrintf(sentry, "syscalls.sock.accepts = %f/sec\n", stats.syscalls_sock_accepts);
+ storeAppendPrintf(sentry, "syscalls.sock.sockets = %f/sec\n", stats.syscalls_sock_sockets);
+ storeAppendPrintf(sentry, "syscalls.sock.connects = %f/sec\n", stats.syscalls_sock_connects);
+ storeAppendPrintf(sentry, "syscalls.sock.binds = %f/sec\n", stats.syscalls_sock_binds);
+ storeAppendPrintf(sentry, "syscalls.sock.closes = %f/sec\n", stats.syscalls_sock_closes);
+ storeAppendPrintf(sentry, "syscalls.sock.reads = %f/sec\n", stats.syscalls_sock_reads);
+ storeAppendPrintf(sentry, "syscalls.sock.writes = %f/sec\n", stats.syscalls_sock_writes);
+ storeAppendPrintf(sentry, "syscalls.sock.recvfroms = %f/sec\n", stats.syscalls_sock_recvfroms);
+ storeAppendPrintf(sentry, "syscalls.sock.sendtos = %f/sec\n", stats.syscalls_sock_sendtos);
+
+ storeAppendPrintf(sentry, "cpu_time = %f seconds\n", stats.cpu_time);
+ storeAppendPrintf(sentry, "wall_time = %f seconds\n", stats.wall_time);
+ storeAppendPrintf(sentry, "cpu_usage = %f%%\n", Math::doublePercent(stats.cpu_time, stats.wall_time));
}
static void
statRegisterWithCacheManager(void)
{
- CacheManager *manager = CacheManager::GetInstance();
- manager->registerAction("info", "General Runtime Information",
- info_get, 0, 1);
- manager->registerAction("service_times", "Service Times (Percentiles)",
- service_times, 0, 1);
- manager->registerAction("filedescriptors", "Process Filedescriptor Allocation",
+ Mgr::RegisterAction("info", "General Runtime Information",
+ &Mgr::InfoAction::Create, 0, 1);
+ Mgr::RegisterAction("service_times", "Service Times (Percentiles)",
+ &Mgr::ServiceTimesAction::Create, 0, 1);
+ Mgr::RegisterAction("filedescriptors", "Process Filedescriptor Allocation",
fde::DumpStats, 0, 1);
- manager->registerAction("objects", "All Cache Objects", stat_objects_get, 0, 0);
- manager->registerAction("vm_objects", "In-Memory and In-Transit Objects",
+ Mgr::RegisterAction("objects", "All Cache Objects", stat_objects_get, 0, 0);
+ Mgr::RegisterAction("vm_objects", "In-Memory and In-Transit Objects",
stat_vmobjects_get, 0, 0);
- manager->registerAction("io", "Server-side network read() size histograms",
- stat_io_get, 0, 1);
- manager->registerAction("counters", "Traffic and Resource Counters",
- statCountersDump, 0, 1);
- manager->registerAction("peer_select", "Peer Selection Algorithms",
+ Mgr::RegisterAction("io", "Server-side network read() size histograms",
+ &Mgr::IoAction::Create, 0, 1);
+ Mgr::RegisterAction("counters", "Traffic and Resource Counters",
+ &Mgr::CountersAction::Create, 0, 1);
+ Mgr::RegisterAction("peer_select", "Peer Selection Algorithms",
statPeerSelect, 0, 1);
- manager->registerAction("digest_stats", "Cache Digest and ICP blob",
+ Mgr::RegisterAction("digest_stats", "Cache Digest and ICP blob",
statDigestBlob, 0, 1);
- manager->registerAction("5min", "5 Minute Average of Counters",
- statAvg5min, 0, 1);
- manager->registerAction("60min", "60 Minute Average of Counters",
- statAvg60min, 0, 1);
- manager->registerAction("utilization", "Cache Utilization",
+ Mgr::RegisterAction("5min", "5 Minute Average of Counters",
+ &Mgr::IntervalAction::Create5min, 0, 1);
+ Mgr::RegisterAction("60min", "60 Minute Average of Counters",
+ &Mgr::IntervalAction::Create60min, 0, 1);
+ Mgr::RegisterAction("utilization", "Cache Utilization",
statUtilization, 0, 1);
- manager->registerAction("histograms", "Full Histogram Counts",
+ Mgr::RegisterAction("histograms", "Full Histogram Counts",
statCountersHistograms, 0, 1);
- manager->registerAction("active_requests",
+ Mgr::RegisterAction("active_requests",
"Client-side Active Requests",
statClientRequests, 0, 1);
- manager->registerAction("username_cache",
+ Mgr::RegisterAction("username_cache",
"Active Cached Usernames",
AuthUser::UsernameCacheStats, 0, 1);
#if DEBUG_OPENFD
- manager->registerAction("openfd_objects", "Objects with Swapout files open",
+ Mgr::RegisterAction("openfd_objects", "Objects with Swapout files open",
statOpenfdObj, 0, 0);
#endif
#if STAT_GRAPHS
- manager->registerAction("graph_variables", "Display cache metrics graphically",
+ Mgr::RegisterAction("graph_variables", "Display cache metrics graphically",
statGraphDump, 0, 1);
#endif
}
static void
statCountersDump(StoreEntry * sentry)
+{
+ Mgr::CountersActionData stats;
+ GetCountersStats(stats);
+ DumpCountersStats(stats, sentry);
+}
+
+void
+GetCountersStats(Mgr::CountersActionData& stats)
{
StatCounters *f = &statCounter;
f->page_faults = rusage_pagefaults(&rusage);
f->cputime = rusage_cputime(&rusage);
+ stats.sample_time = f->timestamp;
+ stats.client_http_requests = f->client_http.requests;
+ stats.client_http_hits = f->client_http.hits;
+ stats.client_http_errors = f->client_http.errors;
+ stats.client_http_kbytes_in = f->client_http.kbytes_in.kb;
+ stats.client_http_kbytes_out = f->client_http.kbytes_out.kb;
+ stats.client_http_hit_kbytes_out = f->client_http.hit_kbytes_out.kb;
+
+ stats.server_all_requests = f->server.all.requests;
+ stats.server_all_errors = f->server.all.errors;
+ stats.server_all_kbytes_in = f->server.all.kbytes_in.kb;
+ stats.server_all_kbytes_out = f->server.all.kbytes_out.kb;
+
+ stats.server_http_requests = f->server.http.requests;
+ stats.server_http_errors = f->server.http.errors;
+ stats.server_http_kbytes_in = f->server.http.kbytes_in.kb;
+ stats.server_http_kbytes_out = f->server.http.kbytes_out.kb;
+
+ stats.server_ftp_requests = f->server.ftp.requests;
+ stats.server_ftp_errors = f->server.ftp.errors;
+ stats.server_ftp_kbytes_in = f->server.ftp.kbytes_in.kb;
+ stats.server_ftp_kbytes_out = f->server.ftp.kbytes_out.kb;
+
+ stats.server_other_requests = f->server.other.requests;
+ stats.server_other_errors = f->server.other.errors;
+ stats.server_other_kbytes_in = f->server.other.kbytes_in.kb;
+ stats.server_other_kbytes_out = f->server.other.kbytes_out.kb;
+
+ stats.icp_pkts_sent = f->icp.pkts_sent;
+ stats.icp_pkts_recv = f->icp.pkts_recv;
+ stats.icp_queries_sent = f->icp.queries_sent;
+ stats.icp_replies_sent = f->icp.replies_sent;
+ stats.icp_queries_recv = f->icp.queries_recv;
+ stats.icp_replies_recv = f->icp.replies_recv;
+ stats.icp_query_timeouts = f->icp.query_timeouts;
+ stats.icp_replies_queued = f->icp.replies_queued;
+ stats.icp_kbytes_sent = f->icp.kbytes_sent.kb;
+ stats.icp_kbytes_recv = f->icp.kbytes_recv.kb;
+ stats.icp_q_kbytes_sent = f->icp.q_kbytes_sent.kb;
+ stats.icp_r_kbytes_sent = f->icp.r_kbytes_sent.kb;
+ stats.icp_q_kbytes_recv = f->icp.q_kbytes_recv.kb;
+ stats.icp_r_kbytes_recv = f->icp.r_kbytes_recv.kb;
+
+#if USE_CACHE_DIGESTS
+
+ stats.icp_times_used = f->icp.times_used;
+ stats.cd_times_used = f->cd.times_used;
+ stats.cd_msgs_sent = f->cd.msgs_sent;
+ stats.cd_msgs_recv = f->cd.msgs_recv;
+ stats.cd_memory = f->cd.memory.kb;
+ stats.cd_local_memory = store_digest ? store_digest->mask_size / 1024 : 0;
+ stats.cd_kbytes_sent = f->cd.kbytes_sent.kb;
+ stats.cd_kbytes_recv = f->cd.kbytes_recv.kb;
+#endif
+
+ stats.unlink_requests = f->unlink.requests;
+ stats.page_faults = f->page_faults;
+ stats.select_loops = f->select_loops;
+ stats.cpu_time = f->cputime;
+ stats.wall_time = tvSubDsec(f->timestamp, current_time);
+ stats.swap_outs = f->swap.outs;
+ stats.swap_ins = f->swap.ins;
+ stats.swap_files_cleaned = f->swap.files_cleaned;
+ stats.aborted_requests = f->aborted_requests;
+}
+
+void
+DumpCountersStats(Mgr::CountersActionData& stats, StoreEntry* sentry)
+{
storeAppendPrintf(sentry, "sample_time = %d.%d (%s)\n",
- (int) f->timestamp.tv_sec,
- (int) f->timestamp.tv_usec,
- mkrfc1123(f->timestamp.tv_sec));
- storeAppendPrintf(sentry, "client_http.requests = %ld\n",
- (long)f->client_http.requests);
- storeAppendPrintf(sentry, "client_http.hits = %ld\n",
- (long)f->client_http.hits);
- storeAppendPrintf(sentry, "client_http.errors = %ld\n",
- (long)f->client_http.errors);
- storeAppendPrintf(sentry, "client_http.kbytes_in = %ld\n",
- (long)f->client_http.kbytes_in.kb);
- storeAppendPrintf(sentry, "client_http.kbytes_out = %ld\n",
- (long)f->client_http.kbytes_out.kb);
- storeAppendPrintf(sentry, "client_http.hit_kbytes_out = %ld\n",
- (long)f->client_http.hit_kbytes_out.kb);
-
- storeAppendPrintf(sentry, "server.all.requests = %ld\n",
- (long)f->server.all.requests);
- storeAppendPrintf(sentry, "server.all.errors = %ld\n",
- (long) f->server.all.errors);
- storeAppendPrintf(sentry, "server.all.kbytes_in = %ld\n",
- (long) f->server.all.kbytes_in.kb);
- storeAppendPrintf(sentry, "server.all.kbytes_out = %ld\n",
- (long) f->server.all.kbytes_out.kb);
-
- storeAppendPrintf(sentry, "server.http.requests = %ld\n",
- (long) f->server.http.requests);
- storeAppendPrintf(sentry, "server.http.errors = %ld\n",
- (long) f->server.http.errors);
- storeAppendPrintf(sentry, "server.http.kbytes_in = %ld\n",
- (long) f->server.http.kbytes_in.kb);
- storeAppendPrintf(sentry, "server.http.kbytes_out = %ld\n",
- (long) f->server.http.kbytes_out.kb);
-
- storeAppendPrintf(sentry, "server.ftp.requests = %ld\n",
- (long) f->server.ftp.requests);
- storeAppendPrintf(sentry, "server.ftp.errors = %ld\n",
- (long) f->server.ftp.errors);
- storeAppendPrintf(sentry, "server.ftp.kbytes_in = %ld\n",
- (long) f->server.ftp.kbytes_in.kb);
- storeAppendPrintf(sentry, "server.ftp.kbytes_out = %ld\n",
- (long) f->server.ftp.kbytes_out.kb);
-
- storeAppendPrintf(sentry, "server.other.requests = %ld\n",
- (long) f->server.other.requests);
- storeAppendPrintf(sentry, "server.other.errors = %ld\n",
- (long) f->server.other.errors);
- storeAppendPrintf(sentry, "server.other.kbytes_in = %ld\n",
- (long) f->server.other.kbytes_in.kb);
- storeAppendPrintf(sentry, "server.other.kbytes_out = %ld\n",
- (long) f->server.other.kbytes_out.kb);
-
- storeAppendPrintf(sentry, "icp.pkts_sent = %ld\n",
- (long)f->icp.pkts_sent);
- storeAppendPrintf(sentry, "icp.pkts_recv = %ld\n",
- (long)f->icp.pkts_recv);
- storeAppendPrintf(sentry, "icp.queries_sent = %ld\n",
- (long)f->icp.queries_sent);
- storeAppendPrintf(sentry, "icp.replies_sent = %ld\n",
- (long)f->icp.replies_sent);
- storeAppendPrintf(sentry, "icp.queries_recv = %ld\n",
- (long)f->icp.queries_recv);
- storeAppendPrintf(sentry, "icp.replies_recv = %ld\n",
- (long)f->icp.replies_recv);
- storeAppendPrintf(sentry, "icp.query_timeouts = %ld\n",
- (long)f->icp.query_timeouts);
- storeAppendPrintf(sentry, "icp.replies_queued = %ld\n",
- (long)f->icp.replies_queued);
- storeAppendPrintf(sentry, "icp.kbytes_sent = %ld\n",
- (long) f->icp.kbytes_sent.kb);
- storeAppendPrintf(sentry, "icp.kbytes_recv = %ld\n",
- (long) f->icp.kbytes_recv.kb);
- storeAppendPrintf(sentry, "icp.q_kbytes_sent = %ld\n",
- (long) f->icp.q_kbytes_sent.kb);
- storeAppendPrintf(sentry, "icp.r_kbytes_sent = %ld\n",
- (long) f->icp.r_kbytes_sent.kb);
- storeAppendPrintf(sentry, "icp.q_kbytes_recv = %ld\n",
- (long) f->icp.q_kbytes_recv.kb);
- storeAppendPrintf(sentry, "icp.r_kbytes_recv = %ld\n",
- (long) f->icp.r_kbytes_recv.kb);
+ (int) stats.sample_time.tv_sec,
+ (int) stats.sample_time.tv_usec,
+ mkrfc1123(stats.sample_time.tv_sec));
+ storeAppendPrintf(sentry, "client_http.requests = %.0f\n",
+ stats.client_http_requests);
+ storeAppendPrintf(sentry, "client_http.hits = %.0f\n",
+ stats.client_http_hits);
+ storeAppendPrintf(sentry, "client_http.errors = %.0f\n",
+ stats.client_http_errors);
+ storeAppendPrintf(sentry, "client_http.kbytes_in = %.0f\n",
+ stats.client_http_kbytes_in);
+ storeAppendPrintf(sentry, "client_http.kbytes_out = %.0f\n",
+ stats.client_http_kbytes_out);
+ storeAppendPrintf(sentry, "client_http.hit_kbytes_out = %.0f\n",
+ stats.client_http_hit_kbytes_out);
+
+ storeAppendPrintf(sentry, "server.all.requests = %.0f\n",
+ stats.server_all_requests);
+ storeAppendPrintf(sentry, "server.all.errors = %.0f\n",
+ stats.server_all_errors);
+ storeAppendPrintf(sentry, "server.all.kbytes_in = %.0f\n",
+ stats.server_all_kbytes_in);
+ storeAppendPrintf(sentry, "server.all.kbytes_out = %.0f\n",
+ stats.server_all_kbytes_out);
+
+ storeAppendPrintf(sentry, "server.http.requests = %.0f\n",
+ stats.server_http_requests);
+ storeAppendPrintf(sentry, "server.http.errors = %.0f\n",
+ stats.server_http_errors);
+ storeAppendPrintf(sentry, "server.http.kbytes_in = %.0f\n",
+ stats.server_http_kbytes_in);
+ storeAppendPrintf(sentry, "server.http.kbytes_out = %.0f\n",
+ stats.server_http_kbytes_out);
+
+ storeAppendPrintf(sentry, "server.ftp.requests = %.0f\n",
+ stats.server_ftp_requests);
+ storeAppendPrintf(sentry, "server.ftp.errors = %.0f\n",
+ stats.server_ftp_errors);
+ storeAppendPrintf(sentry, "server.ftp.kbytes_in = %.0f\n",
+ stats.server_ftp_kbytes_in);
+ storeAppendPrintf(sentry, "server.ftp.kbytes_out = %.0f\n",
+ stats.server_ftp_kbytes_out);
+
+ storeAppendPrintf(sentry, "server.other.requests = %.0f\n",
+ stats.server_other_requests);
+ storeAppendPrintf(sentry, "server.other.errors = %.0f\n",
+ stats.server_other_errors);
+ storeAppendPrintf(sentry, "server.other.kbytes_in = %.0f\n",
+ stats.server_other_kbytes_in);
+ storeAppendPrintf(sentry, "server.other.kbytes_out = %.0f\n",
+ stats.server_other_kbytes_out);
+
+ storeAppendPrintf(sentry, "icp.pkts_sent = %.0f\n",
+ stats.icp_pkts_sent);
+ storeAppendPrintf(sentry, "icp.pkts_recv = %.0f\n",
+ stats.icp_pkts_recv);
+ storeAppendPrintf(sentry, "icp.queries_sent = %.0f\n",
+ stats.icp_queries_sent);
+ storeAppendPrintf(sentry, "icp.replies_sent = %.0f\n",
+ stats.icp_replies_sent);
+ storeAppendPrintf(sentry, "icp.queries_recv = %.0f\n",
+ stats.icp_queries_recv);
+ storeAppendPrintf(sentry, "icp.replies_recv = %.0f\n",
+ stats.icp_replies_recv);
+ storeAppendPrintf(sentry, "icp.query_timeouts = %.0f\n",
+ stats.icp_query_timeouts);
+ storeAppendPrintf(sentry, "icp.replies_queued = %.0f\n",
+ stats.icp_replies_queued);
+ storeAppendPrintf(sentry, "icp.kbytes_sent = %.0f\n",
+ stats.icp_kbytes_sent);
+ storeAppendPrintf(sentry, "icp.kbytes_recv = %.0f\n",
+ stats.icp_kbytes_recv);
+ storeAppendPrintf(sentry, "icp.q_kbytes_sent = %.0f\n",
+ stats.icp_q_kbytes_sent);
+ storeAppendPrintf(sentry, "icp.r_kbytes_sent = %.0f\n",
+ stats.icp_r_kbytes_sent);
+ storeAppendPrintf(sentry, "icp.q_kbytes_recv = %.0f\n",
+ stats.icp_q_kbytes_recv);
+ storeAppendPrintf(sentry, "icp.r_kbytes_recv = %.0f\n",
+ stats.icp_r_kbytes_recv);
#if USE_CACHE_DIGESTS
- storeAppendPrintf(sentry, "icp.times_used = %ld\n",
- (long)f->icp.times_used);
- storeAppendPrintf(sentry, "cd.times_used = %ld\n",
- (long)f->cd.times_used);
- storeAppendPrintf(sentry, "cd.msgs_sent = %ld\n",
- (long)f->cd.msgs_sent);
- storeAppendPrintf(sentry, "cd.msgs_recv = %ld\n",
- (long)f->cd.msgs_recv);
- storeAppendPrintf(sentry, "cd.memory = %ld\n",
- (long) f->cd.memory.kb);
- storeAppendPrintf(sentry, "cd.local_memory = %ld\n",
- (long) (store_digest ? store_digest->mask_size / 1024 : 0));
- storeAppendPrintf(sentry, "cd.kbytes_sent = %ld\n",
- (long) f->cd.kbytes_sent.kb);
- storeAppendPrintf(sentry, "cd.kbytes_recv = %ld\n",
- (long) f->cd.kbytes_recv.kb);
+ storeAppendPrintf(sentry, "icp.times_used = %.0f\n",
+ stats.icp_times_used);
+ storeAppendPrintf(sentry, "cd.times_used = %.0f\n",
+ stats.cd_times_used);
+ storeAppendPrintf(sentry, "cd.msgs_sent = %.0f\n",
+ stats.cd_msgs_sent);
+ storeAppendPrintf(sentry, "cd.msgs_recv = %.0f\n",
+ stats.cd_msgs_recv);
+ storeAppendPrintf(sentry, "cd.memory = %.0f\n",
+ stats.cd_memory);
+ storeAppendPrintf(sentry, "cd.local_memory = %.0f\n",
+ stats.cd_local_memory);
+ storeAppendPrintf(sentry, "cd.kbytes_sent = %.0f\n",
+ stats.cd_kbytes_sent);
+ storeAppendPrintf(sentry, "cd.kbytes_recv = %.0f\n",
+ stats.cd_kbytes_recv);
#endif
- storeAppendPrintf(sentry, "unlink.requests = %ld\n",
- (long)f->unlink.requests);
- storeAppendPrintf(sentry, "page_faults = %ld\n",
- (long)f->page_faults);
- storeAppendPrintf(sentry, "select_loops = %ld\n",
- (long)f->select_loops);
+ storeAppendPrintf(sentry, "unlink.requests = %.0f\n",
+ stats.unlink_requests);
+ storeAppendPrintf(sentry, "page_faults = %.0f\n",
+ stats.page_faults);
+ storeAppendPrintf(sentry, "select_loops = %.0f\n",
+ stats.select_loops);
storeAppendPrintf(sentry, "cpu_time = %f\n",
- f->cputime);
+ stats.cpu_time);
storeAppendPrintf(sentry, "wall_time = %f\n",
- tvSubDsec(f->timestamp, current_time));
- storeAppendPrintf(sentry, "swap.outs = %ld\n",
- (long)f->swap.outs);
- storeAppendPrintf(sentry, "swap.ins = %ld\n",
- (long)f->swap.ins);
- storeAppendPrintf(sentry, "swap.files_cleaned = %ld\n",
- (long)f->swap.files_cleaned);
- storeAppendPrintf(sentry, "aborted_requests = %ld\n",
- (long)f->aborted_requests);
+ stats.wall_time);
+ storeAppendPrintf(sentry, "swap.outs = %.0f\n",
+ stats.swap_outs);
+ storeAppendPrintf(sentry, "swap.ins = %.0f\n",
+ stats.swap_ins);
+ storeAppendPrintf(sentry, "swap.files_cleaned = %.0f\n",
+ stats.swap_files_cleaned);
+ storeAppendPrintf(sentry, "aborted_requests = %.0f\n",
+ stats.aborted_requests);
}
void
storeDigestReport(sentry);
}
-static void
-statAvg5min(StoreEntry * e)
-{
- statAvgDump(e, 5, 0);
-}
-
-static void
-statAvg60min(StoreEntry * e)
-{
- statAvgDump(e, 60, 0);
-}
-
static double
statPctileSvc(double pctile, int interval, int which)
{
#include "event.h"
#include "fde.h"
#include "Store.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "StoreClient.h"
#include "stmem.h"
#include "HttpReply.h"
#include "Stack.h"
#include "SquidTime.h"
#include "swap_log_op.h"
+#include "mgr/StoreIoAction.h"
static STMCB storeWriteComplete;
"SWAPOUT_DONE"
};
-extern OBJH storeIOStats;
-
/*
* This defines an repl type
static void
storeRegisterWithCacheManager(void)
{
- CacheManager *manager=CacheManager::GetInstance();
- manager->registerAction("storedir", "Store Directory Stats", Store::Stats, 0, 1);
- manager->registerAction("store_io", "Store IO Interface Stats", storeIOStats, 0, 1);
- manager->registerAction("store_check_cachable_stats", "storeCheckCachable() Stats",
+ Mgr::RegisterAction("storedir", "Store Directory Stats", Store::Stats, 0, 1);
+ Mgr::RegisterAction("store_io", "Store IO Interface Stats", &Mgr::StoreIoAction::Create, 0, 1);
+ Mgr::RegisterAction("store_check_cachable_stats", "storeCheckCachable() Stats",
storeCheckCachableStats, 0, 1);
}
#include "squid.h"
#include "event.h"
-#include "CacheManager.h"
+#include "mgr/Registration.h"
#if USE_CACHE_DIGESTS
#include "Store.h"
static void
storeDigestRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("store_digest", "Store Digest", storeDigestReport, 0, 1);
+ Mgr::RegisterAction("store_digest", "Store Digest", storeDigestReport, 0, 1);
}
/*
#include "MemObject.h"
#include "SwapDir.h"
-static struct {
-
- struct {
- int calls;
- int select_fail;
- int create_fail;
- int success;
- } create;
-} store_io_stats;
-
-OBJH storeIOStats;
+StoreIoStats store_io_stats;
/*
* submit a request to create a cache object for writing.
{
sio->write(buf,size,offset,free_func);
}
-
-/*
- * Make this non-static so we can register
- * it from storeInit();
- */
-void
-storeIOStats(StoreEntry * sentry)
-{
- storeAppendPrintf(sentry, "Store IO Interface Stats\n");
- storeAppendPrintf(sentry, "create.calls %d\n", store_io_stats.create.calls);
- storeAppendPrintf(sentry, "create.select_fail %d\n", store_io_stats.create.select_fail);
- storeAppendPrintf(sentry, "create.create_fail %d\n", store_io_stats.create.create_fail);
- storeAppendPrintf(sentry, "create.success %d\n", store_io_stats.create.success);
-}
*/
#include "squid.h"
-#include "CacheManager.h"
#include "HttpReply.h"
#include "log/File.h"
#include "MemObject.h"
+#include "mgr/Registration.h"
#include "Store.h"
#include "SquidTime.h"
static void
storeLogRegisterWithCacheManager(void)
{
- CacheManager::GetInstance()->
- registerAction("store_log_tags", "Histogram of store.log tags",
+ Mgr::RegisterAction("store_log_tags", "Histogram of store.log tags",
storeLogTagsHist, 0, 1);
}
int n_peers;
};
-
struct _iostats {
+ enum { histSize = 16 };
+
struct {
int reads;
int reads_deferred;
- int read_hist[16];
+ int read_hist[histSize];
int writes;
- int write_hist[16];
+ int write_hist[histSize];
}
Http, Ftp, Gopher;
--- /dev/null
+#include "config.h"
+#include "ipc/Port.h"
+
+const char Ipc::coordinatorAddr[] = "";
--- /dev/null
+#include "config.h"
+#include "fatal.h"
+#include "ipc/TypedMsgHdr.h"
+
+Ipc::TypedMsgHdr::TypedMsgHdr()
+{
+ fatal("Not implemented");
+}
+
+void
+Ipc::TypedMsgHdr::getFixed(void *raw, size_t size) const
+{
+ fatal("Not implemented");
+}
+
+void
+Ipc::TypedMsgHdr::putFixed(const void *raw, size_t size)
+{
+ fatal("Not implemented");
+}
+
+void
+Ipc::TypedMsgHdr::getString(String &size) const
+{
+ fatal("Not implemented");
+}
+
+void
+Ipc::TypedMsgHdr::putString(const String & size)
+{
+ fatal("Not implemented");
+}
+
+void
+Ipc::TypedMsgHdr::checkType(int destType) const
+{
+ fatal("Not implemented");
+}
+
+void
+Ipc::TypedMsgHdr::setType(int aType)
+{
+ fatal("Not implemented");
+}
--- /dev/null
+#include "config.h"
+#include "ipc/UdsOp.h"
+
+void Ipc::SendMessage(const String& toAddress, const TypedMsgHdr& message)
+{
+ fatal ("Not implemented");
+}
*/
#include "CacheManager.h"
+#include "mgr/Registration.h"
#include "squid.h"
-static CacheManager *cm=0;
-
-CacheManager::CacheManager()
-{
-}
-
-void
-CacheManager::registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic)
+Mgr::Action::Pointer
+CacheManager::createNamedAction(char const* action)
{
- return;
+ fatal ("Not implemented");
+ return NULL;
}
void
-CacheManager::registerAction(CacheManagerAction *anAction)
+CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry)
{
return;
}
-CacheManagerAction *
-CacheManager::findAction(char const * action)
+CacheManager*
+CacheManager::GetInstance(void)
{
- return 0;
+ static CacheManager *instance = 0;
+ if (!instance)
+ instance = new CacheManager();
+ return instance;
}
void
-CacheManager::Start(int fd, HttpRequest * request, StoreEntry * entry)
+Mgr::RegisterAction(char const*, char const*, OBJH, int, int)
{
- return;
}
-CacheManager*
-CacheManager::GetInstance(void)
+void
+Mgr::RegisterAction(char const * action, char const * desc,
+ Mgr::ClassActionCreationHandler *handler,
+ int pw_req_flag, int atomic)
{
- if (!cm)
- cm=new CacheManager();
- return cm;
}
-
{
fatal ("Not implemented");
}
+
+int
+commSetTimeout(int fd, int timeout, AsyncCall::Pointer& callback)
+{
+ fatal ("Not implemented");
+ return -1;
+}
+
+int
+comm_open_uds(int sock_type, int proto, struct sockaddr_un* addr, int flags)
+{
+ fatal ("Not implemented");
+ return -1;
+}
+
+void
+comm_write(int fd, const char *buf, int size, AsyncCall::Pointer &callback, FREE * free_func)
+{
+ fatal ("Not implemented");
+}
+
+ConnectionDetail::ConnectionDetail() : me(), peer()
+{
+ fatal ("Not implemented");
+}
#include "squid.h"
#include "Store.h"
+StoreIoStats store_io_stats;
+
void
StoreEntry::swapOutFileClose()
{
fatal ("Not implemented");
}
-
-void
-storeIOStats(StoreEntry *)
-{
- fatal ("Not implemented");
-}
-
-
#include "StoreMeta.h"
char *
*/
#include "config.h"
+#include "protos.h"
int
percent(int a, int b)
fprintf(stderr, "Not implemented");
exit(1);
}
+
+void*
+xmemset(void* dst, int val, size_t sz)
+{
+ assert(dst);
+ return memset(dst, val, sz);
+}
#include "squid.h"
#include <cppunit/TestAssert.h>
+#include "mgr/Action.h"
#include "Mem.h"
#include "testCacheManager.h"
testCacheManager::testRegister()
{
CacheManager *manager=CacheManager::GetInstance();
+ CPPUNIT_ASSERT(manager != NULL);
- manager->registerAction("sample", "my sample", &dummy_action, false, false);
- CacheManagerAction *anAction = manager->findAction("sample");
+ manager->registerProfile("sample", "my sample", &dummy_action, false, false);
+ Mgr::Action::Pointer action = manager->createNamedAction("sample");
+ CPPUNIT_ASSERT(action != NULL);
- CPPUNIT_ASSERT_EQUAL(0, (int)anAction->flags.pw_req);
- CPPUNIT_ASSERT_EQUAL(0, (int)anAction->flags.atomic);
- CPPUNIT_ASSERT_EQUAL(String("sample"), String(anAction->action));
+ const Mgr::ActionProfile::Pointer profile = action->command().profile;
+ CPPUNIT_ASSERT(profile != NULL);
+ CPPUNIT_ASSERT(profile->creator != NULL);
+ CPPUNIT_ASSERT_EQUAL(false, profile->isPwReq);
+ CPPUNIT_ASSERT_EQUAL(false, profile->isAtomic);
+ CPPUNIT_ASSERT_EQUAL(String("sample"), String(action->name()));
StoreEntry *sentry=new StoreEntry();
sentry->flags=0x25; //arbitrary test value
- anAction->run(sentry);
+ action->run(sentry, false);
CPPUNIT_ASSERT_EQUAL(1,(int)sentry->flags);
}
#include "StoreMetaUnpacker.h"
#include "Store.h"
#include "Generic.h"
+#include "mgr/Registration.h"
+
#undef malloc
#undef free
va_end(args);
}
-#include "CacheManager.h"
-CacheManager*
-CacheManager::GetInstance()
-{
- assert(false);
- return NULL;
-}
-
void
-CacheManager::registerAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic) {}
+Mgr::RegisterAction(char const * action, char const * desc, OBJH * handler, int pw_req_flag, int atomic) {}
/* MinGW needs also a stub of death() */
void