Make the settings file more like an init.d script, add log rotation support and pidfi...
authorDaniel Silverstone <dsilvers@svn.openstreetmap.org>
Sat, 8 Nov 2008 16:27:52 +0000 (16:27 +0000)
committerDaniel Silverstone <dsilvers@svn.openstreetmap.org>
Sat, 8 Nov 2008 16:27:52 +0000 (16:27 +0000)
settings.sh
src/log.c
src/log.h
src/main.c

index 8867833..c2a215a 100755 (executable)
@@ -24,10 +24,97 @@ setting MYSQL_USER openstreetmap
 setting MYSQL_DB openstreetmap
 setting MYSQL_PASS openstreetmap
 
+# Logging, pidfiles etc
+# If you comment out the LOGFILE then it will log to stdout
+setting LOG_FILE /home/osm/gpx-import.log
+# If you comment out the PIDFILE then it will not daemonise
+setting PID_FILE /home/osm/gpx-import.pid
+
 # Optional debug statements
 #setting INTERPOLATE_STDOUT 1
 
-# Run the commandline
-
-exec "$@"
+CMD=$1
+shift
 
+case "$CMD" in
+    start)
+       if test "x$GPX_PID_FILE" = "x"; then
+           exec "$@"
+       else
+           "$@"
+           $0 check
+       fi
+       ;;
+    stop)
+       if test -r $GPX_PID_FILE; then
+           PID=$(cat $GPX_PID_FILE)
+           if test "x$PID" != "x"; then
+               if kill -0 $PID; then
+                   kill -TERM $PID
+                   for TRY in $(seq 1 10); do
+                       sleep 1
+                       if ! kill -0 $PID; then
+                           echo "GPX daemon killed"
+                           rm -f $GPX_PID_FILE
+                           exit 0
+                       else
+                           echo "Still running?"
+                       fi
+                   done
+                   echo "GPX daemon still running?"
+                   exit 1
+               else
+                   echo "GPX daemon is not running, pid ?= $PID"
+                   exit 1
+               fi
+           else
+               echo "GPX daemon pidfile is empty"
+               exit 1
+           fi
+       else
+           echo "GPX daemon pidfile is missing"
+           exit 1
+       fi
+       ;;
+    rotated)
+       if test -r $GPX_PID_FILE; then
+           PID=$(cat $GPX_PID_FILE)
+           if test "x$PID" != "x"; then
+               if kill -0 $PID; then
+                   kill -HUP $PID
+                   echo "GPX daemon sent HUP"
+                   sleep 0.5
+                   $0 check
+               else
+                   echo "GPX daemon is not running, pid ?= $PID"
+               fi
+           else
+               echo "GPX daemon pidfile is empty"
+           fi
+       else
+           echo "GPX daemon pidfile is missing"
+       fi
+       ;;
+    check)
+       if test -r $GPX_PID_FILE; then
+           PID=$(cat $GPX_PID_FILE)
+           if test "x$PID" != "x"; then
+               if kill -0 $PID; then
+                   echo "GPX daemon is running, pid = $PID"
+               else
+                   echo "GPX daemon is not running, pid ?= $PID"
+                   exit 1
+               fi
+           else
+               echo "GPX daemon pidfile is empty"
+               exit 1
+           fi
+       else
+           echo "GPX daemon pidfile is missing"
+           exit 1
+       fi
+       ;;
+    *)
+       echo "usage: $0 [start|stop|rotated|check] path/to/gpx-import"
+       ;;
+esac
index e2a007d..d9f2730 100644 (file)
--- a/src/log.c
+++ b/src/log.c
 #include <stdarg.h>
 #include <time.h>
 #include <string.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdlib.h>
 
 #include "log.h"
 
 #define LOGBUFLEN 1024
 
