]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Added "disker" processes to be responsible for individual cache_dir I/O.
authorAlex Rousskov <rousskov@measurement-factory.com>
Sun, 30 Jan 2011 23:16:22 +0000 (16:16 -0700)
committerAlex Rousskov <rousskov@measurement-factory.com>
Sun, 30 Jan 2011 23:16:22 +0000 (16:16 -0700)
Determine kid process role based on the process name rather than kid ID.
This allows the process to perform role-specific actions before (or while)
squid.conf is parsed.

src/cache_cf.cc
src/fs/rock/RockRebuild.cc
src/fs/rock/RockSwapDir.cc
src/ipc/Kid.cc
src/ipc/Kid.h
src/ipc/Kids.cc
src/ipc/Kids.h
src/main.cc
src/protos.h
src/tools.cc

index 4601feb5366a3d724d8a46d5ae0edf4c782dc426..1ec303cba92d29e804b15d972c1302ed8c922e04 100644 (file)
@@ -1884,16 +1884,8 @@ find_fstype(char *type)
 static void
 parse_cachedir(SquidConfig::_cacheSwap * swap)
 {
-    // The workers option must preceed cache_dir for the IamWorkerProcess check
-    // below to work. TODO: Redo IamWorkerProcess to work w/o Config and remove
-    if (KidIdentifier > 1 && Config.workers == 1) {
-        debugs(3, DBG_CRITICAL,
-               "FATAL: cache_dir found before the workers option. Reorder.");
-        self_destruct();
-    }
-
-    // Among all processes, only workers may need and can handle cache_dir.
-    if (!IamWorkerProcess())
+    // coordinator does not need to handle cache_dir.
+    if (IamCoordinatorProcess())
         return;
 
     char *type_str;
index 3074605446e4b8dac6057daf6da6544db4c0b883..624fe4346564fb38c08406d567f8144f442fc27f 100644 (file)
@@ -34,7 +34,8 @@ Rock::Rebuild::~Rebuild()
 /// prepares and initiates entry loading sequence
 void
 Rock::Rebuild::start() {
-    debugs(47,2, HERE << sd->index);
+    debugs(47, DBG_IMPORTANT, "Loading cache_dir #" << sd->index <<
+           " from " << sd->filePath);
 
     fd = file_open(sd->filePath, O_RDONLY | O_BINARY);
     if (fd < 0)
index 7bad86b11a3a687024746fcbf764ac9883cda9d6..207cd7e6fe992b9d94d23b045ac81aea99cb0f52 100644 (file)
@@ -212,6 +212,10 @@ Rock::SwapDir::validateOptions()
 
 void
 Rock::SwapDir::rebuild() {
+    // in SMP mode, only the disker is responsible for populating the map
+    if (UsingSmp() && !IamDiskProcess())
+        return;
+
     ++StoreController::store_dirs_rebuilding;
     Rebuild *r = new Rebuild(this);
     r->start(); // will delete self when done
index 1768d0e7afd06076c28f29cc1eeb8ec62c596400..e737692bc80aed681286afa8a5dfbf9ce2673d0f 100644 (file)
@@ -12,6 +12,8 @@
 #include <sys/wait.h>
 #endif
 
+int TheProcessKind = pkOther;
+
 Kid::Kid():
         badFailures(0),
         pid(-1),
index fbdf189dd373209d523b35671d85f28ed9ac79ad..e1e283c37e920cb4c6030e8611871cb61b061b13 100644 (file)
@@ -82,4 +82,19 @@ private:
     status_type status; ///< exit status of a stopped kid
 };
 
+
+// TODO: processes may not be kids; is there a better place to put this?
+
+/// process kinds 
+typedef enum {
+    pkOther  = 0, ///< we do not know or do not care
+    pkCoordinator = 1, ///< manages all other kids
+    pkWorker = 2, ///< general-purpose worker bee
+    pkDisker = 4, ///< cache_dir manager
+} ProcessKind;
+
+/// ProcessKind for the current process
+extern int TheProcessKind;
+
+
 #endif /* SQUID_IPC_KID_H */
index 7e15ceb7d6e6a2ca320c679273d7abe16e6fcd9d..7e310a37126f1f3ddd59bfdbeef67a8d196dd29c 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "config.h"
 #include "ipc/Kids.h"
+#include "protos.h"
 
 Kids TheKids;
 KidName TheKidName;
@@ -16,26 +17,31 @@ Kids::Kids()
 }
 
 /// maintain n kids
-void Kids::init(size_t n)
+void Kids::init()
 {
-    assert(n > 0);
-
     if (storage.size() > 0)
         storage.clean();
 
-    storage.reserve(n);
+    storage.reserve(NumberOfKids());
 
     char kid_name[32];
 
-    // add Kid records for all n main strands
-    for (size_t i = 1; i <= n; ++i) {
-        snprintf(kid_name, sizeof(kid_name), "(squid-%d)", (int)i);
+    // add Kid records for all workers
+    for (int i = 0; i < Config.workers; ++i) {
+        snprintf(kid_name, sizeof(kid_name), "(squid-%d)", (int)(storage.size()+1));
+        storage.push_back(Kid(kid_name));
+    }
+
+    // add Kid records for all disk processes
+    // (XXX: some cache_dirs do not need this)
+    for (int i = 0; i < Config.cacheSwap.n_configured; ++i) {
+        snprintf(kid_name, sizeof(kid_name), "(squid-disk-%d)", (int)(storage.size()+1));
         storage.push_back(Kid(kid_name));
     }
 
     // if coordination is needed, add a Kid record for Coordinator
-    if (n > 1) {
-        snprintf(kid_name, sizeof(kid_name), "(squid-coord-%d)", (int)(n + 1));
+    if (storage.size() > 1) {
+        snprintf(kid_name, sizeof(kid_name), "(squid-coord-%d)", (int)(storage.size()+1));
         storage.push_back(Kid(kid_name));
     }
 }
index bfa3735a284d1a1ad8b3164821cb1f036b960973..0a2e348c715e35f81576c60cc3b85339e870501f 100644 (file)
@@ -21,8 +21,8 @@ private:
     Kids& operator= (const Kids&); ///< not implemented
 
 public:
-    /// maintain n kids
-    void init(size_t n);
+    /// initialize all kid records based on Config
+    void init();
 
     /// returns kid by pid
     Kid* find(pid_t pid);
index 597f03d57940417a4a6188f77673b4a4bb92fc56..725515d18236eff050fd8d916aa2b41b7eb1cc49 100644 (file)
@@ -646,8 +646,8 @@ serverConnectionsOpen(void)
         wccp2ConnectionOpen();
 #endif
     }
-    // Coordinator does not start proxying services
-    if (!IamCoordinatorProcess()) {
+    // start various proxying services if we are responsible for them
+    if (IamWorkerProcess()) {
         clientOpenListenSockets();
         icpConnectionsOpen();
 #if USE_HTCP
@@ -687,7 +687,7 @@ serverConnectionsClose(void)
         wccp2ConnectionClose();
 #endif
     }
-    if (!IamCoordinatorProcess()) {
+    if (IamWorkerProcess()) {
         clientHttpConnectionsClose();
         icpConnectionShutdown();
 #if USE_HTCP
@@ -977,6 +977,9 @@ mainInitialize(void)
 #endif
 
     debugs(1, 1, "Process ID " << getpid());
+
+    debugs(1, 1, "Process Roles:" << ProcessRoles());
+
     setSystemLimits();
     debugs(1, 1, "With " << Squid_MaxFD << " file descriptors available");
 
@@ -1228,6 +1231,16 @@ ConfigureCurrentKid(const char *processName)
             const size_t nameLen = idStart - (processName + 1);
             assert(nameLen < sizeof(TheKidName));
             xstrncpy(TheKidName, processName + 1, nameLen + 1);
+            if (!strcmp(TheKidName, "squid-coord"))
+                TheProcessKind = pkCoordinator;
+            else
+            if (!strcmp(TheKidName, "squid"))
+                TheProcessKind = pkWorker;
+            else
+            if (!strcmp(TheKidName, "squid-disk"))
+                TheProcessKind = pkDisker;
+            else
+                TheProcessKind = pkOther; // including coordinator
         }
     } else {
         xstrncpy(TheKidName, APP_SHORTNAME, sizeof(TheKidName));
@@ -1470,7 +1483,7 @@ SquidMain(int argc, char **argv)
 
     if (IamCoordinatorProcess())
         AsyncJob::Start(Ipc::Coordinator::Instance());
-    else if (UsingSmp() && IamWorkerProcess())
+    else if (UsingSmp() && (IamWorkerProcess() || IamDiskProcess()))
         AsyncJob::Start(new Ipc::Strand);
 
     /* at this point we are finished the synchronous startup. */
@@ -1680,7 +1693,9 @@ watch_child(char *argv[])
                Config.workers);
         // but we keep going in hope that user knows best
     }
-    TheKids.init(Config.workers);
+    TheKids.init();
+
+syslog(LOG_NOTICE, "XXX: will start %d kids", TheKids.count());
 
     // keep [re]starting kids until it is time to quit
     for (;;) {
@@ -1702,7 +1717,8 @@ watch_child(char *argv[])
             }
 
             kid.start(pid);
-            syslog(LOG_NOTICE, "Squid Parent: child process %d started", pid);
+            syslog(LOG_NOTICE, "Squid Parent: %s process %d started",
+                kid.name().termedBuf(), pid);
         }
 
         /* parent */
@@ -1726,14 +1742,17 @@ watch_child(char *argv[])
                 kid->stop(status);
                 if (kid->calledExit()) {
                     syslog(LOG_NOTICE,
-                           "Squid Parent: child process %d exited with status %d",
+                           "Squid Parent: %s process %d exited with status %d",
+                           kid->name().termedBuf(),
                            kid->getPid(), kid->exitStatus());
                 } else if (kid->signaled()) {
                     syslog(LOG_NOTICE,
-                           "Squid Parent: child process %d exited due to signal %d with status %d",
+                           "Squid Parent: %s process %d exited due to signal %d with status %d",
+                           kid->name().termedBuf(),
                            kid->getPid(), kid->termSignal(), kid->exitStatus());
                 } else {
-                    syslog(LOG_NOTICE, "Squid Parent: child process %d exited", kid->getPid());
+                    syslog(LOG_NOTICE, "Squid Parent: %s process %d exited",
+                           kid->name().termedBuf(), kid->getPid());
                 }
             } else {
                 syslog(LOG_NOTICE, "Squid Parent: unknown child process %d exited", pid);
index 57ba76a433c5dfe5750b6cd81b711a36b2ea9b41..cb534ad14798064d72d8bee631a9220eff70f79c 100644 (file)
@@ -588,12 +588,16 @@ SQUIDCEXTERN bool IamPrimaryProcess();
 SQUIDCEXTERN bool IamCoordinatorProcess();
 /// whether the current process handles HTTP transactions and such
 SQUIDCEXTERN bool IamWorkerProcess();
+/// whether the current process is dedicated to managing a cache_dir
+bool IamDiskProcess();
 /// Whether we are running in daemon mode
 SQUIDCEXTERN bool InDaemonMode(); // try using specific Iam*() checks above first
 /// Whether there should be more than one worker process running
 SQUIDCEXTERN bool UsingSmp(); // try using specific Iam*() checks above first
 /// number of Kid processes as defined in src/ipc/Kid.h
 SQUIDCEXTERN int NumberOfKids();
+/// a string describing this process roles such as worker or coordinator
+String ProcessRoles();
 SQUIDCEXTERN int DebugSignal;
 
 /* AYJ debugs function to show locations being reset with memset() */
index 18729c9bdf135eeb85310fc099403f4c5add33b2..0cfe32a1ed6f57edaa104330e92a7a26eb06dc9f 100644 (file)
@@ -819,7 +819,13 @@ IamWorkerProcess()
     if (opt_no_daemon || Config.workers == 0)
         return true;
 
-    return 0 < KidIdentifier && KidIdentifier <= Config.workers;
+    return TheProcessKind == pkWorker;
+}
+
+bool
+IamDiskProcess()
+{
+    return TheProcessKind == pkDisker;
 }
 
 bool
