]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/dird.c
!!! I didn't run the regression tests.!!!
[bacula/bacula] / bacula / src / dird / dird.c
index e866dcfad121afc69072ab2e3aea319ca5b579f1..be64a25307f1c10adee67b3c955b30a76ef0f131 100644 (file)
@@ -44,8 +44,9 @@ void term_scheduler();
 void term_ua_server();
 int do_backup(JCR *jcr);
 void backup_cleanup(void);
-void start_UA_server(char *addr, int port);
+void start_UA_server(dlist *addrs);
 void init_job_server(int max_workers);
+void term_job_server();
 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);
@@ -63,6 +64,7 @@ int SDConnectTimeout;
 /* Globals Imported */
 extern int r_first, r_last;          /* first and last resources */
 extern RES_TABLE resources[];
+extern RES **res_head;
 extern RES_ITEM job_items[];
 extern URES res_all;
 
@@ -72,6 +74,7 @@ extern URES res_all;
 static void usage()
 {
    fprintf(stderr, _(
+"Copyright (C) 2000-2004 Kern Sibbald and John Walker\n"
 "\nVersion: " VERSION " (" BDATE ")\n\n"
 "Usage: dird [-f -s] [-c config_file] [-d debug_level] [config_file]\n"
 "       -c <file>   set configuration file to file\n"
@@ -211,8 +214,8 @@ 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);
+   create_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
+   read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
 
    drop(uid, gid);                   /* reduce priveleges if requested */
 
@@ -224,7 +227,7 @@ int main (int argc, char *argv[])
       4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
 
    Dmsg0(200, "Start UA server\n");
-   start_UA_server(director->DIRaddr, director->DIRport);
+   start_UA_server(director->DIRaddrs);
 
    start_watchdog();                 /* start network watchdog thread */
 
@@ -254,10 +257,11 @@ static void terminate_dird(int sig)
       exit(1);
    }
    already_here = TRUE;
-   write_state_file(director->working_directory, "bacula-dir", director->DIRport);
-   delete_pid_file(director->pid_directory, "bacula-dir", director->DIRport);
+   write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
+   delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs));
 // signal(SIGCHLD, SIG_IGN);          /* don't worry about children now */
    term_scheduler();
+   term_job_server();
    if (runjob) {
       free(runjob);
    }
@@ -297,10 +301,10 @@ static void free_saved_resources(int table)
    int num = r_last - r_first + 1;
    RES **res_tab = reload_table[table].res_table;
    if (!res_tab) {
-      Dmsg1(000, "res_tab for table %d already released.\n", table);
+      Dmsg1(100, "res_tab for table %d already released.\n", table);
       return;
    }
-   Dmsg1(000, "Freeing resources for table %d\n", table);
+   Dmsg1(100, "Freeing resources for table %d\n", table);
    for (int j=0; j<num; j++) {
       free_resource(res_tab[j], r_first + j);
    }
@@ -315,18 +319,15 @@ static void free_saved_resources(int table)
  * it goes to zero, no one is using the associated
  * resource table, so free it.
  */
-static void reload_job_end_cb(JCR *jcr)
+static void reload_job_end_cb(JCR *jcr, void *ctx)
 {
-   if (jcr->reload_id == 0) {
-      return;                        /* nothing to do */
-   }
-   int i = jcr->reload_id - 1;
-   Dmsg3(000, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
-      i, reload_table[i].job_count);
+   int reload_id = (int)((long int)ctx);
+   Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
+      reload_id, reload_table[reload_id].job_count);
    lock_jcr_chain();
    LockRes();