+static char logfilename[PATH_MAX];
+static bool logfilename_initialised = false;
+
+static FILE *logfile;
+
+void
+log_reopen(void)
+{
+  if (!logfilename_initialised) {
+    strncpy(logfilename, getenv("GPX_LOG_FILE") ? getenv("GPX_LOG_FILE") : "-", PATH_MAX);
+    INFO("Initialising logfile '%s'", logfilename);
+    logfile = stdout;
+    logfilename_initialised = true;
+  }
+  if (strcmp(logfilename, "-") == 0)
+    return;
+  if (logfile != stdout)
+    INFO("Rotating logfile");
+  fclose(logfile);
+  logfile = fopen(logfilename, "a");
+  if (logfile == NULL) {
+    fprintf(stderr, "Unable to open logfile %s!\n", logfilename);
+    exit(2);
+  }
+  INFO("Logfile opened");
+}
+
+void
+log_close(void)
+{
+  if (strcmp(logfilename, "-") == 0)
+    return;
+  INFO("Log terminated");
+  fclose(logfile);
+}
+
 void
 _gpxlog(const char *level, const char *fmt, ...)
 {
@@ -43,5 +82,11 @@ _gpxlog(const char *level, const char *fmt, ...)
   va_start(ap, fmt);
   vsnprintf(buffer + strlen(buffer), LOGBUFLEN - strlen(buffer) - 1, fmt, ap);
   va_end(ap);
-  puts(buffer);
+  if (!logfilename_initialised) {
+    puts(buffer);
+  } else {
+    fputs(buffer, logfile);
+    fputc('\n', logfile);
+    fflush(logfile);
+  }
 }
index 6762a80..ec0fc67 100644 (file)
--- a/src/log.h
+++ b/src/log.h
@@ -23,6 +23,9 @@
 extern void _gpxlog(const char *level, const char *fmt, ...)
   __attribute__ ((format (printf, 2, 3)));
 
+extern void log_reopen(void);
+extern void log_close(void);
+
 
 
 #ifdef NDEBUG
index 6434210..3254859 100644 (file)
@@ -24,6 +24,7 @@
 #include <signal.h>
 #include <string.h>
 #include <inttypes.h>
+#include <errno.h>
 
 #include "gpx.h"
 #include "db.h"
 #include "interpolate.h"
 
 static bool needs_quit = false;
+static bool needs_logfile_rotate = false;
+
+static void
+unlink_pidfile(void)
+{
+  if (getenv("GPX_PID_FILE") == NULL) {
+    return;
+  }
+  
+  unlink(getenv("GPX_PID_FILE"));
+}
+  
+static void
+do_pidfile(void)
+{
+  int childpid;
+  FILE *f;
+  
+  if (getenv("GPX_PID_FILE") == NULL) {
+    INFO("No pidfile specified, not daemonising");
+    log_reopen();
+    return;
+  }
+  
+  f = fopen(getenv("GPX_PID_FILE"), "w");
+  if (f == NULL) {
+    ERROR("Unable to open pidfile %s", getenv("GPX_PID_FILE"));
+    exit(1);
+  }
+  
+  childpid = fork();
+  switch(childpid) {
+  case -1:
+    ERROR("Unable to fork() for child: %s (%d)", strerror(errno), errno);
+    exit(1);
+    break;
+  case 0:
+    /* Child */
+    setsid();
+    setpgid(0, 0);
+    log_reopen();
+    fclose(stderr);
+    break;
+  default:
+    /* Parent */
+    fprintf(f, "%d\n", childpid);
+    fclose(f);
+    exit(0);
+  }
+}
 
 static void
 do_quit(int ignored)
@@ -45,6 +96,13 @@ do_quit(int ignored)
   needs_quit = true;
 }
 
+static void
+do_logfile(int ignored)
+{
+  (void)ignored;
+  needs_logfile_rotate = true;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -67,10 +125,17 @@ main(int argc, char **argv)
     return 1;
   }
   
-  signal(SIGHUP, do_quit);
+  signal(SIGHUP, do_logfile);
   signal(SIGINT, do_quit);
+  signal(SIGTERM, do_quit);
+  
+  do_pidfile(); /* Note: this will also reopen the logfile nicely */
   
   do {
+    if (needs_logfile_rotate == true) {
+      log_reopen();
+      needs_logfile_rotate = false;
+    }
     DEBUG("Looking for work");
     cstart = clock();
     job = db_find_work(sleep_time);
@@ -143,5 +208,9 @@ main(int argc, char **argv)
   
   DEBUG("Bye");
   
+  log_close();
+  
+  unlink_pidfile();
+  
   return 0;
 }