starter: Make daemon name configurable
authorAdrian-Ken Rueegsegger <ken@codelabs.ch>
Tue, 22 Jan 2013 15:13:15 +0000 (16:13 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 19 Mar 2013 14:23:45 +0000 (15:23 +0100)
A daemon can be specified using the '--daemon' command line parameter. This
tells starter to invoke a daemon other than 'charon'.

Additionally the ipsec script uses the environment variable DAEMON_NAME to tell
the starter which daemon to use.

src/ipsec/_ipsec.in
src/starter/confread.c
src/starter/files.h
src/starter/invokecharon.c
src/starter/starter.c

index 6b406f6..3742b12 100644 (file)
@@ -18,6 +18,9 @@
 PATH="/sbin:/bin:/usr/sbin:/usr/bin:@IPSEC_SBINDIR@"
 export PATH
 
+# set daemon name
+[ -z "$DAEMON_NAME" ] && DAEMON_NAME="charon"
+
 # name and version of the ipsec implementation
 OS_NAME=`uname -s`
 IPSEC_NAME="@IPSEC_NAME@"
@@ -30,8 +33,8 @@ IPSEC_CONFDIR="@IPSEC_CONFDIR@"
 IPSEC_PIDDIR="@IPSEC_PIDDIR@"
 IPSEC_SCRIPT="@IPSEC_SCRIPT@"
 
-IPSEC_STARTER_PID="${IPSEC_PIDDIR}/starter.pid"
-IPSEC_CHARON_PID="${IPSEC_PIDDIR}/charon.pid"
+IPSEC_STARTER_PID="${IPSEC_PIDDIR}/starter.${DAEMON_NAME}.pid"
+IPSEC_CHARON_PID="${IPSEC_PIDDIR}/${DAEMON_NAME}.pid"
 
 IPSEC_STROKE="${IPSEC_DIR}/stroke"
 IPSEC_STARTER="${IPSEC_DIR}/starter"
@@ -220,7 +223,7 @@ start)
        if [ -d /var/lock/subsys ]; then
                touch /var/lock/subsys/ipsec
        fi
-       exec $IPSEC_STARTER "$@"
+       exec $IPSEC_STARTER --daemon $DAEMON_NAME "$@"
        ;;
 status|statusall)
        op="$1"
index 883534a..f0f05b0 100644 (file)
@@ -190,7 +190,7 @@ static void load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
        /* verify the executables are actually available */
 #ifdef START_CHARON
        cfg->setup.charonstart = cfg->setup.charonstart &&
-                                                        daemon_exists("charon", CHARON_CMD);
+                                                        daemon_exists(daemon_name, cmd);
 #else
        cfg->setup.charonstart = FALSE;
 #endif
index 96b76fd..76cdaa9 100644 (file)
@@ -15,8 +15,6 @@
 #ifndef _STARTER_FILES_H_
 #define _STARTER_FILES_H_
 
-#define STARTER_PID_FILE IPSEC_PIDDIR "/starter.pid"
-
 #define PROC_NETKEY             "/proc/net/pfkey"
 #define PROC_KLIPS              "/proc/net/pf_key"
 #define PROC_MODULES    "/proc/modules"
 #define CONFIG_FILE     IPSEC_CONFDIR "/ipsec.conf"
 #define SECRETS_FILE    IPSEC_CONFDIR "/ipsec.secrets"
 
-#define CHARON_CMD      IPSEC_DIR "/charon"
 #define CHARON_CTL_FILE IPSEC_PIDDIR "/charon.ctl"
-#define CHARON_PID_FILE IPSEC_PIDDIR "/charon.pid"
+
+extern char *daemon_name;
+extern char *cmd;
+extern char *pid_file;
 
 #define DYNIP_DIR       IPSEC_PIDDIR "/dynip"
 
index 1c93381..d981f6c 100644 (file)
@@ -46,22 +46,22 @@ void starter_charon_sigchild(pid_t pid, int status)
                if (status == SS_RC_LIBSTRONGSWAN_INTEGRITY ||
                        status == SS_RC_DAEMON_INTEGRITY)
                {
-                       DBG1(DBG_APP, "charon has quit: integrity test of %s failed",
-                                (status == 64) ? "libstrongswan" : "charon");
+                       DBG1(DBG_APP, "%s has quit: integrity test of %s failed",
+                                daemon_name, (status == 64) ? "libstrongswan" : daemon_name);
                        _stop_requested = 1;
                }
                else if (status == SS_RC_INITIALIZATION_FAILED)
                {
-                       DBG1(DBG_APP, "charon has quit: initialization failed");
+                       DBG1(DBG_APP, "%s has quit: initialization failed", daemon_name);
                        _stop_requested = 1;
                }
                if (!_stop_requested)
                {
-                       DBG1(DBG_APP, "charon has died -- restart scheduled (%dsec)",
-                                CHARON_RESTART_DELAY);
+                       DBG1(DBG_APP, "%s has died -- restart scheduled (%dsec)",
+                                daemon_name, CHARON_RESTART_DELAY);
                        alarm(CHARON_RESTART_DELAY);   // restart in 5 sec
                }
