[Initng-svn] r2935 - in initng: plugins/reload plugins/stcmd src

svn at initng.thinktux.net svn at initng.thinktux.net
Sat Feb 4 00:28:00 CET 2006


Author: makomk
Date: Sat Feb  4 00:27:59 2006
New Revision: 2935

Modified:
   initng/plugins/reload/initng_reload.c
   initng/plugins/reload/initng_reload.h
   initng/plugins/stcmd/initng_stcmd.c
   initng/src/initng_global.c
   initng/src/initng_global.h
   initng/src/initng_plugin.h
   initng/src/initng_plugin_callers.c
   initng/src/initng_plugin_callers.h
   initng/src/main.c
Log:
Restructure reload support somewhat - create a framework for it in initng core. Should 
allow better error handling and support for multiple reload plugins. Plus, since all the 
modules are loaded before the active_db is reloaded, it actually *works* again.


Modified: initng/plugins/reload/initng_reload.c
==============================================================================
--- initng/plugins/reload/initng_reload.c	(original)
+++ initng/plugins/reload/initng_reload.c	Sat Feb  4 00:27:59 2006
@@ -44,13 +44,8 @@
 #define SAVE_FILE      VARDIR "/initng_db_backup.v12"
 #define SAVE_FILE_FAKE VARDIR "/initng_db_backup_fake.v12"
 
-s_command FAST_RELOAD = { 'c', "hot_reload", VOID_COMMAND, STANDARD_COMMAND, NO_OPT,
-    {(void *) &cmd_fast_reload},
-    "Fast Reload"
-};
-
-static void write_file(const char *filename);
-static void read_file(const char *filename);
+static int write_file(const char *filename);
+static int read_file(const char *filename);
 
 const char *module_needs[] = {
     "rlparser",
@@ -58,9 +53,11 @@
     NULL
 };
 
+/* FIXME - not all errors are detected, in some cases success could be 
+   reported incorrectly */
 static void read_file(const char *filename)
 {
-    FILE *fil;
+    FILE *fil; int success = TRUE;
 
     fil = fopen(filename, "r");
 
@@ -74,7 +71,7 @@
         data_save_struct entry;
 
         if (!fread(&entry, sizeof(entry), 1, fil))
-            continue;
+            success = FALSE; continue;
 
         if (initng_active_db_find_by_name(entry.name))
         {
@@ -86,7 +83,7 @@
         if (!(new_entry = initng_active_db_new(entry.name)))
         {
             F_("Can't create new active!\n");
-            continue;
+            success = FALSE; continue;
         }
 
         /* set current_state */
@@ -101,7 +98,7 @@
         if (!(new_entry->type = initng_service_types_get(entry.type)))
         {
             F_("Unkown service type %s.\n", entry.type);
-            continue;
+            success = FALSE; continue;
         }
 
         /* set time_current_state */
@@ -191,7 +188,7 @@
         {
             F_("Could not add entry!\n");
             initng_active_db_free(new_entry);
-            continue;
+            success = FALSE; continue;
         }
 
         /* Dont need to reload data from disk, loaded when needed
@@ -205,10 +202,12 @@
     if (unlink(filename) != 0)
     {
         W_("Failed removing file %s !!!\n", filename);
-        return;
+        return success; /* not important */
     }
+
+    return success; 
 }
-static void write_file(const char *filename)
+static int write_file(const char *filename)
 {
     FILE *fil;
     active_db_h *current, *q = NULL;
@@ -217,12 +216,13 @@
     int i;
     int pnr = 0;
     s_data *c_d = NULL;
+    int success = TRUE;
 
     fil = fopen(filename, "w+");
     if (!fil)
     {
         F_("Could not open '%s' for writing\n", filename);
-        return;
+        return FALSE;
     }
 
     /* walk the active_db */
@@ -237,7 +237,7 @@
         if (strlen(current->name) >= MAX_SERVICE_NAME_STRING_LEN)
         {
             F_("Service name is to long, it won't fit the fileformat spec! max is %i, won't save this service!\n", MAX_SERVICE_NAME_STRING_LEN);
-            continue;
+            success = FALSE; continue;
         }
 
         memset(&entry, 0, sizeof entry);
@@ -308,7 +308,7 @@
             if (i == MAX_ENTRYS_FOR_SERVICE)
             {
                 F_("Maximum 20 data entries / service can't be saved!\n");
-                break;
+                success = FALSE; break;
             }
         }
 
@@ -317,36 +317,45 @@
         {
             F_("failed to write entry '%s': %m\n", entry.name);
             /* TODO: database recovery?? */
-            break;
+            success = FALSE; break;
         }
     }
 
     fclose(fil);
-
+    return success;
 }
 
-static void cmd_fast_reload(char *arg, FILE * fd)
+static int dump_state(void) 
 {
-    (void) arg;
-    char *new_argv[4];
-
+    int retval; 
     if (g.i_am_init)
     {
-        write_file(SAVE_FILE);
+        retval = write_file(SAVE_FILE);
     }
     else
     {
-        write_file(SAVE_FILE_FAKE);
-        _exit(0);
+        retval = write_file(SAVE_FILE_FAKE);
     }
+    return retval ? TRUE : FAIL;
+}
 