-   if (--reload_table[i].job_count <= 0) {
-      free_saved_resources(i);
+   if (--reload_table[reload_id].job_count <= 0) {
+      free_saved_resources(reload_id);
    }
    UnlockRes();
    unlock_jcr_chain();
@@ -347,6 +348,21 @@ static int find_free_reload_table_entry()
 /*
  * If we get here, we have received a SIGHUP, which means to
  *    reread our configuration file. 
+ *
+ * The algorithm used is as follows: we count how many jobs are
+ *   running and mark the running jobs to make a callback on 
+ *   exiting. The old config is saved with the reload table
+ *   id in a reload table. The new config file is read. Now, as
+ *   each job exits, it calls back to the reload_job_end_cb(), which
+ *   decrements the count of open jobs for the given reload table.
+ *   When the count goes to zero, we release those resources.
+ *   This allows us to have pointers into the resource table (from
+ *   jobs), and once they exit and all the pointers are released, we
+ *   release the old table. Note, if no new jobs are running since the
+ *   last reload, then the old resources will be immediately release.
+ *   A console is considered a job because it may have pointers to
+ *   resources, but a SYSTEM job is not since it *should* not have any
+ *   permanent pointers to jobs.
  */
 extern "C"
 void reload_config(int sig)
@@ -354,7 +370,7 @@ void reload_config(int sig)
    static bool already_here = false;
    sigset_t set;       
    JCR *jcr;
-   int njobs = 0;
+   int njobs = 0;                    /* number of running jobs */
    int table, rtable;
 
    if (already_here) {
@@ -376,27 +392,13 @@ void reload_config(int sig)
       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 && jcr->JobType != JT_SYSTEM) {
-        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);
+   Dmsg1(100, "Reload_config njobs=%d\n", njobs);
    reload_table[table].res_table = save_config_resources();
-   Dmsg1(000, "Saved old config in table %d\n", table);
+   Dmsg1(100, "Saved old config in table %d\n", table);
 
-   Dmsg0(000, "Calling parse config\n");
    parse_config(configfile);
 
-   Dmsg0(000, "Reloaded config file\n");
+   Dmsg0(100, "Reloaded config file\n");
    if (!check_resources()) {
       rtable = find_free_reload_table_entry();   /* save new, bad table */
       if (rtable < 0) {
@@ -410,18 +412,21 @@ void reload_config(int sig)
       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];
+        res_head[i] = res_tab[i];
       }
       table = rtable;                /* release new, bad, saved table below */
-      if (njobs != 0) {
-        foreach_jcr(jcr) {
-           if (jcr->reload_id == table) {
-              jcr->reload_id = 0;
-           }
-           free_locked_jcr(jcr);
+   } else {
+      /*
+       * Hook all active jobs so that they release this table 
+       */
+      foreach_jcr(jcr) {
+        if (jcr->JobType != JT_SYSTEM) {
+           reload_table[table].job_count++;
+           job_end_push(jcr, reload_job_end_cb, (void *)((long int)table));
+           njobs++;
         }
+        free_locked_jcr(jcr);
       }
-      njobs = 0;                     /* force bad tabel to be released below */
    }
 
    /* Reset globals */
@@ -514,7 +519,7 @@ Without that I don't know who I am :-(\n"), configfile);
                       job->hdr.name, job_items[i].name, *def_svalue, i, offset);
                  svalue = (char **)((char *)job + offset);
                  if (*svalue) {
-                     Dmsg1(000, "Hey something is wrong. p=0x%lu\n", *svalue);
+                     Pmsg1(000, "Hey something is wrong. p=0x%lu\n", *svalue);
                  }
                  *svalue = bstrdup(*def_svalue);
                  set_bit(i, job->hdr.item_present);
@@ -524,7 +529,7 @@ Without that I don't know who I am :-(\n"), configfile);
                       job->hdr.name, job_items[i].name, i, offset);
                  svalue = (char **)((char *)job + offset);
                  if (*svalue) {
-                     Dmsg1(000, "Hey something is wrong. p=0x%lu\n", *svalue);
+                     Pmsg1(000, "Hey something is wrong. p=0x%lu\n", *svalue);
                  }
                  *svalue = *def_svalue;
                  set_bit(i, job->hdr.item_present);
@@ -576,59 +581,62 @@ Without that I don't know who I am :-(\n"), configfile);
             Emsg0(M_ERROR_TERM, 0, "Too many items in Job resource\n");
         }
       }
