[Initng-svn] r2977 - initng/plugins/daemon

svn at initng.thinktux.net svn at initng.thinktux.net
Thu Feb 9 19:26:29 CET 2006


Author: jimmy
Date: Thu Feb  9 19:26:28 2006
New Revision: 2977

Modified:
   initng/plugins/daemon/initng_daemon.c
Log:
Lots of work to initng_daemon.c


Modified: initng/plugins/daemon/initng_daemon.c
==============================================================================
--- initng/plugins/daemon/initng_daemon.c	(original)
+++ initng/plugins/daemon/initng_daemon.c	Thu Feb  9 19:26:28 2006
@@ -34,6 +34,12 @@
 #include <sys/reboot.h>                     /* reboot() RB_DISABLE_CAD */
 #include <assert.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
 
 
 #include "../../src/initng_handler.h"
@@ -45,6 +51,8 @@
 #include "../../src/initng_static_states.h"
 #include "../../src/initng_static_service_types.h"
 #include "../../src/initng_depend.h"
+#include "../../src/initng_env_variable.h"
+#include "../../src/initng_static_process_types.h"
 #include "../../src/initng_execute.h"
 
 #include "initng_daemon.h"
@@ -56,6 +64,9 @@
  */
 
 static void kill_daemon(active_db_h * service);
+static void clear_pidfile(active_db_h * s);
+static pid_t get_pidof(active_db_h * s);
+static pid_t get_pidfile(active_db_h * s, int warn);
 
 
 /*
@@ -77,6 +88,7 @@
 static void handle_DAEMON_WAITING_FOR_STOP_DEP(active_db_h * daemon);
 static void handle_DAEMON_START_DEPS_MET(active_db_h * daemon);
 static void handle_DAEMON_STOP_DEPS_MET(active_db_h * daemon);
+static void handle_DAEMON_WAIT_FOR_PID_FILE(active_db_h *daemon);
 
 /*
  * ############################################################################
@@ -101,6 +113,43 @@
 ptype_h T_DAEMON = { "daemon", &handle_killed_daemon };
 ptype_h T_KILL = { "kill", NULL };
 
+/*
+ * ############################################################################
+ * #                       DAEMON VARIABLES                                   #
+ * ############################################################################
+ */
+
+/*
+ * timeout waiting for a pidfile to be created
+ * after the daemon returns happily.
+ */
+#define PID_TIMEOUT 90
+
+/* Rate limit on missing pidfile warnings */
+#define PID_WARN_RATE 2
+
+/* The name of the process, initng should probe */
+s_entry PIDOF = { "pid_of", STRING, &TYPE_DAEMON,
+    "When daemon exits, initng will look for a process with this name, and set daemon pid no to that pid."
+};
+
+/* The filename/path of a pidfile that initng can fetch pid no */
+s_entry PIDFILE = { "pid_file", STRINGS, &TYPE_DAEMON,
+    "When daemon exits, initng will get pid of daemon from this file."
+};
+
+/* Determines when initng looks for a pidfile */
+s_entry FORKS = { "forks", SET, &TYPE_DAEMON,
+    "Does the daemon fork?"
+};
+
+/*
+ * this is an internal option, that is set after the
+ * service died once, and the pid is updated.
+ */
+s_entry INTERNAL_GOT_PID = { NULL, SET, &TYPE_DAEMON, NULL, NULL };
+s_entry INTERNAL_PIDFILE_TIMEOUT = { NULL, INT, &TYPE_DAEMON, NULL, NULL };
+s_entry INTERNAL_PID_WARN_TIME = { NULL, INT, &TYPE_DAEMON, NULL, NULL };
 
 /*
  * ############################################################################
@@ -151,9 +200,14 @@
 a_state_h DAEMON_STOPPED = { "DAEMON_STOPPED", IS_DOWN, NULL };
 
 /*
- * This is the state, when the Start code is actually running.
+ * This is the state, when the launch is actually run.
+ */
+a_state_h DAEMON_LAUNCH = { "DAEMON_LAUNCH", IS_STARTING, NULL };
+
+/*
+ * In this state, the fork has return, and initng is waiting for a pidfile to appeare.
  */
-a_state_h DAEMON_RUN = { "DAEMON_RUN", IS_STARTING, NULL };
+a_state_h DAEMON_WAIT_FOR_PID_FILE = { "DAEMON_WAIT_FOR_PID_FILE", IS_STARTING, &handle_DAEMON_WAIT_FOR_PID_FILE };
 
 /*
  * Generally FAILING states, if something goes wrong, some of these are set.
@@ -211,10 +265,22 @@
         return (FALSE);
     }
 
+    /* Add a new servicetype */
     initng_service_types_add(&TYPE_DAEMON);
 
+    /* Add 2 new processtype */
     initng_process_db_ptype_add(&T_DAEMON);
+    initng_process_db_ptype_add(&T_KILL);
 
+    /* Add some new variables */
+    initng_service_data_types_add(&PIDFILE);
+    initng_service_data_types_add(&PIDOF);
+    initng_service_data_types_add(&FORKS);
+    initng_service_data_types_add(&INTERNAL_GOT_PID);
+    initng_service_data_types_add(&INTERNAL_PIDFILE_TIMEOUT);
+    initng_service_data_types_add(&INTERNAL_PID_WARN_TIME);
+
+    /* Add some new service-states */
     initng_active_state_add(&DAEMON_START_MARKED);
     initng_active_state_add(&DAEMON_STOP_MARKED);
     initng_active_state_add(&DAEMON_RUNNING);
@@ -223,13 +289,14 @@
     initng_active_state_add(&DAEMON_START_DEPS_MET);
     initng_active_state_add(&DAEMON_STOP_DEPS_MET);
     initng_active_state_add(&DAEMON_STOPPED);
-    initng_active_state_add(&DAEMON_RUN);
+    initng_active_state_add(&DAEMON_LAUNCH);
+    initng_active_state_add(&DAEMON_WAIT_FOR_PID_FILE);
     initng_active_state_add(&DAEMON_START_DEPS_FAILED);
     initng_active_state_add(&DAEMON_STOP_DEPS_FAILED);
     initng_active_state_add(&DAEMON_FAIL_STARTING);
     initng_active_state_add(&DAEMON_FAIL_STOPPING);
 
-
+    /* return happily */
     return (TRUE);
 }
 
@@ -237,10 +304,7 @@
 {
     D_("module_unload();\n");
 
-    initng_service_types_del(&TYPE_DAEMON);
-
-    initng_process_db_ptype_del(&T_DAEMON);
-
+    /* Remove all added states */
     initng_active_state_del(&DAEMON_START_MARKED);
     initng_active_state_del(&DAEMON_STOP_MARKED);
     initng_active_state_del(&DAEMON_RUNNING);
@@ -249,12 +313,28 @@
     initng_active_state_del(&DAEMON_START_DEPS_MET);
     initng_active_state_del(&DAEMON_STOP_DEPS_MET);
     initng_active_state_del(&DAEMON_STOPPED);
-    initng_active_state_del(&DAEMON_RUN);
+    initng_active_state_del(&DAEMON_LAUNCH);
+    initng_active_state_del(&DAEMON_WAIT_FOR_PID_FILE);
     initng_active_state_del(&DAEMON_START_DEPS_FAILED);
     initng_active_state_del(&DAEMON_STOP_DEPS_FAILED);
     initng_active_state_del(&DAEMON_FAIL_STARTING);
     initng_active_state_del(&DAEMON_FAIL_STOPPING);
 
+    /* Delete all added variables */
+    initng_service_data_types_del(&PIDFILE);
+    initng_service_data_types_del(&PIDOF);
+    initng_service_data_types_del(&FORKS);
+    initng_service_data_types_del(&INTERNAL_GOT_PID);
+    initng_service_data_types_del(&INTERNAL_PIDFILE_TIMEOUT);
+    initng_service_data_types_del(&INTERNAL_PID_WARN_TIME);
+
+    /* Delete the processstypes */
+    initng_process_db_ptype_del(&T_DAEMON);
+    initng_process_db_ptype_del(&T_KILL);
+    
+    /* Last, delete the servicetype */
+    initng_service_types_del(&TYPE_DAEMON);
+
 }
 
 /*
@@ -386,7 +466,11 @@
 
 static void handle_DAEMON_START_DEPS_MET(active_db_h * daemon)
 {
-    if (!initng_common_mark_service(daemon, &DAEMON_RUN))
+    /* clear all stale pidfiles if any */
+    clear_pidfile(daemon);
+
+    /* set the DAEMON_LAUNCH state */
+    if (!initng_common_mark_service(daemon, &DAEMON_LAUNCH))
         return;
 
     /* F I N A L L Y   S T A R T */