-    new_argv[0] = i_strdup("/sbin/initng");
-    new_argv[1] = i_strdup("--hot_reload");
-    new_argv[2] = NULL;
-
-    execve("/sbin/initng", new_argv, environ);
-    F_("Failed to reload initng!\n");
-
+static int reload_state(void) 
+{
+    struct stat st;
+    if(stat( g.i_am_init ? SAVE_FILE : SAVE_FILE_FAKE, &st))
+    {
+	D_("No state file found, passing on reload_state request\n");
+	return FALSE;
+    }
+    if (g.i_am_init)
+    {
+        read_file(SAVE_FILE);
+    }
+    else
+    {
+        read_file(SAVE_FILE_FAKE);
+    }
+    return TRUE;
 }
 
 /* Save a reload file for backup if initng segfaults */
@@ -392,7 +401,7 @@
         return (FALSE);
     }
 
-    if (g.hot_reload)
+    /*    if (g.hot_reload)
     {
         if (g.i_am_init)
         {
@@ -402,16 +411,16 @@
         {
             read_file(SAVE_FILE_FAKE);
         }
-    }
+	} */
 
-    initng_command_add(&FAST_RELOAD);
     initng_plugin_hook_add(&g.SWATCHERS, 90, &save_backup);
+    initng_plugin_hook_add(&g.DUMP_STATE, 10, &dump_state);
+    initng_plugin_hook_add(&g.RELOAD_STATE, 10, &reload_state);
     return (TRUE);
 }
 
 void module_unload(void)
 {
     D_("module_unload();\n");
-    initng_command_del(&FAST_RELOAD);
     initng_plugin_hook_del(&g.SWATCHERS, &save_backup);
 }

Modified: initng/plugins/reload/initng_reload.h
==============================================================================
--- initng/plugins/reload/initng_reload.h	(original)
+++ initng/plugins/reload/initng_reload.h	Sat Feb  4 00:27:59 2006
@@ -20,9 +20,6 @@
 
 #include "../../src/initng_control_command.h"
 
-static void cmd_fast_reload(char *arg, FILE * fd);
-
-
 /* Warning.
  * Changing these variables, will make reload incompatible,
  * and probably hang initng
@@ -34,7 +31,6 @@
 #define MAX_PTYPE_STRING_LEN 100
 #define MAX_ENTRYS_FOR_SERVICE 20
 
-extern s_command FAST_RELOAD;
 typedef struct
 {
     char type[MAX_TYPE_STRING_LEN + 1];

Modified: initng/plugins/stcmd/initng_stcmd.c
==============================================================================
--- initng/plugins/stcmd/initng_stcmd.c	(original)
+++ initng/plugins/stcmd/initng_stcmd.c	Sat Feb  4 00:27:59 2006
@@ -56,6 +56,7 @@
 #include "print_service.h"
 
 
+static void cmd_fast_reload(char *arg, FILE * fd);
 static int cmd_get_pid_of(char *arg);
 static int cmd_start_on_new(char *arg);
 static int cmd_free_service(char *arg);
@@ -85,7 +86,10 @@
 static int cmd_del_verbose(char *arg);
 #endif
 
-
+s_command FAST_RELOAD = { 'c', "hot_reload", VOID_COMMAND, STANDARD_COMMAND, NO_OPT,
+    {(void *) &cmd_fast_reload},
+    "Fast Reload"
+};
 s_command GET_PID_OF = { 'g', "get_pid_of", INT_COMMAND, ADVANCHED_COMMAND, REQUIRES_OPT,
     {(void *) &cmd_get_pid_of}, "Get pid of service"
 };
@@ -239,7 +243,29 @@
 }
 
 
+static void cmd_fast_reload(char *arg, FILE * fd)
+{
+    (void) arg; int retval; char *new_argv[4];
 
+    retval = initng_plugin_callers_dump_state();
+    
+    if(retval == TRUE)
+    {
+	D_("exec()int initng\n");
+	new_argv[0] = i_strdup("/sbin/initng");
+	new_argv[1] = i_strdup("--hot_reload");
+	new_argv[2] = NULL;
+
+	execve("/sbin/initng", new_argv, environ);
+	F_("Failed to reload initng!\n");
+    } 
+    else
+    {
+	if(retval == FALSE)
+	    F_("No plugin was willing to dump state\n");
+	else F_("dump_state failed!\n");
+    }
+}
 
 static int cmd_start_on_new(char *arg)
 {
@@ -710,6 +736,7 @@
         return (FALSE);
     }
 
+    initng_command_add(&FAST_RELOAD);
     initng_command_add(&GET_PID_OF);
     initng_command_add(&START_ON_NEW);
     initng_command_add(&FREE_SERVICE);
@@ -754,6 +781,7 @@
 {
     D_("module_unload(stcmd);\n");
 
+    initng_command_del(&FAST_RELOAD);
     initng_command_del(&GET_PID_OF);
     initng_command_del(&START_ON_NEW);
     initng_command_del(&FREE_SERVICE);

Modified: initng/src/initng_global.c
==============================================================================
--- initng/src/initng_global.c	(original)
+++ initng/src/initng_global.c	Sat Feb  4 00:27:59 2006
@@ -104,6 +104,8 @@
     INIT_LIST_HEAD(&g.LAUNCH.list);
     INIT_LIST_HEAD(&g.DEP_ON.list);
     INIT_LIST_HEAD(&g.ADDITIONAL_PARSE.list);
+    INIT_LIST_HEAD(&g.DUMP_STATE.list);
+    INIT_LIST_HEAD(&g.RELOAD_STATE.list);
 
 
     /*

Modified: initng/src/initng_global.h
==============================================================================
--- initng/src/initng_global.h	(original)
+++ initng/src/initng_global.h	Sat Feb  4 00:27:59 2006
@@ -73,6 +73,8 @@
     s_call LAUNCH;
     s_call DEP_ON;
     s_call ADDITIONAL_PARSE;
+    s_call DUMP_STATE;
+    s_call RELOAD_STATE;
 
 
     /* global variables */

