Good afternoon,

Here's a patch I'm proposing for kick_mupdate to make it report error
conditions.

Wes, you specifically wanted to see how different callers would deal
with the returned error status.  You'll notice that in some cases I
ultimately didn't change the behavior from the calling side.  The
biggest difference in behavior is in lmtpd.c.

So far I've only confirmed that this code will compile.  I haven't done
any other testing with it yet.

Comments are welcome.

Thanks,

Dave
-- 
Dave McMurtrie, SPE
Email Systems Team Leader
Carnegie Mellon University,
Computing Services
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);
        }
 

Reply via email to