chiark / gitweb /
implement connfail
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Wed, 21 Apr 2010 01:13:39 +0000 (02:13 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Wed, 21 Apr 2010 01:13:39 +0000 (02:13 +0100)
backends/innduct.c

index 46b84c6..5452cd8 100644 (file)
@@ -215,6 +215,15 @@ typedef enum {      /* in queue                 in conn->sent             */
   RCN(deferred)                                        \
   RCN(connretry)
 
+#define RCI_TRIPLE_FMT_BASE "%d(id%d+bd%d+nc%d)"
+#define RCI_TRIPLE_VALS_BASE(counts,x)         \
+       , counts[art_Unchecked] x               \
+       + counts[art_Wanted] x                  \
+       + counts[art_Unsolicited] x,            \
+       counts[art_Unchecked] x                 \
+       , counts[art_Wanted] x                  \
+       , counts[art_Unsolicited] x
+
 typedef enum {
 #define RC_INDEX(x) RCI_##x
   RESULT_COUNTS(RC_INDEX, RC_INDEX)
@@ -336,6 +345,7 @@ static pid_t xfork(const char *what) {
   child= fork();
   if (child==-1) sysdie("cannot fork for %s",what);
   if (!child) postfork(what);
+  debug("forked %s %ld", what, (unsigned long)child);
   return child;
 }
 
@@ -435,6 +445,7 @@ static void logcore(int sysloglevel, const char *fmt, ...) {
     vfprintf(stderr,fmt,al);
     putc('\n',stderr);
   }
+  va_end(al);
 }
 
 static void logv(int sysloglevel, const char *pfx, int errnoval,
@@ -491,6 +502,8 @@ static void connect_attempt_discard(void) {
   perhaps_close(&connecting_sockets[1]);
 
   if (connecting_child) {
+    r= kill(connecting_child, SIGTERM);
+    if (r) syswarn("failed to kill connecting child");
     int status= xwaitpid(&connecting_child, "connect");
 
     if (!(WIFEXITED(status) ||
@@ -577,7 +590,7 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) {
 
   /* Phew! */
   LIST_ADDHEAD(idle, conn);
-  notice(CN "connected %s", conn->fd, conn->stream ? "streaming" : "plain");
+  notice("#%d connected %s", conn->fd, conn->stream ? "streaming" : "plain");
   connect_attempt_discard();
   check_master_queue();
   return 0;
@@ -590,7 +603,7 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) {
   connect_attempt_discard();
 }
 
-static void connect_start() {
+static void connect_start(void) {
   assert(!connecting_sockets[0]);
   assert(!connecting_sockets[1]);
   assert(!connecting_child);
@@ -768,6 +781,45 @@ static void conn_check_work(Conn *conn)  {
   }
 }
 
+static void vconnfail(Conn *conn, const char *fmt, va_list al)
+     __attribute__((printf,2,0));
+
+static void vconnfail(Conn *conn, const char *fmt, va_list al) {
+  int requeue[art_MaxState];
+
+  Article *art;
+  while ((art= LIST_REMHEAD(conn->queue))) LIST_ADDTAIL(queue);
+  while ((art= LIST_REMHEAD(conn->sent))) {
+    counts[art->state]++;
+    if (art->state==art_Unsolicited) art->state= art_Unchecked;
+    LIST_ADDTAIL(queue);
+  }
+
+  int i;
+  XmitDetails *xd;
+  for (i=0, dp=&conn->xmitd; i<conn->xmitu; i++, dp++)
+    xmit_free(dp);
+
+  char *m= xvasprintf(fmt,al);
+  warn("#%d connection failed, requeueing " RCI_TRIPLE_FMT_BASE ": %s",
+       conn->fd, RCI_TRIPLE_FMT_VALS(requeue, /*nothing*/), m);
+  free(m);
+
+  close(conn->fd);
+  free(conn);
+
+  connect_delay= reconnect_delay_periods;
+  check_master_queue();
+}
+
+static void connfail(Connection *conn, const char *fmt, ...)
+     __attribute__((printf,2,3));
+static void connfail(Connection *conn, const char *fmt, ...) {
+  va_list al;
+  va_start(al,fmt);
+  vconnfail(fmt,al);
+  va_end(al);
+}
 
 /*========== article transmission ==========*/
 
@@ -1660,14 +1712,8 @@ static int inputfile_is_done(InputFile *ipf) {
 static void notice_processed(InputFile *ipf, const char *what,
                             const char *spec) {
 #define RCI_NOTHING(x) /* nothing */
-#define RCI_TRIPLE_FMT(x) " " #x "=%d(id%d+bd%d+nc%d)"
-#define RCI_TRIPLE_VALS(x)                     \
-       , ipf->counts[art_Unchecked].sent       \
-       + ipf->counts[art_Wanted].sent          \
-       + ipf->counts[art_Unsolicited].sent,    \
-       ipf->counts[art_Unchecked].sent         \
-       , ipf->counts[art_Wanted].sent          \
-       , ipf->counts[art_Unsolicited].sent
+#define RCI_TRIPLE_FMT(x) " " #x "=" RCI_TRIPLE_FMT_BASE
+#define RCI_TRIPLE_VALS(x) RCI_TRIPLE_VALS_BASE(ipf->counts, .x)
 
   info("processed %s%s offered=%d(ch%d,nc%d) accepted=%d(ch%d+nc%d)"
        RESULT_COUNTS(RCI_NOTHING, RCI_TRIPLE_FMT)