@@ -404,8 +488,14 @@
             return;
     }
 
-    /* We just set it to up, as soon as it is started */
-    initng_common_mark_service(daemon, &DAEMON_RUNNING);
+    /* If this daemon never forks, set it to DAEMON_RUNNING directly */
+    if (!initng_active_db_is(&FORKS, daemon))
+    {
+	/* We just set it to up, as soon as it is started */
+	initng_common_mark_service(daemon, &DAEMON_RUNNING);
+    }
+    
+    /* Else Let this service stay in state DAEMON_RUN */
 }
 
 static void handle_DAEMON_STOP_DEPS_MET(active_db_h * service)
@@ -467,58 +557,176 @@
 
 
 
-#ifdef THIS_IS_DISABLED
-static void handle_STOPPED(active_db_h * daemon_stopped)
+
+
+/*
+ * Is run on every interrupt for services DAEMON_WAIT_FOR_PID_FILE
+ */
+static void handle_DAEMON_WAIT_FOR_PID_FILE(active_db_h * s)
 {
-    active_db_h *current, *safe = NULL;
+    pid_t pid = -1;
+    process_h *p = NULL;
+    int timeout = 0, wt, warn = 0;
 
-    /*
-     * Make sure there is no daemons that needs this
-     * that still think its running.
-     */
-    while_active_db_safe(current, safe)
+
+    timeout = initng_active_db_get_int(&INTERNAL_PIDFILE_TIMEOUT, s);
+    if (timeout > 0 && timeout < time(0))
     {
-        /* no idea to stop myself */
-        if (current == daemon_stopped)
-            continue;
+        F_("Service \"%s\" wait for pidfile timed out!\n", s->name);
+        initng_common_mark_service(s, &FAIL_STARTING);
+        return;
+    }
 
-        /* DON'T stop runlevels OR virtuals */
-        if (current->type == &TYPE_VIRTUAL)
-            continue;
+    wt = initng_active_db_get_int(&INTERNAL_PID_WARN_TIME, s);
+    if (wt > time(0) || (wt + PID_WARN_RATE) < time(0))
+    {
+        warn = 1;
+        initng_active_db_set_int(&INTERNAL_PID_WARN_TIME, s, (int) time(0));
+    }
 
-        /* check that current needs daemon_stopped */
-        if (initng_depend(current, daemon_stopped) == FALSE)
-            continue;
+    /* get the process to handle */
+    p = initng_process_db_get(&T_DAEMON, s);
+    if (!p)
+    {
+        F_("Did not find a daemon process on this service!\n");
+        initng_common_mark_service(s, &FAIL_STARTING);
+        return;
+    }
 
-        /* don't stop a stopped daemon */
-        if (IS_DOWN(current))
-            continue;
+    /* check if string PIDOF or PIDFILE exits */
+    if (initng_active_db_is(&PIDOF, s))
+    {
+        D_("getting pid by PIDOF!\n");
+        /* get pid by process name */
+        pid = get_pidof(s);
+        D_("result : %d\n", pid);
+    }
 
-        /* if stop this */
-        D_("%s have to stop %s.\n", daemon_stopped->name, current->name);
-        initng_handler_stop_daemon(current);
+    if (initng_active_db_is(&PIDFILE, s))
+    {
+        D_("getting pid by PIDFILE!\n");
+        pid = get_pidfile(s, warn);
+        D_("result : %d\n", pid);
     }
 
-    /* check if this daemon is restarting */
-    if (initng_active_db_is(&RESTARTING, daemon_stopped))
+    if (pid < 2)
     {
-        initng_active_db_remove(&RESTARTING, daemon_stopped);
-        initng_handler_start_daemon(daemon_stopped);
-        D_("Service is restarting now!\n");
+        /* make sure this one is run in 1 second again */
+        initng_global_set_sleep(1);
         return;
     }
 
+    if (kill(pid, 0) < 0 && (errno == ESRCH))
+    {
+        F_("Got a non-existent pid %i for daemon \"%s\"\n", pid, s->name);
+        initng_common_mark_service(s, &FAIL_STARTING);
+        return;
+    }
 
-    /* free daemon, and forget */
-    initng_active_db_del(daemon_stopped);
-    initng_active_db_free(daemon_stopped);
-    D_("Service removed.\n");
+    /* set the new pid, to that we got from pidof or pidfile */
+    if (initng_active_db_is(&FORKS, s))
+        p->pid = pid;
+
+    /* FIXME: if forks=noret, we should send messages to the pid in the
+       pidfile (and track changes in it), but use the original pid for
+       death detection - needed for mysql */
+
+    /* set INTERNAL_GOT_PID so that this service may be set to done */
+    initng_active_db_set(&INTERNAL_GOT_PID, s);
+    initng_active_db_unset(&INTERNAL_PIDFILE_TIMEOUT, s);
+
+    /* mark this service running */
+    initng_common_mark_service(s, &RUNNING);
 }
 
 
