Re: Negative worker count?!?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Henrique de Moraes Holschuh wrote:
>
>> On Thu, 01 Feb 2007, Earl Shannon wrote:
>>
>>> Jan 31 17:24:03 uni24map master[3673]: lmtp has -2 workers?!?
>>> Jan 31 17:24:03 uni24map master[3673]: lmtp has -1 workers?!?
>>
>> Which Cyrus version, and if using a prepackaged one, exactly which
>> one?

Don't know if this issue has been resolved already, but I had the same
problem a few years back, and worked with Henrique to fix it. The
attached patch is what we came up with, and resolved the problem for me.

The patched master processes all messages from all workers every time it
loops, rather than only processing one worker message per service per loop.

The patch is a diff against  $Id: master.c,v 1.104 2006/11/30 17:11:23
murch Exp $

-Jules

-- 
Jules Agee
System Administrator
Pacific Coast Feather Co.
julesa@xxxxxxx      x284
--- master1.c	2007-02-07 15:57:23.000000000 -0800
+++ master2.c	2007-02-07 15:56:15.000000000 -0800
@@ -1148,10 +1148,41 @@
     if (sigaction(SIGCHLD, &action, NULL) < 0) {
         fatal("unable to install signal handler for SIGCHLD: %m", 1);
     }
 }
 
+/*
+ * Receives a message from a service.
+ *
+ * Returns zero if all goes well
+ * 1 if no msg available
+ * 2 if bad message received (incorrectly sized)
+ * -1 on error (errno set)
+ */
+int read_msg(int fd, struct notify_message *msg)
+{
+        ssize_t r;
+        size_t off = 0;
+        int s = sizeof(*msg);
+
+        while (s > 0) {
+            do
+                r = read(fd, msg + off, s);
+            while ((r == -1) && (errno == EINTR));
+            if (r <= 0) break;
+            s -= r;
+            off += r;
+        }
+        if ( ((r == 0) && (off == 0)) ||
+             ((r == -1) && (errno == EAGAIN)) )
+            return 1;
+        if (r == -1) return -1;
+        if (s != 0) return 2;
+        return 0;
+}
+
+
 void process_msg(const int si, struct notify_message *msg) 
 {
     struct centry *c;
     /* si must NOT point to an invalid service */
     struct service * const s = &Services[si];;
@@ -2204,18 +2235,24 @@
             int x = Services[i].stat[0];
             int y = Services[i].socket;
             int j;
 
             if (FD_ISSET(x, &rfds)) {
-                r = read(x, &msg, sizeof(msg));
-                if (r != sizeof(msg)) {
-                    syslog(LOG_ERR, "got incorrectly sized response from 
-child: %x", i);
+                 while ((r = read_msg(x, &msg)) == 0)
+                    process_msg(&Services[i], &msg);
+
+                if (r == 2) {
+                    syslog(LOG_ERR,
+                        "got incorrectly sized response from child: %x", i);
                     continue;
                 }
-                
-                process_msg(i, &msg);
+                if (r < 0) {
+                    syslog(LOG_ERR,
+                        "error while receiving message from child %x: %m", i);
+                    continue;
+                }
+
             }
 
             if (Services[i].exec &&
                 Services[i].nactive < Services[i].max_workers) {
                 /* bring us up to desired_workers */
----
Cyrus Home Page: http://cyrusimap.web.cmu.edu/
Cyrus Wiki/FAQ: http://cyrusimap.web.cmu.edu/twiki
List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html

[Index of Archives]     [Cyrus SASL]     [Squirrel Mail]     [Asterisk PBX]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [KDE]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux