]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/dird.c
Fix typo
[bacula/bacula] / bacula / src / dird / dird.c
index 34aecc0e5a1ca5fc19569eb211b74b9a688a73ee..c09721b6b08d46f6898de0297dd8b9336f8687d7 100644 (file)
@@ -32,9 +32,9 @@
 /* Forward referenced subroutines */
 static void terminate_dird(int sig);
 static int check_resources();
-static void reload_config(int sig);
 
 /* Exported subroutines */
+void reload_config(int sig);
 
 
 /* Imported subroutines */
@@ -52,6 +52,7 @@ void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
 static char *configfile = NULL;
 static char *runjob = NULL;
 static int background = 1;
+static void init_reload(void);
 
 /* Globals Exported */
 DIRRES *director;                    /* Director resource */
@@ -60,6 +61,7 @@ int SDConnectTimeout;
 
 /* Globals Imported */
 extern int r_first, r_last;          /* first and last resources */
+extern RES_TABLE resources[];
 extern RES_ITEM job_items[];
 extern URES res_all;
 
@@ -105,6 +107,7 @@ int main (int argc, char *argv[])
    my_name_is(argc, argv, "bacula-dir");
    textdomain("bacula-dir");
    init_msg(NULL, NULL);             /* initialize message handler */
+   init_reload();
    daemon_start_time = time(NULL);
 
    while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
@@ -272,46 +275,130 @@ static void terminate_dird(int sig)
    exit(sig);
 }
 
+struct RELOAD_TABLE {
+   int job_count;
+   RES **res_table;
+};
+
+static const int max_reloads = 10;
+static RELOAD_TABLE reload_table[max_reloads];
+
+static void init_reload(void) 
+{
+   for (int i=0; i < max_reloads; i++) {
+      reload_table[i].job_count = 0;
+      reload_table[i].res_table = NULL;
+   }
+}
+
+static void free_saved_resources(int table)
+{
+   int num = r_last - r_first + 1;
+   RES **res_tab = reload_table[table].res_table;
+   Dmsg1(000, "Freeing resources for table %d\n", table);
+   for (int j=0; j<num; j++) {
+      free_resource(res_tab[j], r_first + j);
+   }
+   free(res_tab);
+   reload_table[table].job_count = 0;
+   reload_table[table].res_table = NULL;
+}
+
+/*
+ * Called here at the end of every job that was
+ * hooked decrementing the active job_count. When
+ * it goes to zero, no one is using the associated
+ * resource table, so free it.
+ */
+static void reload_job_end_cb(JCR *jcr)
+{
+   int i = jcr->reload_id - 1;
+   Dmsg1(000, "reload job_end JobId=%d\n", jcr->JobId);
+   lock_jcr_chain();
+   LockRes();
+   if (--reload_table[i].job_count <= 0) {
+      free_saved_resources(i);
+   }
+   UnlockRes();
+   unlock_jcr_chain();
+}
+
+static int find_free_table()
+{
+   int table = -1;
+   for (int i=0; i < max_reloads; i++) {
+      if (reload_table[i].res_table == NULL) {
+        table = i;
+        break;
+      }
+   }
+   return table;
+}
+
 /*
  * If we get here, we have received a SIGHUP, which means to
- * reread our configuration file. 
- *
- *  ***FIXME***  Check that there are no jobs running before
- *              doing this. 
+ *    reread our configuration file. 
  */
-static void reload_config(int sig)
+void reload_config(int sig)
 {
    static bool already_here = false;
    sigset_t set;       
    JCR *jcr;
    int njobs = 0;
+   int table, rtable;
 
    if (already_here) {
       abort();                       /* Oops, recursion -> die */
    }
-   already_here = TRUE;
+   already_here = true;
    sigfillset(&set);
    sigprocmask(SIG_BLOCK, &set, NULL);
 
    lock_jcr_chain();
    LockRes();
 
+   table = find_free_table();
+   if (table < 0) {
+      Jmsg(NULL, M_ERROR, 0, _("Too many reload requests.\n"));
+      goto bail_out;
+   }
+
+   /*
+    * Hook all active jobs that are not already hooked (i.e.
+    *  reload_id == 0
+    */
    foreach_jcr(jcr) {
-      if (jcr->JobId != 0) {     /* this is a console */
+      if (jcr->reload_id == 0) {
+        reload_table[table].job_count++;
+        jcr->reload_id = table + 1;
+        job_end_push(jcr, reload_job_end_cb);
         njobs++;
       }
       free_locked_jcr(jcr);
    }
-   if (njobs > 0) {
-      goto bail_out;
-   }
-
-   free_config_resources();
+   Dmsg1(000, "Reload_config njobs=%d\n", njobs);
+   reload_table[table].res_table = save_config_resources();
+   Dmsg1(000, "Saved old config in table %d\n", table);
 
+   Dmsg0(000, "Calling parse config\n");
    parse_config(configfile);
 
+   Dmsg0(000, "Reloaded config file\n");
    if (!check_resources()) {
-      Jmsg(NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
+      rtable = find_free_table();     /* save new, bad table */
+      if (rtable < 0) {
+         Jmsg(NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile);
+      } else {
+         Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
+      }
+      reload_table[rtable].res_table = save_config_resources();
+      /* Now restore old resoure values */
+      int num = r_last - r_first + 1;
+      RES **res_tab = reload_table[table].res_table;
+      for (int i=0; i<num; i++) {
+        resources[i].res_head = res_tab[i];
+      }
+      table = rtable;                /* release new, bad, saved table below */
    }
 
    /* Reset globals */
@@ -319,6 +406,9 @@ static void reload_config(int sig)
    FDConnectTimeout = director->FDConnectTimeout;
    SDConnectTimeout = director->SDConnectTimeout;
    Dmsg0(0, "Director's configuration file reread.\n");
+       
+   /* Now release saved resources */
+   free_saved_resources(table);
 
 bail_out:
    UnlockRes();