-      if (job->client && job->client->catalog) {
-        CAT *catalog = job->client->catalog;
-        B_DB *db;
-
-        /*
-         * Make sure we can open catalog, otherwise print a warning
-         * message because the server is probably not running.
-         */
-        db = db_init_database(NULL, catalog->db_name, catalog->db_user,
-                           catalog->db_password, catalog->db_address,
-                           catalog->db_port, catalog->db_socket);
-        if (!db || !db_open_database(NULL, db)) {
-            Jmsg(NULL, M_FATAL, 0, _("Could not open database \"%s\".\n"),
-                catalog->db_name);
-           if (db) {
-               Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
-           }
-           OK = false;
-        } else {
-           /* If a pool is defined for this job, create the pool DB       
-            *  record if it is not already created. 
-            */
-           if (job->pool) {
-              create_pool(NULL, db, job->pool, POOL_OP_UPDATE);  /* update request */
+   } /* End loop over Job res */
+
+   /* Loop over databases */
+   CAT *catalog;
+   foreach_res(catalog, R_CATALOG) {
+      B_DB *db;
+      /*
+       * Make sure we can open catalog, otherwise print a warning
+       * message because the server is probably not running.
+       */
+      db = db_init_database(NULL, catalog->db_name, catalog->db_user,
+                        catalog->db_password, catalog->db_address,
+                        catalog->db_port, catalog->db_socket);
+      if (!db || !db_open_database(NULL, db)) {
+         Jmsg(NULL, M_FATAL, 0, _("Could not open database \"%s\".\n"),
+             catalog->db_name);
+        if (db) {
+            Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
+        }
+        OK = false;
+        continue;
+      } 
+
+      /* Loop over all pools, defining/updating them in each database */
+      POOL *pool;
+      foreach_res(pool, R_POOL) {
+        create_pool(NULL, db, pool, POOL_OP_UPDATE);  /* update request */
+      }      
+      /* Loop over all counters, defining them in each database */
+
+      /* Set default value in all counters */
+      COUNTER *counter;
+      foreach_res(counter, R_COUNTER) {
+        /* Write to catalog? */
+        if (!counter->created && counter->Catalog == catalog) {
+           COUNTER_DBR cr;
+           bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter));
+           cr.MinValue = counter->MinValue;
+           cr.MaxValue = counter->MaxValue;
+           cr.CurrentValue = counter->MinValue;
+           if (counter->WrapCounter) {
+              bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter));
+           } else {
+              cr.WrapCounter[0] = 0;  /* empty string */
            }
-           /* Set default value in all counters */
-           COUNTER *counter;
-           foreach_res(counter, R_COUNTER) {
-              /* Write to catalog? */
-              if (!counter->created && counter->Catalog == catalog) {
-                 COUNTER_DBR cr;
-                 bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter));
-                 cr.MinValue = counter->MinValue;
-                 cr.MaxValue = counter->MaxValue;
-                 cr.CurrentValue = counter->MinValue;
-                 if (counter->WrapCounter) {
-                    bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter));
-                 } else {
-                    cr.WrapCounter[0] = 0;  /* empty string */
-                 }
-                 if (db_create_counter_record(NULL, db, &cr)) {
-                    counter->CurrentValue = cr.CurrentValue;
-                    counter->created = true;
-                     Dmsg2(100, "Create counter %s val=%d\n", counter->hdr.name, counter->CurrentValue);
-                 }
-              } 
-              if (!counter->created) {
-                 counter->CurrentValue = counter->MinValue;  /* default value */
-              }
+           if (db_create_counter_record(NULL, db, &cr)) {
+              counter->CurrentValue = cr.CurrentValue;
+              counter->created = true;
+               Dmsg2(100, "Create counter %s val=%d\n", counter->hdr.name, counter->CurrentValue);
            }
+        } 
+        if (!counter->created) {
+           counter->CurrentValue = counter->MinValue;  /* default value */
         }
-        db_close_database(NULL, db);
       }
+      db_close_database(NULL, db);
    }
 
    UnlockRes();