Added HUP support. As it happens, it's also thread-safe.
authoraland <aland>
Mon, 12 Nov 2007 14:07:09 +0000 (14:07 +0000)
committeraland <aland>
Mon, 12 Nov 2007 14:07:09 +0000 (14:07 +0000)
All it does is re-initialize modules that are flagged as
"safe for HUP".  Right now, only the "files" module is flagged
 like this, but it's easy enough to flag other modules, too.

In the future, we may want to examine the ability to reload
policies, etc.  This MAY be possible, if the policies are
contained in one file....

src/include/conffile.h
src/include/modules.h
src/main/conffile.c
src/main/modules.c
src/main/radiusd.c
src/modules/rlm_files/rlm_files.c

index 26ba12e..353f2f6 100644 (file)
@@ -54,6 +54,7 @@ int           cf_item_parse(CONF_SECTION *cs, const char *name,
                              int type, void *data, const char *dflt);
 int            cf_section_parse(CONF_SECTION *, void *base,
                                 const CONF_PARSER *variables);
+void           cf_section_parse_free(CONF_SECTION *cs, void *base);
 CONF_SECTION   *cf_file_read(const char *file);
 int            cf_file_include(const char *file, CONF_SECTION *cs);
 
index 9f019e4..4727ed2 100644 (file)
@@ -30,6 +30,7 @@ enum {
 #define RLM_TYPE_THREAD_SAFE           (0 << 0)
 #define RLM_TYPE_THREAD_UNSAFE         (1 << 0)
 #define RLM_TYPE_CHECK_CONFIG_SAFE     (1 << 1)
+#define RLM_TYPE_HUP_SAFE              (1 << 2)
 
 #define RLM_MODULE_MAGIC_NUMBER ((uint32_t) (0xf4ee4ad2))
 #define RLM_MODULE_INIT RLM_MODULE_MAGIC_NUMBER
@@ -58,6 +59,7 @@ enum {
 
 int setup_modules(int, CONF_SECTION *);
 int detach_modules(void);
+int module_hup(CONF_SECTION *modules);
 int module_authorize(int type, REQUEST *request);
 int module_authenticate(int type, REQUEST *request);
 int module_preacct(REQUEST *request);
index 689022e..059ad18 100644 (file)
@@ -264,9 +264,10 @@ static int data_cmp(const void *a, const void *b)
 /*
  *     Free strings we've parsed into data structures.
  */
-static void cf_section_parse_free(void *base, const CONF_PARSER *variables)
+void cf_section_parse_free(CONF_SECTION *cs, void *base)
 {
        int i;
+       const CONF_PARSER *variables = cs->variables;
 
        /*
         *      Don't automatically free the strings if we're being
@@ -322,9 +323,7 @@ void cf_section_free(CONF_SECTION **cs)
 
        if (!cs || !*cs) return;
 
-       if ((*cs)->variables) {
-               cf_section_parse_free((*cs)->base, (*cs)->variables);
-       }
+       cf_section_parse_free(*cs, (*cs)->base);
 
        for (ci = (*cs)->children; ci; ci = next) {
                next = ci->next;
@@ -960,6 +959,8 @@ int cf_section_parse(CONF_SECTION *cs, void *base,
        int i;
        void *data;
 
+       cs->variables = variables; /* this doesn't hurt anything */
+
        if (!cs->name2) {
                DEBUG2("%.*s%s {", cs->depth, parse_spaces,
                       cs->name1);
@@ -1021,13 +1022,12 @@ int cf_section_parse(CONF_SECTION *cs, void *base,
        DEBUG2("%.*s}", cs->depth, parse_spaces);
 
        cs->base = base;
-       cs->variables = variables;
 
        return 0;
 
  error:
        DEBUG2("%.*s}", cs->depth, parse_spaces);
-       cf_section_parse_free(base, variables);
+       cf_section_parse_free(cs, base);
        return -1;
 }
 
index e2a3ad6..c6f214a 100644 (file)
@@ -763,6 +763,62 @@ static int load_byserver(CONF_SECTION *cs)
        return 0;
 }
 
+
+int module_hup(CONF_SECTION *modules)
+{
+       CONF_ITEM *ci;
+       CONF_SECTION *cs;
+       module_instance_t *node;
+
+       if (!modules) return 0;
+
+       /*
+        *      Loop over the modules
+        */
+       for (ci=cf_item_find_next(modules, NULL);
+            ci != NULL;
+            ci=cf_item_find_next(modules, ci)) {
+               void *insthandle = NULL;
+               void *old_insthandle = NULL;
+
+               /*
+                *      If it's not a section, ignore it.
+                */
+               if (!cf_item_is_section(ci)) continue;
+
+               cs = cf_itemtosection(ci);
+
+               node = cf_data_find(cs, "instance");
+               if (!node ||
+                   ((node->entry->module->type & RLM_TYPE_HUP_SAFE) == 0)) {
+                       continue;
+               }
+
+               DEBUG2(" Module: Trying to reload module \"%s\"", node->name);
+
+               if ((node->entry->module->instantiate)(cs, &insthandle) < 0) {
+                       cf_log_err(cf_sectiontoitem(cs),
+                                  "HUP failed for module \"%s\"",
+                                  node->name);
+                       continue;
+               }
+
+               radlog(L_INFO, " Module: Reloaded module \"%s\"", node->name);
+
+               old_insthandle = node->insthandle;
+               node->insthandle = insthandle;
+
+               cf_section_parse_free(cs, old_insthandle);
+
+               if (node->entry->module->detach) {
+                       (node->entry->module->detach)(old_insthandle);
+               }
+       }
+
+       return 1;
+}
+
+
 /*
  *     Parse the module config sections, and load
  *     and call each module's init() function.
index 195a0e4..73595b6 100644 (file)
@@ -430,13 +430,7 @@ int main(int argc, char *argv[])
         *      Process requests until HUP or exit.
         */
        while ((rcode = radius_event_process()) == 0x80) {
-               thread_pool_lock();
-               /*
-                *      Reload anything that can safely be reloaded.
-                */
-               DEBUG("HUP support not available.");
-
-               thread_pool_unlock();
+               module_hup(cf_section_sub_find(mainconfig.config, "modules"));
        }
        
        DEBUG("Exiting...");
index f92aae8..3c78c85 100644 (file)
@@ -567,7 +567,7 @@ static int file_postauth(void *instance, REQUEST *request)
 module_t rlm_files = {
        RLM_MODULE_INIT,
        "files",
-       RLM_TYPE_CHECK_CONFIG_SAFE,     /* type: reserved */
+       RLM_TYPE_CHECK_CONFIG_SAFE | RLM_TYPE_HUP_SAFE,
        file_instantiate,               /* instantiation */
        file_detach,                    /* detach */
        {