@@ -831,13 +837,13 @@ InDaemonMode()
 bool
 UsingSmp()
 {
-    return !opt_no_daemon && Config.workers > 1;
+    return InDaemonMode() && NumberOfKids() > 1;
 }
 
 bool
 IamCoordinatorProcess()
 {
-    return UsingSmp() && KidIdentifier == Config.workers + 1;
+    return TheProcessKind == pkCoordinator;
 }
 
 bool
@@ -863,11 +869,28 @@ NumberOfKids()
     if (!InDaemonMode())
         return 0;
 
-    // workers + the coordinator process
-    if (UsingSmp())
-        return Config.workers + 1;
+    // XXX: detect and abort when called before workers/cache_dirs are parsed
 
-    return Config.workers;
+    // XXX: this is not always the case as there are other cache_dir types
+    const int rockDirs = Config.cacheSwap.n_configured;
+
+    const bool needCoord = Config.workers > 1 || rockDirs > 0;
+    return (needCoord ? 1 : 0) + Config.workers + rockDirs;
+}
+
+String
+ProcessRoles()
+{
+    String roles = "";
+    if (IamMasterProcess())
+        roles.append(" master");
+    if (IamCoordinatorProcess())
+        roles.append(" coordinator");
+    if (IamWorkerProcess())
+        roles.append(" worker");
+    if (IamDiskProcess())
+        roles.append(" disker");
+    return roles;
 }
 
 void