chiark / gitweb /
Merge branch 'master' of login.chiark.greenend.org.uk:public-git/inn-innduct
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Mon, 3 May 2010 12:35:28 +0000 (13:35 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Mon, 3 May 2010 12:35:28 +0000 (13:35 +0100)
1  2 
backends/innduct.c

diff --combined backends/innduct.c
index c0404fc011b9a0b0715055664c635170ee6812d7,609cf7951f9e1fa3be9db346e61d5a2b8d11c27d..a7679334ca196e01445d645f5135017f4e425b26
   *  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
 - */
 -
  /*
   * Newsfeeds file entries should look like this:
   *     host.name.of.site[/exclude,exclude,...]\
@@@ -313,7 -323,8 +313,8 @@@ static void statemc_setstate(StateMachi
  
  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);
  
@@@ -350,12 -361,11 +351,12 @@@ static void connfail(Conn *conn, const 
  static const oop_rd_style peer_rd_style;
  static oop_rd_call peer_rd_err, peer_rd_ok;
  
 +
  /*----- configuration options -----*/
  /* when changing defaults, remember to update the manpage */
  
  static const char *sitename, *remote_host;
 -static const char *feedfile, *realsockdir="/tmp/innduct.control";
 +static const char *feedfile, *path_control;
  static int quiet_multiple=0;
  static int become_daemon=1, try_filemon=1;
  static int try_stream=1;
@@@ -517,7 -527,8 +518,7 @@@ struct Conn 
  /* main initialises */
  static oop_source *loop;
  static ConnList conns;
 -static char *path_lock, *path_flushing, *path_defer;
 -static char *path_control, *path_dump;
 +static char *path_lock, *path_flushing, *path_defer, *path_dump;
  static char *globpat_backlog;
  static pid_t self_pid;
  
@@@ -554,7 -565,7 +555,7 @@@ static void logv(int sysloglevel, cons
                 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 +846,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]);
  }
  
@@@ -999,6 -1010,8 +1000,6 @@@ static void *control_master_readable(oo
    }while(0)
  
  static void control_init(void) {
 -  char *real=0;
 -  
    union {
      struct sockaddr sa;
      struct sockaddr_un un;
    memset(&sa,0,sizeof(sa));
    int maxlen= sizeof(sa.un.sun_path);
  
 -  int reallen= readlink(path_control, sa.un.sun_path, maxlen);
 -  if (reallen<0) {
 -    if (errno != ENOENT)
 -      NOCONTROL("readlink control socket symlink path %s", path_control);
 -  }
 -  if (reallen >= maxlen) {
 -    debug("control socket symlink path too long (r=%d)",reallen);
 -    xunlink(path_control, "old (overlong) control socket symlink");
 -    reallen= -1;
 -  }
 -  
 -  if (reallen<0) {
 -    struct stat stab;
 -    int r= lstat(realsockdir,&stab);
 -    if (r) {
 -      if (errno != ENOENT) NOCONTROL("lstat real socket dir %s", realsockdir);
 -
 -      r= mkdir(realsockdir, 0700);
 -      if (r) NOCONTROL("mkdir real socket dir %s", realsockdir);
 -
 -    } else {
 -      uid_t self= geteuid();
 -      if (!S_ISDIR(stab.st_mode) ||
 -        stab.st_uid != self ||
 -        stab.st_mode & 0007) {
 -      warn("no control socket, because real socket directory"
 -           " is somehow wrong (ISDIR=%d, uid=%lu (exp.%lu), mode %lo)",
 -           !!S_ISDIR(stab.st_mode),
 -           (unsigned long)stab.st_uid, (unsigned long)self,
 -           (unsigned long)stab.st_mode & 0777UL);
 -      goto nocontrol;
 -      }
 -    }
 -
 -    real= xasprintf("%s/s%lx.%lx", realsockdir,
 -                  (unsigned long)xtime(), (unsigned long)self_pid);
 -    int reallen= strlen(real);
 -
 -    if (reallen >= maxlen) {
 -      warn("no control socket, because tmpnam gave overly-long path"
 -         " %s", real);
 -      goto nocontrol;
 -    }
 -    r= symlink(real, path_control);
 -    if (r) NOCONTROL("make control socket path %s a symlink to real"
 -                   " socket path %s", path_control, real);
 -    memcpy(sa.un.sun_path, real, reallen);
 -  }
 +  int pathlen= strlen(path_control);
 +  if (pathlen > maxlen)
 +    NOCONTROL("control socket path %s too long (%d>%d)",
 +            path_control, pathlen, maxlen);
  
 -  int r= unlink(sa.un.sun_path);
 +  int r= unlink(path_control);
    if (r && errno!=ENOENT)
 -    NOCONTROL("remove old real socket %s", sa.un.sun_path);
 +    NOCONTROL("remove old control socket %s", path_control);
  
    control_master= socket(PF_UNIX, SOCK_STREAM, 0);
    if (control_master<0) NOCONTROL("create new control socket");
  
 -  sa.un.sun_family= AF_UNIX;
    int sl= strlen(sa.un.sun_path) + offsetof(struct sockaddr_un, sun_path);
 +  sa.un.sun_family= AF_UNIX;
 +  memcpy(sa.un.sun_path, path_control, pathlen);
 +
    r= bind(control_master, &sa.sa, sl);
 -  if (r) NOCONTROL("bind to real socket path %s", sa.un.sun_path);
 +  if (r) NOCONTROL("bind to control socket path %s", sa.un.sun_path);
  
    r= listen(control_master, 5);
    if (r) NOCONTROL("listen");
    xsetnonblock(control_master, 1);
  
    loop->on_fd(loop, control_master, OOP_READ, control_master_readable, 0);
 -  info("control socket ok, real path %s", sa.un.sun_path);
 +  info("control socket ok, listening on %s", path_control);
  
    return;
  
   nocontrol:
 -  free(real);
    xclose_perhaps(&control_master, "control master",0);
    return;
  }
@@@ -2229,7 -2285,7 +2230,7 @@@ static void *filemon_inotify_readable(o
        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;
@@@ -2585,20 -2641,21 +2586,21 @@@ static void statemc_start_flush(const c
    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;
@@@ -2614,7 -2671,7 +2616,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);
  }
  
@@@ -3364,11 -3421,10 +3366,11 @@@ CCMD(dump) 
    }
  
    fprintf(f,"paths");
 +  DUMPV("%s", , feedfile);
 +  DUMPV("%s", , path_control);
    DUMPV("%s", , path_lock);
    DUMPV("%s", , path_flushing);
    DUMPV("%s", , path_defer);
 -  DUMPV("%s", , path_control);
    DUMPV("%s", , path_dump);
    DUMPV("%s", , globpat_backlog);
    fprintf(f,"\n");
