]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/dird.c
Fix typo
[bacula/bacula] / bacula / src / dird / dird.c
index 8842bc62677abd99767c82b57b15c6959b17cec3..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 */
@@ -45,13 +45,14 @@ int do_backup(JCR *jcr);
 void backup_cleanup(void);
 void start_UA_server(char *addr, int port);
 void init_job_server(int max_workers);
-void store_jobtype(LEX *lc, struct res_items *item, int index, int pass);
-void store_level(LEX *lc, struct res_items *item, int index, int pass);
-void store_replace(LEX *lc, struct res_items *item, int index, int pass);
+void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
+void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
+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,7 +61,8 @@ int SDConnectTimeout;
 
 /* Globals Imported */
 extern int r_first, r_last;          /* first and last resources */
-extern struct res_items job_items[];
+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) {
@@ -208,10 +211,11 @@ int main (int argc, char *argv[])
 
    /* Create pid must come after we are a daemon -- so we have our final pid */
    create_pid_file(director->pid_directory, "bacula-dir", director->DIRport);
+   read_state_file(director->working_directory, "bacula-dir", director->DIRport);
 
    drop(uid, gid);                   /* reduce priveleges if requested */
 
-/* signal(SIGHUP, reload_config); */
+   signal(SIGHUP, reload_config);
 
    init_console_msg(working_directory);
 
@@ -249,8 +253,8 @@ static void terminate_dird(int sig)
       exit(1);
    }
    already_here = TRUE;
-   delete_pid_file(director->pid_directory, "bacula-dir",  
-                  director->DIRport);
+   write_state_file(director->working_directory, "bacula-dir", director->DIRport);
+   delete_pid_file(director->pid_directory, "bacula-dir", director->DIRport);
 // signal(SIGCHLD, SIG_IGN);          /* don't worry about children now */
    term_scheduler();
    if (runjob) {
@@ -268,46 +272,150 @@ static void terminate_dird(int sig)
    stop_watchdog();
    close_memory_pool();              /* release free memory in pool */
    sm_dump(False);
-   exit(sig != 0);
+   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 int already_here = FALSE;
+   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);
 
-   free_config_resources();
+   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->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);
+   }
+   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(200, "check_resources()\n");
+   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 */
    set_working_directory(director->working_directory);
    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();
+   unlock_jcr_chain();
    sigprocmask(SIG_UNBLOCK, &set, NULL);
    signal(SIGHUP, reload_config);
-   already_here = FALSE;
-   Dmsg0(0, "Director's configuration file reread.\n");
+   already_here = false;
 }
 
 /*