chiark / gitweb /
do not debug log every filemon event
[inn-innduct.git] / backends / innduct.c
index 54580afbd386ca21391ce63a667821d1b32de74f..609cf7951f9e1fa3be9db346e61d5a2b8d11c27d 100644 (file)
@@ -1,28 +1,38 @@
+/*
+ *  innduct
+ *  tailing reliable realtime streaming feeder for inn
+ *
+ *  Copyright (C) 2010 Ian Jackson <ijackson@chiark.greenend.org.uk>
+ * 
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  (I believe that when you compile and link this as part of the inn2
+ *  build, with the Makefile runes I have provided, all the libraries
+ *  and files which end up included in innduct are licence-compatible
+ *  with GPLv3.  If not then please let me know.  -Ian Jackson.)
+ */
+
+/*
+ * todo
+ *  specify perms of /tmp/innduct.control
+ */
+
 /*
  * debugging rune:
  *  build-lfs/backends/innduct --connection-timeout=30 --no-daemon -C ../inn.conf -f `pwd`/fee sit localhost
  */
 
-/*--
-flow control notes
-to ensure articles go away eventually
-separate queue for each input file
-  queue expiry
-    every period, check head of backlog queue for expiry with SMretrieve
-      if too old: discard, and check next article
-    also check every backlog article as we read it
-  flush expiry
-    after too long in SEPARATED/DROPPING ie Separated/Finishing/Dropping
-    one-off: eat queued articles from flushing and write them to defer
-    one-off: connfail all connections which have any articles from flushing
-    newly read articles from flushing go straight to defer
-    this should take care of it and get us out of this state
-to avoid filling up ram needlessly
-  input control
-    limit number of queued articles for each ipf
-    pause/resume inputfile tailing
---*/
-
 /*
  * Newsfeeds file entries should look like this:
  *     host.name.of.site[/exclude,exclude,...]\
@@ -313,7 +323,8 @@ static void statemc_setstate(StateMachineState newsms, int periods,
 
 static void statemc_start_flush(const char *why); /* Normal => Flushing */
 static void spawn_inndcomm_flush(const char *why); /* Moved => Flushing */
-static int trigger_flush_ok(void); /* => Flushing,FLUSHING, ret 1; or ret 0 */
+static int trigger_flush_ok(const char *why /* 0 means timeout */);
+                                  /* => Flushing,FLUSHING, ret 1; or ret 0 */
 
 static void article_done(Article *art, int whichcount);
 