+/*
+ * ############################################################################
+ * #                         KILL HANDLER FUNCTIONS                            #
+ * ############################################################################
+ */
+
+static void handle_killed_daemon(active_db_h * daemon, process_h * process)
+{
+    assert(daemon);
+    assert(daemon->name);
+    assert(daemon->current_state);
+    assert(daemon->current_state->state_name);
+    assert(process);
 
+    D_("handle_killed_start(%s): initial status: \"%s\".\n",
+       daemon->name, daemon->current_state->state_name);
 
-#endif
+    /* Set the universal variable, that signalize that something happened */
+    initng_global_set_interrupt();
+
+    /*
+     * If the return code (for example "exit 1", in a bash script)
+     * from the program, is bigger than 0, this commonly signalize
+     * that something got wrong, print this as an error msg on screen
+     */
+    if (process->r_code > 0)
+    {
+        F_(" start %s, Returned with exit %i.\n", daemon->name,
+           process->r_code);
+    }
+
+
+    /*
+     * If the daemon is launching and not running
+     */
+    if (daemon->current_state == &DAEMON_LAUNCH)
+    {
+    
+	/*
+	 * If pidof or pidfile is set, try fetch the pid.
+	 */
+	if (initng_active_db_is(&PIDOF, daemon) || initng_active_db_is(&PIDFILE, daemon))
+	{
+	    /* Set the WAIT_FOR_PIDFILE state, This will start checking for pidfiles. */
+    	    initng_common_mark_service(daemon, &DAEMON_WAIT_FOR_PID_FILE);
+	    
+    	    /* set the timeout also */
+    	    initng_active_db_set_int(&INTERNAL_PIDFILE_TIMEOUT, daemon,
+                                 (int) time(0) + PID_TIMEOUT);
+    	    initng_active_db_set_int(&INTERNAL_PID_WARN_TIME, daemon, (int) time(0));
+	    
+	    /* return away from here */
+    	    return;
+	}
+	
+	W_("%s daemon forked, and exited, but initng have no way of getting the pid it got.\nInitng mark this daemon as running but wont notice if it dies.", daemon->name);
+	initng_common_mark_service(daemon, &DAEMON_RUNNING);
+	return;
+    }
+    /*
+     * Make sure r_code don't signal error (can be override by UP_ON_FAILURE.
+     */
+     
+     /*   TODO              MAKE UP_ON_FAILURE more universal */
+    if (process->r_code && !initng_active_db_is(&UP_ON_FAILURE, daemon))
+    {
+
+        initng_common_mark_service(daemon, &DAEMON_FAIL_STARTING);
+        list_del(&process->list);
+        initng_process_db_free(process);
+        return;
+    }
+
+    /* OK! now daemon is STOPPED! */
+    initng_common_mark_service(daemon, &DAEMON_STOPPED);
+
+    /* free the process struct, to spare memory */
+    list_del(&process->list);
+    initng_process_db_free(process);
+}
+
+/*
+ * ############################################################################
+ * #                         LOCAL FUNCTIONS                                  #
+ * ############################################################################
+ */
+ 
 
 static void kill_daemon(active_db_h * service)
 {
@@ -590,65 +798,276 @@
     }
 }
 
