> 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