Negative worker count?!?

Jules Agee julesa at pcf.com
Wed Feb 7 19:17:07 EST 2007


> 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 at pcf.com      x284
-------------- next part --------------
--- 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 =3D 0;
+        int s =3D sizeof(*msg);
+
+        while (s > 0) {
+            do
+                r =3D read(fd, msg + off, s);
+            while ((r =3D=3D -1) && (errno =3D=3D EINTR));
+            if (r <=3D 0) break;
+            s -=3D r;
+            off +=3D r;
+        }
+        if ( ((r =3D=3D 0) && (off =3D=3D 0)) ||
+             ((r =3D=3D -1) && (errno =3D=3D EAGAIN)) )
+            return 1;
+        if (r =3D=3D -1) return -1;
+        if (s !=3D 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 =3D &Services[si];;
@@ -2204,18 +2235,24 @@
             int x =3D Services[i].stat[0];
             int y =3D Services[i].socket;
             int j;
 =

             if (FD_ISSET(x, &rfds)) {
-                r =3D read(x, &msg, sizeof(msg));
-                if (r !=3D sizeof(msg)) {
-                    syslog(LOG_ERR, "got incorrectly sized response from =

-child: %x", i);
+                 while ((r =3D read_msg(x, &msg)) =3D=3D 0)
+                    process_msg(&Services[i], &msg);
+
+                if (r =3D=3D 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 */


More information about the Info-cyrus mailing list