-               unlink(CHARON_PID_FILE);
+               unlink(pid_file);
        }
 }
 
@@ -88,7 +88,8 @@ int starter_stop_charon (void)
                        else if (i == 40)
                        {
                                kill(pid, SIGKILL);
-                               DBG1(DBG_APP, "starter_stop_charon(): charon does not respond, sending KILL");
+                               DBG1(DBG_APP, "starter_stop_charon(): %s does not respond, sending KILL",
+                                        daemon_name);
                        }
                        else
                        {
@@ -98,15 +99,15 @@ int starter_stop_charon (void)
                }
                if (_charon_pid == 0)
                {
-                       DBG1(DBG_APP, "charon stopped after %d ms", 200*i);
+                       DBG1(DBG_APP, "%s stopped after %d ms", daemon_name, 200*i);
                        return 0;
                }
-               DBG1(DBG_APP, "starter_stop_charon(): can't stop charon !!!");
+               DBG1(DBG_APP, "starter_stop_charon(): can't stop %s !!!", daemon_name);
                return -1;
        }
        else
        {
-               DBG1(DBG_APP, "stater_stop_charon(): charon was not started...");
+               DBG1(DBG_APP, "stater_stop_charon(): %s was not started...", daemon_name);
        }
        return -1;
 }
@@ -119,7 +120,7 @@ int starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
        char buffer[BUF_LEN];
        int argc = 1;
        char *arg[] = {
-               CHARON_CMD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               cmd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
@@ -130,7 +131,7 @@ int starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
                argc = 0;
                arg[argc++] = "/usr/bin/gdb";
                arg[argc++] = "--args";
-               arg[argc++] = CHARON_CMD;
+               arg[argc++] = cmd;
                }
        if (!no_fork)
        {
@@ -172,7 +173,8 @@ int starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
 
        if (_charon_pid)
        {
-               DBG1(DBG_APP, "starter_start_charon(): charon already started...");
+               DBG1(DBG_APP, "starter_start_charon(): %s already started...",
+                        daemon_name);
                return -1;
        }
        else
@@ -203,9 +205,9 @@ int starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
                        {
                                /* wait for charon for a maximum of 500 x 20 ms = 10 s */
                                usleep(20000);
-                               if (stat(CHARON_PID_FILE, &stb) == 0)
+                               if (stat(pid_file, &stb) == 0)
                                {
-                                       DBG1(DBG_APP, "charon (%d) started after %d ms",
+                                       DBG1(DBG_APP, "%s (%d) started after %d ms", daemon_name,
                                                 _charon_pid, 20*(i+1));
                                        return 0;
                                }
@@ -213,7 +215,8 @@ int starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
                        if (_charon_pid)
                        {
                                /* If charon is started but with no ctl file, stop it */
-                               DBG1(DBG_APP, "charon too long to start... - kill kill");
+                               DBG1(DBG_APP, "%s too long to start... - kill kill",
+                                        daemon_name);
                                for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
                                {
                                        if (i == 0)
@@ -233,7 +236,7 @@ int starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
                        }
                        else
                        {
-                               DBG1(DBG_APP, "charon refused to be started");
+                               DBG1(DBG_APP, "%s refused to be started", daemon_name);
                        }
                        return -1;
                }
index ae6863f..917e52d 100644 (file)
@@ -12,6 +12,8 @@
  * for more details.
  */
 
+#define _GNU_SOURCE
+
 #include <sys/select.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 
 #define CHARON_RESTART_DELAY 5
 
+static const char* cmd_default = IPSEC_DIR "/charon";
+static const char* pid_file_default = IPSEC_PIDDIR "/charon.pid";
+static const char* starter_pid_file_default = IPSEC_PIDDIR "/starter.pid";
+
+char *daemon_name = NULL;
+char *cmd = NULL;
+char *pid_file = NULL;
+char *starter_pid_file = NULL;
+
 /* logging */
 static bool log_to_stderr = TRUE;
 static bool log_to_syslog = TRUE;
@@ -162,7 +173,10 @@ static void signal_handler(int signal)
                        {
                                if (pid == starter_charon_pid())
                                {
-                                       name = " (Charon)";
+                                       if (asprintf(&name, " (%s)", daemon_name) < 0)
+                                       {
+                                                name = NULL;
+                                       }
                                }
                                if (WIFSIGNALED(status))
                                {
@@ -193,6 +207,11 @@ static void signal_handler(int signal)
                                        starter_charon_sigchild(pid, exit_status);
                                }
                        }
+
+                       if (name)
+                       {
+                               free(name);
+                       }
                }
                break;
 
@@ -325,11 +344,56 @@ static bool check_pid(char *pid_file)
        return FALSE;
 }
 
+/* Set daemon name and adjust command and pid filenames accordingly */
+static bool set_daemon_name()
+{
+       if (!daemon_name)
+       {
+               daemon_name = "charon";
+       }
+
+       if (asprintf(&cmd, IPSEC_DIR"/%s", daemon_name) < 0)
+       {
+                cmd = (char*)cmd_default;
+       }
+
+       if (asprintf(&pid_file, IPSEC_PIDDIR"/%s.pid", daemon_name) < 0)
+       {
+                pid_file = (char*)pid_file_default;
+       }
+
+       if (asprintf(&starter_pid_file, IPSEC_PIDDIR"/starter.%s.pid",
+                                daemon_name) < 0)
+       {
+                starter_pid_file = (char*)starter_pid_file_default;
+       }
+
+       return TRUE;
+}
+
+static void cleanup()
+{
+       if (cmd != cmd_default)
+       {
+               free(cmd);
+       }
+
+       if (pid_file != pid_file_default)
+       {
+               free(pid_file);
+       }
+
+       if (starter_pid_file != starter_pid_file_default)
+       {
+               free(starter_pid_file);
+       }
+}
+
 static void usage(char *name)
 {
        fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>]\n"
                        "               [--debug|--debug-more|--debug-all|--nolog]\n"
-                       "               [--attach-gdb]\n");
+                       "               [--attach-gdb] [--daemon <name>]\n");
        exit(LSB_RC_INVALID_ARGUMENT);
 }
 
