From: Ian Jackson Date: Wed, 21 Apr 2010 01:13:39 +0000 (+0100) Subject: implement connfail X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=inn-innduct.git;a=commitdiff_plain;h=3d18441fd7f23d987eaa016875097b382b1f5063 implement connfail --- diff --git a/backends/innduct.c b/backends/innduct.c index 46b84c6..5452cd8 100644 --- a/backends/innduct.c +++ b/backends/innduct.c @@ -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; ixmitu; 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)