diff -Naur /var/tmp/cyrus/134/imap/imapd.c 134/imap/imapd.c --- /var/tmp/cyrus/134/imap/imapd.c 2009-03-31 12:01:01.000000000 -0400 +++ 134/imap/imapd.c 2009-03-31 11:42:13.000000000 -0400 @@ -471,7 +471,9 @@ config_mupdate_server) { /* It is not currently active, make sure we have the most recent * copy of the database */ - kick_mupdate(); + if (kick_mupdate(0) != 0) { + return IMAP_IOERROR; + } r = mboxlist_detail(name, &mbtype, pathp, mpathp, &remote, &acl, tid); } @@ -1061,7 +1063,7 @@ /* if we need to force a kick, do so */ if (referral_kick) { - kick_mupdate(); + kick_mupdate(0); referral_kick = 0; } @@ -5009,7 +5011,7 @@ /* do MUPDATE create operations */ } /* make sure we've seen the update */ - if (ultraparanoid && res == PROXY_OK) kick_mupdate(); + if (ultraparanoid && res == PROXY_OK) kick_mupdate(0); } imapd_check(s, 0, 0); @@ -5069,7 +5071,7 @@ else { if (config_mupdate_server && (config_mupdate_config != IMAP_ENUM_MUPDATE_CONFIG_STANDARD)) { - kick_mupdate(); + kick_mupdate(0); } prot_printf(imapd_out, "%s OK %s\r\n", tag, @@ -5161,7 +5163,7 @@ } /* make sure we've seen the update */ - if (ultraparanoid && res == PROXY_OK) kick_mupdate(); + if (ultraparanoid && res == PROXY_OK) kick_mupdate(0); } imapd_check(s, 0, 0); @@ -5241,7 +5243,7 @@ else { if (config_mupdate_server && (config_mupdate_config != IMAP_ENUM_MUPDATE_CONFIG_STANDARD)) { - kick_mupdate(); + kick_mupdate(0); } prot_printf(imapd_out, "%s OK %s\r\n", tag, @@ -5434,7 +5436,7 @@ res = pipe_including_tag(s, tag, 0); /* make sure we've seen the update */ - if (ultraparanoid && res == PROXY_OK) kick_mupdate(); + if (ultraparanoid && res == PROXY_OK) kick_mupdate(0); return; } @@ -5457,7 +5459,7 @@ } /* make sure we've seen the update */ - if (res == PROXY_OK) kick_mupdate(); + if (res == PROXY_OK) kick_mupdate(0); } imapd_check(s, 0, 0); @@ -5627,7 +5629,7 @@ } else { if (config_mupdate_server && (config_mupdate_config != IMAP_ENUM_MUPDATE_CONFIG_STANDARD)) { - kick_mupdate(); + kick_mupdate(0); } prot_printf(imapd_out, "%s OK %s\r\n", tag, @@ -6345,7 +6347,7 @@ /* setup new ACL in MUPDATE */ } /* make sure we've seen the update */ - if (ultraparanoid && res == PROXY_OK) kick_mupdate(); + if (ultraparanoid && res == PROXY_OK) kick_mupdate(0); } imapd_check(s, 0, 0); @@ -6374,7 +6376,7 @@ } else { if (config_mupdate_server && (config_mupdate_config != IMAP_ENUM_MUPDATE_CONFIG_STANDARD)) { - kick_mupdate(); + kick_mupdate(0); } prot_printf(imapd_out, "%s OK %s\r\n", tag, diff -Naur /var/tmp/cyrus/134/imap/lmtpd.c 134/imap/lmtpd.c --- /var/tmp/cyrus/134/imap/lmtpd.c 2009-03-31 12:01:01.000000000 -0400 +++ 134/imap/lmtpd.c 2009-03-31 11:05:20.000000000 -0400 @@ -447,7 +447,9 @@ /* do a local lookup and kick the slave if necessary */ r = mboxlist_detail(name, &type, NULL, NULL, server, aclp, tid); if (r == IMAP_MAILBOX_NONEXISTENT && config_mupdate_server) { - kick_mupdate(); + if (kick_mupdate(60) != 0) { + fatal("error communicating with local MUPDATE slave", EC_TEMPFAIL); + } r = mboxlist_detail(name, &type, NULL, NULL, server, aclp, tid); } } diff -Naur /var/tmp/cyrus/134/imap/mupdate-client.c 134/imap/mupdate-client.c --- /var/tmp/cyrus/134/imap/mupdate-client.c 2009-03-31 12:01:01.000000000 -0400 +++ 134/imap/mupdate-client.c 2009-03-31 10:13:46.000000000 -0400 @@ -656,12 +656,27 @@ return r; } -void kick_mupdate(void) +static volatile sig_atomic_t km_timedout = 0; + +static void km_timed_out(int sig) +{ + if (sig == SIGALRM) { + km_timedout = 1; + } else { + fatal("Bad signal in km_timed_out", EC_SOFTWARE); + } +} + + +int kick_mupdate(time_t timeout) { char buf[2048]; struct sockaddr_un srvaddr; int s, r; int len; + int rc = 0; + struct sigaction action; + s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { @@ -676,18 +691,51 @@ strcpy(srvaddr.sun_path, buf); len = sizeof(srvaddr.sun_family) + strlen(srvaddr.sun_path) + 1; + if (timeout) { + /* Setup timeout */ + km_timedout = 0; + action.sa_flags = 0; + action.sa_handler = km_timed_out; + if(sigaction(SIGALRM, &action, NULL) < 0) + { + syslog(LOG_ERR, "Setting timeout in kick_mupdate failed: sigaction: %m"); + /* continue anyway */ + } + + alarm(timeout); + } + r = connect(s, (struct sockaddr *)&srvaddr, len); if (r == -1) { - syslog(LOG_ERR, "kick_mupdate: can't connect to target: %m"); - goto done; + if (timeout && km_timedout) { + syslog(LOG_ERR, "kick_mupdate: connect to local mupdate slave timed out after %d seconds",timeout); + rc = MUPDATE_TIMEOUT; + } else { + syslog(LOG_ERR, "kick_mupdate: can't connect to local mupdate slave: %m"); + rc = MUPDATE_NOCONN; + } + goto done; } + if (timeout) { + alarm(timeout); + } r = read(s, buf, sizeof(buf)); - if (r <= 0) { - syslog(LOG_ERR, "kick_mupdate: can't read from target: %m"); + if (r == -1) { + if (timeout && km_timedout) { + syslog(LOG_ERR, "kick_mupdate: timed out reading from local mupdate slave after %d seconds.",timeout); + rc = MUPDATE_TIMEOUT; + } else { + syslog(LOG_ERR, "kick_mupdate: can't read from local mupdate slave: %m"); + rc = MUPDATE_NOCONN; + } } done: + if (timeout) { + alarm(0); + signal(SIGALRM, SIG_IGN); + } close(s); - return; + return(rc); } diff -Naur /var/tmp/cyrus/134/imap/mupdate-client.h 134/imap/mupdate-client.h --- /var/tmp/cyrus/134/imap/mupdate-client.h 2009-03-31 12:01:01.000000000 -0400 +++ 134/imap/mupdate-client.h 2009-03-31 08:45:33.000000000 -0400 @@ -112,6 +112,6 @@ void *context); /* ping a local slave */ -void kick_mupdate(void); +int kick_mupdate(time_t timeout); #endif diff -Naur /var/tmp/cyrus/134/imap/mupdate.c 134/imap/mupdate.c --- /var/tmp/cyrus/134/imap/mupdate.c 2009-03-31 12:01:01.000000000 -0400 +++ 134/imap/mupdate.c 2009-03-31 09:29:45.000000000 -0400 @@ -881,7 +881,7 @@ if (c->streaming) { /* Make *very* sure we are up-to-date */ - kick_mupdate(); + kick_mupdate(0); sendupdates(c, 0); /* don't flush pout though */ } diff -Naur /var/tmp/cyrus/134/imap/nntpd.c 134/imap/nntpd.c --- /var/tmp/cyrus/134/imap/nntpd.c 2009-03-31 12:01:01.000000000 -0400 +++ 134/imap/nntpd.c 2009-03-31 10:16:40.000000000 -0400 @@ -307,7 +307,9 @@ r = mboxlist_detail(name, &type, NULL, NULL, server, aclp, tid); if (r == IMAP_MAILBOX_NONEXISTENT && config_mupdate_server) { - kick_mupdate(); + if (kick_mupdate(0) != 0) { + return IMAP_IOERROR; + } r = mboxlist_detail(name, &type, NULL, NULL, server, aclp, tid); } diff -Naur /var/tmp/cyrus/134/imap/smmapd.c 134/imap/smmapd.c --- /var/tmp/cyrus/134/imap/smmapd.c 2009-03-31 12:01:01.000000000 -0400 +++ 134/imap/smmapd.c 2009-03-31 10:15:31.000000000 -0400 @@ -303,7 +303,9 @@ */ r = mboxlist_detail(namebuf, &type, &path, NULL, NULL, &acl, NULL); if (r == IMAP_MAILBOX_NONEXISTENT && config_mupdate_server) { - kick_mupdate(); + if (kick_mupdate(0) != 0) { + return IMAP_IOERROR; + } r = mboxlist_detail(namebuf, &type, &path, NULL, NULL, &acl, NULL); }