@@ -392,12 +456,22 @@ int main (int argc, char **argv)
                        if (!auto_update)
                                usage(argv[0]);
                }
+               else if (streq(argv[i], "--daemon") && i+1 < argc)
+               {
+                       daemon_name = argv[++i];
+               }
                else
                {
                        usage(argv[0]);
                }
        }
 
+       if (!set_daemon_name())
+       {
+               DBG1(DBG_APP, "unable to set daemon name");
+               exit(LSB_RC_FAILURE);
+       }
+
        init_log("ipsec_starter");
 
        DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...",
@@ -423,13 +497,14 @@ int main (int argc, char **argv)
        if (getuid() != 0)
        {
                DBG1(DBG_APP, "permission denied (must be superuser)");
+               cleanup();
                exit(LSB_RC_NOT_ALLOWED);
        }
 
-       if (check_pid(CHARON_PID_FILE))
+       if (check_pid(pid_file))
        {
-               DBG1(DBG_APP, "charon is already running (%s exists) -- skipping charon start",
-                        CHARON_PID_FILE);
+               DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start",
+                        daemon_name, pid_file);
        }
        else
        {
@@ -438,12 +513,14 @@ int main (int argc, char **argv)
        if (stat(DEV_RANDOM, &stb) != 0)
        {
                DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
+               cleanup();
                exit(LSB_RC_FAILURE);
        }
 
        if (stat(DEV_URANDOM, &stb)!= 0)
        {
                DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
+               cleanup();
                exit(LSB_RC_FAILURE);
        }
 
@@ -455,6 +532,7 @@ int main (int argc, char **argv)
                {
                        confread_free(cfg);
                }
+               cleanup();
                exit(LSB_RC_INVALID_ARGUMENT);
        }
 
@@ -471,11 +549,12 @@ int main (int argc, char **argv)
 
        last_reload = time_monotonic(NULL);
 
-       if (check_pid(STARTER_PID_FILE))
+       if (check_pid(starter_pid_file))
        {
                DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done",
-                        STARTER_PID_FILE);
+                        starter_pid_file);
                confread_free(cfg);
+               cleanup();
                exit(LSB_RC_SUCCESS);
        }
 
@@ -515,13 +594,14 @@ int main (int argc, char **argv)
                                break;
                        default:
                                confread_free(cfg);
+                               cleanup();
                                exit(LSB_RC_SUCCESS);
                }
        }
 
-       /* save pid file in /var/run/starter.pid */
+       /* save pid file in /var/run/starter[.daemon_name].pid */
        {
-               FILE *fd = fopen(STARTER_PID_FILE, "w");
+               FILE *fd = fopen(starter_pid_file, "w");
 
                if (fd)
                {
@@ -576,7 +656,8 @@ int main (int argc, char **argv)
                        }
                        starter_netkey_cleanup();
                        confread_free(cfg);
-                       unlink(STARTER_PID_FILE);
+                       unlink(starter_pid_file);
+                       cleanup();
                        DBG1(DBG_APP, "ipsec starter stopped");
                        close_log();
                        exit(LSB_RC_SUCCESS);
@@ -709,13 +790,13 @@ int main (int argc, char **argv)
                }
 
                /*
-                * Start charon
+                * Start daemon
                 */
                if (_action_ & FLAG_ACTION_START_CHARON)
                {
                        if (cfg->setup.charonstart && !starter_charon_pid())
                        {
-                               DBG2(DBG_APP, "Attempting to start charon...");
+                               DBG2(DBG_APP, "Attempting to start %s...", daemon_name);
                                if (starter_start_charon(cfg, no_fork, attach_gdb))
                                {
                                        /* schedule next try */
@@ -807,7 +888,8 @@ int main (int argc, char **argv)
                /*
                 * Wait for something to happen
                 */
-               if (pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
+               if (!_action_ &&
+                       pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
                                        &action.sa_mask) == 0)
                {
                        /* timeout -> auto_update */