+/*
+ * pid_of(name)
+ *  This function will walk /proc all numbers dirs, looking in the stat file for
+ *  the process name, if it matches name, it will return the pid of it.
+ *  If it not succeeds to find it, it will return(-1).
+ */
+static pid_t pid_of(const char *name)
+{
+    DIR *dir;
+    struct dirent *d;
+    FILE *fp;
+
+    /* maximum possible length for string "/proc/12232/stat" can be */
+#define BUFF_SIZE 512
+
+    D_("Will fetch pid of \"%s\"\n", name);
+
+    /* Open /proc or fail */
+    if (!(dir = opendir("/proc")))
+        return (-1);
+
+    /* Walk through the directory. */
+    while ((d = readdir(dir)) != NULL)
+    {
+        char buf[BUFF_SIZE + 1];	/* Will contain a fixed string like "/proc/12232/stat" */
+        char *s = NULL;			/* Temporary pointer when parsing the content of the stat file */
+        int len = 0;			/* An length counter */
+        pid_t pid = -1;			/* Will contain the pid to return */
+
+        /* Make sure this dirname is a number == pid */
+        if ((pid = atoi(d->d_name)) <= 0)
+            continue;
+
+        /* Fix a string, that matches the full path of the stat file */
+        snprintf(buf, BUFF_SIZE, "/proc/%d/stat", pid);
+        D_("To open: %s\n", buf);
+
+        /* Read SID & statname from it or fail */
+        if (!(fp = fopen(buf, "r")))
+        {
+            W_("Could not open %s.\n", buf);
+            continue;
+        }
+
+        /* fetch the full stat file, or fail */
+        if (fgets(buf, BUFF_SIZE, fp) == NULL)
+	{
+	    fclose(fp);
+	    continue;
+	}
+
+	/* close stat file */
+	fclose(fp);
+	
+	/* set the walk counter, to the start of the file content fetched */
+        s = buf;
+
+        /* skip all chars to the first space - first string contains the pid no */
+        while (*s && *s != ' ')
+            s++;
+	    
+	/* Make sure we have any data */
+        if (*s == '\0')
+            continue;
+
+        /* skip the space */
+        s++;
+
+        /* skip the '(' char */
+        if (*s != '(')
+            continue;
+        s++;
+
+        /* count the length */
+        while (s[len] && s[len] != ')')
+            len++;
+
+	/* compare the name in the '(' ')' chars with the process name we are looking for */
+        if (strncmp(s, name, len) == 0)
+        {
+            D_("Found %s with pid %d\n", name, pid);
+	    
+	    /* make sure the dir (/proc) is closed. */
+	    if(dir)
+		closedir(dir);
+		
+	    /* return happily with the pid */
+            return (pid);
+        }
+    }
+    
+    /* close the dir (/proc) if still open */
+    if(dir) closedir(dir);
+
+    D_("Did not find a process with name \"%s\"\n", name);
+    return (-1);
+}
+
+
 
 /*
- * ############################################################################
- * #                         KILL HANDLER FUNCTIONS                            #
- * ############################################################################
+ * Check if a pidfile exists, if it exists, update the 
+ * pid in the active_db entry. and return TRUE
  */
+static pid_t pid_from_file(const char *name, int warn)
+{
+    int fd = 0;
+    int len = 0;
+    char buf[21];
 
-static void handle_killed_daemon(active_db_h * daemon, process_h * process)
+    assert(name);
+
+    /* open pid file */
+    fd = open(name, O_RDONLY);
+
+    /* If we cant open pidfile, this is bad */
+    if (fd == -1)
+    {
+        if (warn)
+            W_("Unable to open pidfile: %s, \"%s\", it might not be created yet.\n", name, strerror(errno));
+        return (-1);
+    }
+
+    /* Read data from buffer */
+    len = read(fd, buf, 20);
+    close(fd);
+    if (len < 1)
+    {
+        F_("Read 0 chars from %s, It's empty.\n", name);
+        return (-1);
+    }
+
+    /* remove last newline */
+    if (buf[len - 1] == '\n')
+        buf[len - 1] = 0;
+    else
+        buf[len] = 0;
+
+    /* Try to convert pid to int */
+    return (atoi(buf));
+}
+
+static pid_t get_pidof(active_db_h * s)
 {
-    assert(daemon);
-    assert(daemon->name);
-    assert(daemon->current_state);
-    assert(daemon->current_state->state_name);
-    assert(process);
+    pid_t pid;
+    const char *pidof;
+    char *pidof_fixed = NULL;
+
+    pidof = initng_active_db_get_string(&PIDOF, s);
+    if (!pidof)
+        return (-1);
+
+
+    pidof_fixed = fix_variables(pidof, s);
+    if (!pidof_fixed)
+        return (-1);
+
+    pid = pid_of(pidof_fixed);
+    free(pidof_fixed);
+    return (pid);
+}
 