Modified: initng/src/initng_plugin.h
==============================================================================
--- initng/src/initng_plugin.h	(original)
+++ initng/src/initng_plugin.h	Sat Feb  4 00:27:59 2006
@@ -53,6 +53,8 @@
     void (*alarm) (void);
     f_module_h *fdh;
     int (*additional_parse) (service_cache_h * service);
+    int (*dump_state) (void);
+    int (*reload_state) (void);
 
 } uc __attribute__ ((__transparent_union__));
 

Modified: initng/src/initng_plugin_callers.c
==============================================================================
--- initng/src/initng_plugin_callers.c	(original)
+++ initng/src/initng_plugin_callers.c	Sat Feb  4 00:27:59 2006
@@ -96,3 +96,60 @@
     }
     return;
 }
+
+/* called to dump active_db */
+int initng_plugin_callers_dump_state(void)
+{
+    s_call *current, *q = NULL; int retval = FALSE;
+
+    while_list_safe(current, &g.DUMP_STATE, q)
+    {
+        if (current->c.dump_state)
+        {
+            D_("Calling dump_state plugin from %s\n",
+               current->from_file);
+            retval = (*current->c.dump_state) ();
+	    if(retval == TRUE) 
+	    {
+		D_("dump_state plugin from %s succeeded\n",
+		   current->from_file);
+		break;
+	    } 
+	    else if(retval == FAIL) 
+	    {
+		F_("dump_state plugin from %s failed\n", current->from_file);
+		break;
+	    }
+        }
+    }
+    return retval;
+ 
+}
+
+/* called to reload dump of active_db */
+int initng_plugin_callers_reload_state(void)
+{
+    s_call *current, *q = NULL; int retval = FALSE;
+
+    while_list_safe(current, &g.RELOAD_STATE, q)
+    {
+        if (current->c.reload_state)
+        {
+            D_("Calling reload_state plugin from %s\n",
+               current->from_file);
+            retval = (*current->c.reload_state) ();
+	    if(retval == TRUE) 
+	    {
+		D_("reload_state plugin from %s succeeded\n",
+		   current->from_file);
+		break;
+	    } 
+	    else if(retval == FAIL) 
+	    {
+		F_("reload_state plugin from %s failed\n", current->from_file);
+		break;
+	    }
+        }
+    }
+    return retval;
+}

Modified: initng/src/initng_plugin_callers.h
==============================================================================
--- initng/src/initng_plugin_callers.h	(original)
+++ initng/src/initng_plugin_callers.h	Sat Feb  4 00:27:59 2006
@@ -30,4 +30,6 @@
 void initng_plugin_callers_alarm(void);
 
 void initng_plugin_callers_load_module_system_changed(h_sys_state state);
+int initng_plugin_callers_dump_state(void);
+int initng_plugin_callers_reload_state(void);
 #endif

Modified: initng/src/main.c
==============================================================================
--- initng/src/main.c	(original)
+++ initng/src/main.c	Sat Feb  4 00:27:59 2006
@@ -319,6 +319,7 @@
 {
 #endif
     struct timeval last;        /* save the time here */
+    int retval;
 
 #ifdef DEBUG
     int loop_counter = 0;       /* counts how many times the main_loop has run */
@@ -395,6 +396,19 @@
         initng_main_su_login();
     }
 
+    if(g.hot_reload)
+    {
+	retval = initng_plugin_callers_reload_state();
+	if(retval != TRUE) {
+	    if(retval == FALSE)
+		F_("No plugin handled hot_reload!\n");
+	    else F_("Hot reload failed!\n");
+
+	    /* if the hot reload failed, we're probably in big trouble */
+	    initng_main_su_login();
+	}
+    }
+
     /* set title of initng, can be watched in ps -ax */
     initng_toolbox_set_proc_title("initng [%s]", g.runlevel);
 


More information about the Initng-svn mailing list