@@@ -3552,7 -3608,7 +3554,7 @@@ static const Option innduct_options[]= 
  {0,"no-filemon",         0,       &try_filemon,              op_setint, 0   },
  {'C',"inndconf",         "F",     &inndconffile,             op_string      },
  {'P',"port",             "PORT",  &port,                     op_integer     },
 -{0,"ctrl-sock-dir",      0,       &realsockdir,              op_string      },
 +{0,"cli",                0,       &path_control,             op_string      },
  {0,"help",               0,       0,                         help           },
  
  {0,"max-connections",    "N",     &max_connections,          op_integer     },
@@@ -3602,14 -3658,6 +3604,14 @@@ static void convert_to_periods_rndup(in
    *store /= period_seconds;
  }
  
 +static void assemble_path(const char **path_io, const char *suffix,
 +                        const char *what) {
 +  const char *const specified= *path_io;
 +  if (!specified[0]) badusage("%s, if specified, must be nonempty", what);
 +  if (specified[strlen(specified)-1]=='/')
 +    *path_io= xasprintf("%s%s%s", specified, sitename, suffix);
 +}
 +
  int main(int argc, char **argv) {
    if (!argv[1]) {
      printusage(stderr);
    if (max_bad_data_ratio < 0 || max_bad_data_ratio > 100)
      badusage("bad input data ratio must be between 0..100");
    max_bad_data_ratio *= 0.01;
 +  
 +  if (!feedfile) feedfile= xasprintf("%s/%s",innconf->pathoutgoing,sitename);
 +  else assemble_path(&feedfile, "", "feed filename");
  
 -  if (!feedfile) {
 -    feedfile= xasprintf("%s/%s",innconf->pathoutgoing,sitename);
 -  } else if (!feedfile[0]) {
 -    badusage("feed filename must be nonempty");
 -  } else if (feedfile[strlen(feedfile)-1]=='/') {
 -    feedfile= xasprintf("%s%s",feedfile,sitename);
 -  }
 +  if (path_control) path_control= xasprintf("%s_cli", feedfile);
 +  else assemble_path(&path_control, "%s_cli", "control socket path");
  
    if (max_queue_per_ipf<0)
      max_queue_per_ipf= max_queue_per_conn * 2;
    path_lock=        xasprintf("%s_lock",      feedfile);
    path_flushing=    xasprintf("%s_flushing",  feedfile);
    path_defer=       xasprintf("%s_defer",     feedfile);
 -  path_control=     xasprintf("%s_control",   feedfile);
    path_dump=        xasprintf("%s_dump",      feedfile);
    globpat_backlog=  xasprintf("%s_backlog*",  feedfile);
  
  
    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");
 +//  r= SMinit(); if (!r) die("storage manager initialisation (SMinit) failed");
  
    if (!become_daemon)
      control_stdio();