-    D_("handle_killed_start(%s): initial status: \"%s\".\n",
-       daemon->name, daemon->current_state->state_name);
+/* this will get the pid of PIDFILE entry of service */
+static pid_t get_pidfile(active_db_h * s, int warn)
+{
+    pid_t pid;
+    const char *pidfile = NULL;
+    char *pidfile_fixed = NULL;
+
+    /* get the pidfile */
+    while ((pidfile = initng_active_db_get_next_string(&PIDFILE, s, pidfile)))
+    {
+        /* fix the variables in the string */
+        pidfile_fixed = fix_variables(pidfile, s);
+
+        /* check so we got the string */
+        if (!pidfile_fixed)
+            return (-1);
+	    
+	/* make sure the first char is a '/' so its a full path */
+	if(pidfile_fixed[0]!='/')
+	{
+	    F_("The pidfile path %s is not a full path!\n", pidfile_fixed);
+	    return(-1);
+	}
 
-    /* Set the universal variable, that signalize that something happened */
-    initng_global_set_interrupt();
+        /* get the pid from the file */
+        pid = pid_from_file(pidfile_fixed, warn);
+        free(pidfile_fixed);
+
+        /* return the pid */
+        if (pid > 1)
+            return (pid);
+    }
+    return (-1);
+}
 
-    /*
-     * If the return code (for example "exit 1", in a bash script)
-     * from the program, is bigger than 0, this commonly signalize
-     * that something got wrong, print this as an error msg on screen
-     */
-    if (process->r_code > 0)
-        F_(" start %s, Returned with exit %i.\n", daemon->name,
-           process->r_code);
+static void clear_pidfile(active_db_h * s)
+{
+    const char *pidfile = NULL;
 
-    /*
-     * If daemon is stopping, ignore this signal
-     */
-    if (daemon->current_state != &DAEMON_RUN)
+    /* clear this set variable. */
+    initng_active_db_unset(&INTERNAL_GOT_PID, s);
+
+
+    /* ok, search for pidfiles */
+    while ((pidfile =
+                initng_active_db_get_next_string(&PIDFILE, s, pidfile)))
     {
-        F_("Start exited!, and daemon is not marked starting!\n");
-        return;
+        if (pidfile)
+        {
+            if (unlink(pidfile) != 0 && errno != ENOENT)
+            {
+                    F_("Could not remove stale pidfile %s\n", pidfile);
+                    return;
+            }
+        }
     }
+}
+
 
+#ifdef THIS_IS_DISABLED
+static void handle_STOPPED(active_db_h * daemon_stopped)
+{
+    active_db_h *current, *safe = NULL;
 
     /*
-     * Make sure r_code don't signal error (can be override by UP_ON_FAILURE.
+     * Make sure there is no daemons that needs this
+     * that still think its running.
      */
-     
-     /*   TODO              MAKE UP_ON_FAILURE more universal */
-    if (process->r_code && !initng_active_db_is(&UP_ON_FAILURE, daemon))
+    while_active_db_safe(current, safe)
     {
+        /* no idea to stop myself */
+        if (current == daemon_stopped)
+            continue;
 
-        initng_common_mark_service(daemon, &DAEMON_FAIL_STARTING);
-        list_del(&process->list);
-        initng_process_db_free(process);
+        /* DON'T stop runlevels OR virtuals */
+        if (current->type == &TYPE_VIRTUAL)
+            continue;
+
+        /* check that current needs daemon_stopped */
+        if (initng_depend(current, daemon_stopped) == FALSE)
+            continue;
+
+        /* don't stop a stopped daemon */
+        if (IS_DOWN(current))
+            continue;
+
+        /* if stop this */
+        D_("%s have to stop %s.\n", daemon_stopped->name, current->name);
+        initng_handler_stop_daemon(current);
+    }
+
+    /* check if this daemon is restarting */
+    if (initng_active_db_is(&RESTARTING, daemon_stopped))
+    {
+        initng_active_db_remove(&RESTARTING, daemon_stopped);
+        initng_handler_start_daemon(daemon_stopped);
+        D_("Service is restarting now!\n");
         return;
     }
 
-    /* OK! now daemon is STOPPED! */
-    initng_common_mark_service(daemon, &DAEMON_STOPPED);
 
-    /* free the process struct, to spare memory */
-    list_del(&process->list);
-    initng_process_db_free(process);
+    /* free daemon, and forget */
+    initng_active_db_del(daemon_stopped);
+    initng_active_db_free(daemon_stopped);
+    D_("Service removed.\n");
 }
 
+
+
+
+#endif


More information about the Initng-svn mailing list