@@ -554,7 +565,7 @@ static void logv(int sysloglevel, const char *pfx, int errnoval,
                 const char *fmt, va_list al) PRINTF(5,0);
 static void logv(int sysloglevel, const char *pfx, int errnoval,
                 const char *fmt, va_list al) {
-  char msgbuf[256]; /* NB do not call xvasprintf here or you'll recurse */
+  char msgbuf[1024]; /* NB do not call xvasprintf here or you'll recurse */
   vsnprintf(msgbuf,sizeof(msgbuf), fmt,al);
   msgbuf[sizeof(msgbuf)-1]= 0;
 
@@ -845,7 +856,7 @@ CCMD(help) {
 }
 
 CCMD(flush) {
-  int ok= trigger_flush_ok();
+  int ok= trigger_flush_ok("manual request");
   if (!ok) fprintf(cc->out,"already flushing (state is %s)\n", sms_names[sms]);
 }
 
@@ -1539,6 +1550,26 @@ static void conn_maybe_write(Conn *conn)  {
 
 /*---------- expiry, flow control and deferral ----------*/
 
+/*
+ * flow control notes
+ * to ensure articles go away eventually
+ * separate queue for each input file
+ *   queue expiry
+ *     every period, check head of backlog queue for expiry with SMretrieve
+ *       if too old: discard, and check next article
+ *     also check every backlog article as we read it
+ *   flush expiry
+ *     after too long in SEPARATED/DROPPING ie Separated/Finishing/Dropping
+ *     one-off: eat queued articles from flushing and write them to defer
+ *     one-off: connfail all connections which have any articles from flushing
+ *     newly read articles from flushing go straight to defer
+ *     this should take care of it and get us out of this state
+ * to avoid filling up ram needlessly
+ *   input control
+ *     limit number of queued articles for each ipf
+ *     pause/resume inputfile tailing
+ */
+
 static void check_reading_pause_resume(InputFile *ipf) {
   if (ipf->queue.count >= max_queue_per_ipf)
     inputfile_reading_pause(ipf);
@@ -2254,7 +2285,7 @@ static void *filemon_inotify_readable(oop_source *lp, int fd,
       die("inotify read %d bytes wanted struct of %d", r, (int)sizeof(iev));
     }
     InputFile *ipf= filemon_inotify_wd2ipf[iev.wd];
-    debug("filemon inotify readable read %p wd=%d", ipf, iev.wd);
+    /*debug("filemon inotify readable read %p wd=%d", ipf, iev.wd);*/
     filemon_callback(ipf);
   }
   return OOP_CONTINUE;
@@ -2279,7 +2310,7 @@ static void filemon_method_dump_info(FILE *f) {
   DUMPV("%d",,filemon_inotify_fd);
   DUMPV("%d",,filemon_inotify_wdmax);
   for (i=0; i<filemon_inotify_wdmax; i++)
-    fprintf(f," wd2ipf[%d]=%p\n", i, filemon_inotify_wd2ipf[i],);
+    fprintf(f," wd2ipf[%d]=%p\n", i, filemon_inotify_wd2ipf[i]);
 }
 
 #endif /* HAVE_INOTIFY && !HAVE_FILEMON */
@@ -2610,20 +2641,21 @@ static void statemc_start_flush(const char *why) { /* Normal => Flushing */
   spawn_inndcomm_flush(why); /* => Flushing FLUSHING */
 }
 
-static int trigger_flush_ok(void) { /* => Flushing,FLUSHING, ret 1; or ret 0 */
+static int trigger_flush_ok(const char *why) {
   switch (sms) {
 
   case sm_NORMAL:
-    statemc_start_flush("periodic"); /* Normal => Flushing; => FLUSHING */
-    return 1;
+    statemc_start_flush(why ? why : "periodic");
+    return 1;                           /* Normal => Flushing; => FLUSHING */
 
   case sm_FLUSHFAILED:
-    spawn_inndcomm_flush("retry"); /* Moved => Flushing; => FLUSHING */
-    return 1;
+    spawn_inndcomm_flush(why ? why : "retry");
+    return 1;                            /* Moved => Flushing; => FLUSHING */
 
   case sm_SEPARATED:
   case sm_DROPPING:
-    warn("took too long to complete old feedfile after flush, autodeferring");
+    warn("abandoning old feedfile after flush (%s), autodeferring",
+        why ? why : "took too long to complete");
     assert(flushing_input_file);
     autodefer_input_file(flushing_input_file);
     return 1;
@@ -2639,7 +2671,7 @@ static void statemc_period_poll(void) {
   assert(until_flush>=0);
 
   if (until_flush) return;
-  int ok= trigger_flush_ok();
+  int ok= trigger_flush_ok(0);
   assert(ok);
 }
 
@@ -3305,6 +3337,7 @@ static void dump_input_file(FILE *f, const ControlCommand *c,
     DUMPV("%d", ipf->,readcount_ok);
     DUMPV("%d", ipf->,readcount_blank);
     DUMPV("%d", ipf->,readcount_err);
+    DUMPV("%d", ipf->,count_nooffer_missing);
   }
   fprintf(f,"\n");
   if (ipf) {
@@ -3732,6 +3765,10 @@ int main(int argc, char **argv) {
 
   notice("starting");
 
+  int val= 1;
+  r= SMsetup(SM_PREOPEN, &val); if (!r) warn("SMsetup SM_PREOPEN failed");
+  r= SMinit(); if (!r) die("storage manager initialisation (SMinit) failed");
+
   if (!become_daemon)
     control_stdio();