]> git.sur5r.net Git - bacula/bacula/commitdiff
Finish JobDefs implementation + fix Makefile.in cats directory scripts
authorKern Sibbald <kern@sibbald.com>
Sat, 27 Dec 2003 13:14:12 +0000 (13:14 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 27 Dec 2003 13:14:12 +0000 (13:14 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@957 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/Makefile.in
bacula/src/dird/bacula-dir.conf.in
bacula/src/dird/dird.c
bacula/src/dird/dird_conf.c

index 997d7f986726b440cd892e11bbf1e9bb4359347d..d2a4c677ad6f4b7b0e1afed13573239428496006 100755 (executable)
@@ -122,13 +122,14 @@ Makefiles:
        chmod 755 startmysql stopmysql bacula fd startit stopit btraceback; \
        chmod 755 mtx-changer bconsole gconsole)
 
-       chmod 755 create_bacula_database      update_bacula_tables     make_bacula_tables
-       chmod 755 grant_bacula_privileges     drop_bacula_tables       drop_bacula_database
-
-       chmod 755 create_@DB_NAME@_database   update_@DB_NAME@_tables  make_@DB_NAME@_tables
-       chmod 755 grant_@DB_NAME@_privileges  drop_@DB_NAME@_tables    drop_@DB_NAME@_database
-
-       chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
+       (cd src/cats; \
+       chmod 755 create_bacula_database      update_bacula_tables     make_bacula_tables; \
+       chmod 755 grant_bacula_privileges     drop_bacula_tables       drop_bacula_database; \
+          \
+       chmod 755 create_@DB_NAME@_database   update_@DB_NAME@_tables  make_@DB_NAME@_tables; \
+       chmod 755 grant_@DB_NAME@_privileges  drop_@DB_NAME@_tables    drop_@DB_NAME@_database; \
+          \
+       chmod 755 make_catalog_backup delete_catalog_backup)
 
 clean:
        @for I in ${all_subdirs}; \
index 01ac8dcdeb57e27dee9d4e1c0cd78f19ac801c27..474f6ae97beeeaf8005f0bc6954047e11213cf91 100644 (file)
@@ -23,11 +23,8 @@ Director {                            # define myself
   Messages = Standard
 }
 
-#
-# Define the main nightly save backup job
-#   By default, this job will back up to disk in /tmp
-Job {
-  Name = "Client1"
+JobDefs {
+   Name = "DefaultJob"
   Type = Backup
   Client = @hostname@-fd 
   FileSet = "Full Set"
@@ -35,20 +32,25 @@ Job {
   Storage = File
   Messages = Standard
   Pool = Default
-  Write Bootstrap = "@working_dir@/Client1.bsr"
   Priority = 10
 }
 
+
+#
+# Define the main nightly save backup job
+#   By default, this job will back up to disk in /tmp
+Job {
+  Name = "Client1"
+  JobDefs = "DefaultJob"
+  Write Bootstrap = "@working_dir@/Client1.bsr"
+}
+
 # Backup the catalog database (after the nightly save)
 Job {
   Name = "BackupCatalog"
-  Type = Backup
-  Client=@hostname@-fd 
+  JobDefs = "DefaultJob"
   FileSet="Catalog"
   Schedule = "WeeklyCycleAfterBackup"
-  Storage = File
-  Messages = Standard
-  Pool = Default
   # This creates an ASCII copy of the catalog
   RunBeforeJob = "@scriptdir@/make_catalog_backup -u bacula"
   # This deletes the copy of the catalog
@@ -60,12 +62,8 @@ Job {
 # Standard Restore template, to be changed by Console program
 Job {
   Name = "RestoreFiles"
+  JobDefs = "DefaultJob"
   Type = Restore
-  Client=@hostname@-fd 
-  FileSet="Full Set"
-  Storage = File
-  Messages = Standard
-  Pool = Default
   Where = /tmp/bacula-restores
 }
 
index 8a0c47ed5203dff568a7c7071a4641bc77e9745e..f68da92bd2fd68e1f0c352f89aeddcbc6fed0d6a 100644 (file)
@@ -38,13 +38,16 @@ static void reload_config(int sig);
 
 
 /* Imported subroutines */
-extern JCR *wait_for_next_job(char *runjob);
-extern void term_scheduler();
-extern void term_ua_server();
-extern int do_backup(JCR *jcr);
-extern void backup_cleanup(void);
-extern void start_UA_server(char *addr, int port);
-extern void init_job_server(int max_workers);
+JCR *wait_for_next_job(char *runjob);
+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 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);
 
 static char *configfile = NULL;
 static char *runjob = NULL;
@@ -55,6 +58,12 @@ DIRRES *director;                  /* Director resource */
 int FDConnectTimeout;
 int SDConnectTimeout;
 
+/* Globals Imported */
+extern int r_first, r_last;          /* first and last resources */
+extern struct res_items job_items[];
+extern URES res_all;
+
+
 #define CONFIG_FILE "./bacula-dir.conf" /* default configuration file */
 
 static void usage()
@@ -100,7 +109,7 @@ int main (int argc, char *argv[])
 
    while ((ch = getopt(argc, argv, "c:d:fg:r:stu:v?")) != -1) {
       switch (ch) {
-         case 'c':                    /* specify config file */
+      case 'c':                    /* specify config file */
         if (configfile != NULL) {
            free(configfile);
         }
@@ -310,7 +319,7 @@ static void reload_config(int sig)
  */
 static int check_resources()
 {
-   int OK = TRUE;
+   bool OK = true;
    JOB *job;
 
    LockRes();
@@ -320,43 +329,119 @@ static int check_resources()
    if (!director) {
       Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n\
 Without that I don't know who I am :-(\n"), configfile);
-      OK = FALSE;
+      OK = false;
    } else {
       set_working_directory(director->working_directory);
       if (!director->messages) {       /* If message resource not specified */
         director->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
         if (!director->messages) {
             Jmsg(NULL, M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile);
-           OK = FALSE;
+           OK = false;
         }
       }
       if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) {
          Jmsg(NULL, M_FATAL, 0, _("Only one Director resource permitted in %s\n"),
            configfile);
-        OK = FALSE;
+        OK = false;
       } 
    }
 
    if (!job) {
       Jmsg(NULL, M_FATAL, 0, _("No Job records defined in %s\n"), configfile);
-      OK = FALSE;
+      OK = false;
    }
    foreach_res(job, R_JOB) {
-      if (!job->client) {
-         Jmsg(NULL, M_FATAL, 0, _("No Client record defined for job %s\n"), job->hdr.name);
-        OK = FALSE;
-      }
-      if (!job->fileset) {
-         Jmsg(NULL, M_FATAL, 0, _("No FileSet record defined for job %s\n"), job->hdr.name);
-        OK = FALSE;
-      }
-      if (!job->storage && job->JobType != JT_VERIFY) {
-         Jmsg(NULL, M_FATAL, 0, _("No Storage resource defined for job %s\n"), job->hdr.name);
-        OK = FALSE;
+      int i;
+
+      if (job->jobdefs) {
+        /* Transfer default items from JobDefs Resource */
+        for (i=0; job_items[i].name; i++) {
+           char **def_svalue, **svalue;  /* string value */
+           int *def_ivalue, *ivalue;     /* integer value */
+           int64_t *def_lvalue, *lvalue; /* 64 bit values */
+           uint32_t offset;
+
+            Dmsg4(400, "Job \"%s\", field \"%s\" bit=%d def=%d\n",
+               job->hdr.name, job_items[i].name, 
+               bit_is_set(i, job->hdr.item_present),  
+               bit_is_set(i, job->jobdefs->hdr.item_present));
+
+           if (!bit_is_set(i, job->hdr.item_present) &&
+                bit_is_set(i, job->jobdefs->hdr.item_present)) { 
+               Dmsg2(400, "Job \"%s\", field \"%s\": getting default.\n",
+                job->hdr.name, job_items[i].name);
+              offset = (char *)(job_items[i].value) - (char *)&res_all;   
+              /*
+               * Handle strings and directory strings
+               */
+              if (job_items[i].handler == store_str ||
+                  job_items[i].handler == store_dir) {
+                 def_svalue = (char **)((char *)(job->jobdefs) + offset);
+                  Dmsg5(400, "Job \"%s\", field \"%s\" def_svalue=%s item %d offset=%u\n", 
+                      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%u\n", (unsigned)*svalue);
+                 }
+                 *svalue = bstrdup(*def_svalue);
+                 set_bit(i, job->hdr.item_present);
+              } else if (job_items[i].handler == store_res) {
+                 def_svalue = (char **)((char *)(job->jobdefs) + offset);
+                  Dmsg4(400, "Job \"%s\", field \"%s\" item %d offset=%u\n", 
+                      job->hdr.name, job_items[i].name, i, offset);
+                 svalue = (char **)((char *)job + offset);
+                 if (*svalue) {
+                     Dmsg1(000, "Hey something is wrong. p=0x%u\n", (unsigned)*svalue);
+                 }
+                 *svalue = *def_svalue;
+                 set_bit(i, job->hdr.item_present);
+              /*
+               * Handle integer fields 
+               *    Note, our store_yesno does not handle bitmaped fields
+               */
+              } else if (job_items[i].handler == store_yesno   ||
+                         job_items[i].handler == store_pint    ||
+                         job_items[i].handler == store_jobtype ||
+                         job_items[i].handler == store_level   ||
+                         job_items[i].handler == store_pint    ||
+                         job_items[i].handler == store_replace) {
+                 def_ivalue = (int *)((char *)(job->jobdefs) + offset);
+                  Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n", 
+                      job->hdr.name, job_items[i].name, *def_ivalue, i, offset);
+                 ivalue = (int *)((char *)job + offset);
+                 *ivalue = *def_ivalue;
+                 set_bit(i, job->hdr.item_present);
+              /*
+               * Handle 64 bit integer fields 
+               */
+              } else if (job_items[i].handler == store_time   ||
+                         job_items[i].handler == store_size   ||
+                         job_items[i].handler == store_int64) {
+                 def_lvalue = (int64_t *)((char *)(job->jobdefs) + offset);
+                  Dmsg5(400, "Job \"%s\", field \"%s\" def_lvalue=%" lld " item %d offset=%u\n", 
+                      job->hdr.name, job_items[i].name, *def_lvalue, i, offset);
+                 lvalue = (int64_t *)((char *)job + offset);
+                 *lvalue = *def_lvalue;
+                 set_bit(i, job->hdr.item_present);
+              }
+           }
+        }
       }
-      if (!job->pool) {
-         Jmsg(NULL, M_FATAL, 0, _("No Pool resource defined for job %s\n"), job->hdr.name);
-        OK = FALSE;
+      /* 
+       * Ensure that all required items are present
+       */
+      for (i=0; job_items[i].name; i++) {
+        if (job_items[i].flags & ITEM_REQUIRED) {
+              if (!bit_is_set(i, job->hdr.item_present)) {  
+                  Jmsg(NULL, M_FATAL, 0, "Field \"%s\" in Job \"%s\" resource is required, but not found.\n",
+                   job_items[i].name, job->hdr.name);
+                 OK = false;
+               }
+        }
+        /* If this triggers, take a look at lib/parse_conf.h */
+        if (i >= MAX_RES_ITEMS) {
+            Emsg0(M_ERROR_TERM, 0, "Too many items in Job resource\n");
+        }
       }
       if (job->client && job->client->catalog) {
         CAT *catalog = job->client->catalog;
@@ -375,7 +460,7 @@ Without that I don't know who I am :-(\n"), configfile);
            if (db) {
                Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
            }
-           OK = FALSE;
+           OK = false;
         } else {
            /* If a pool is defined for this job, create the pool DB       
             *  record if it is not already created. 
@@ -410,13 +495,6 @@ Without that I don't know who I am :-(\n"), configfile);
            }
            db_close_database(NULL, db);
         }
-
-      } else {
-        if (job->client) {
-            Jmsg(NULL, M_FATAL, 0, _("No Catalog resource defined for client %s\n"), 
-              job->client->hdr.name);
-           OK = FALSE;
-        }
       }
    }
 
index b6738d5f834092231a73f4b9089a3f287611d144..f741addf9eca54729546ad5700c9801835278e5c 100644 (file)
@@ -61,9 +61,9 @@ extern void store_inc(LEX *lc, struct res_items *item, int index, int pass);
 
 /* Forward referenced subroutines */
 
-static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass);
-static void store_level(LEX *lc, struct res_items *item, int index, int pass);
-static void store_replace(LEX *lc, struct res_items *item, int index, int pass);
+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);
 
 
 /* We build the current resource here as we are
@@ -187,16 +187,16 @@ static struct res_items cat_items[] = {
  *
  *   name         handler     value                 code flags    default_value
  */
-static struct res_items job_items[] = {
+struct res_items job_items[] = {
    {"name",      store_name,    ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,   ITEM(res_job.hdr.desc), 0, 0, 0},
-   {"type",      store_jobtype, ITEM(res_job),          0, 0, 0},
-   {"level",     store_level,   ITEM(res_job),          0, 0, 0},
-   {"messages",  store_res,     ITEM(res_job.messages), R_MSGS, 0, 0},
-   {"storage",   store_res,     ITEM(res_job.storage),  R_STORAGE, 0, 0},
-   {"pool",      store_res,     ITEM(res_job.pool),     R_POOL, 0, 0},
-   {"client",    store_res,     ITEM(res_job.client),   R_CLIENT, 0, 0},
-   {"fileset",   store_res,     ITEM(res_job.fileset),  R_FILESET, 0, 0},
+   {"type",      store_jobtype, ITEM(res_job.JobType),  0, ITEM_REQUIRED, 0},
+   {"level",     store_level,   ITEM(res_job.level),    0, ITEM_REQUIRED, 0},
+   {"messages",  store_res,     ITEM(res_job.messages), R_MSGS, ITEM_REQUIRED, 0},
+   {"storage",   store_res,     ITEM(res_job.storage),  R_STORAGE, ITEM_REQUIRED, 0},
+   {"pool",      store_res,     ITEM(res_job.pool),     R_POOL, ITEM_REQUIRED, 0},
+   {"client",    store_res,     ITEM(res_job.client),   R_CLIENT, ITEM_REQUIRED, 0},
+   {"fileset",   store_res,     ITEM(res_job.fileset),  R_FILESET, ITEM_REQUIRED, 0},
    {"schedule",  store_res,     ITEM(res_job.schedule), R_SCHEDULE, 0, 0},
    {"verifyjob", store_res,     ITEM(res_job.verify_job), R_JOB, 0, 0},
    {"jobdefs",   store_res,     ITEM(res_job.jobdefs),  R_JOBDEFS, 0, 0},
@@ -904,22 +904,22 @@ void save_resource(int type, struct res_items *items, int pass)
    int i, size;
    int error = 0;
    
-   if (type == R_JOBDEFS) {
-      return;                        /* nothing required */
-   }
-   /* 
-    * Ensure that all required items are present
-    */
-   for (i=0; items[i].name; i++) {
-      if (items[i].flags & ITEM_REQUIRED) {
-           if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
-               Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n",
-                items[i].name, resources[rindex]);
-            }
-      }
-      /* If this triggers, take a look at lib/parse_conf.h */
-      if (i >= MAX_RES_ITEMS) {
-         Emsg1(M_ERROR_TERM, 0, "Too many items in %s resource\n", resources[rindex]);
+   /* Check Job requirements after applying JobDefs */
+   if (type != R_JOB && type != R_JOBDEFS) {
+      /* 
+       * Ensure that all required items are present
+       */
+      for (i=0; items[i].name; i++) {
+        if (items[i].flags & ITEM_REQUIRED) {
+              if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
+                  Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n",
+                   items[i].name, resources[rindex]);
+               }
+        }
+        /* If this triggers, take a look at lib/parse_conf.h */
+        if (i >= MAX_RES_ITEMS) {
+            Emsg1(M_ERROR_TERM, 0, "Too many items in %s resource\n", resources[rindex]);
+        }
       }
    }
 
@@ -962,25 +962,6 @@ void save_resource(int type, struct res_items *items, int pass)
         res->res_job.pool       = res_all.res_job.pool;
         res->res_job.verify_job = res_all.res_job.verify_job;
         res->res_job.jobdefs    = res_all.res_job.jobdefs;
-        if (type == R_JOB) {
-           if (res->res_job.JobType == 0) {
-               Emsg1(M_ERROR_TERM, 0, "Job Type not defined for Job resource %s\n", res_all.res_dir.hdr.name);
-           }
-           if (res->res_job.level != 0) {
-              int i;
-              for (i=0; joblevels[i].level_name; i++) {
-                 if (joblevels[i].level == res->res_job.level &&
-                     joblevels[i].job_type == res->res_job.JobType) {
-                    i = 0;
-                    break;
-                 }
-              }
-              if (i != 0) {
-                  Emsg1(M_ERROR_TERM, 0, "Inappropriate level specified in Job resource %s\n", 
-                    res_all.res_dir.hdr.name);
-              }
-           }
-        }
         break;
       case R_COUNTER:
         if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
@@ -1106,7 +1087,7 @@ void save_resource(int type, struct res_items *items, int pass)
  * Store JobType (backup, verify, restore)
  *
  */
-static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass)
+void store_jobtype(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token, i;   
 
@@ -1114,7 +1095,7 @@ static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass)
    /* Store the type both pass 1 and pass 2 */
    for (i=0; jobtypes[i].type_name; i++) {
       if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) {
-        ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
+        *(int *)(item->value) = jobtypes[i].job_type;
         i = 0;
         break;
       }
@@ -1130,7 +1111,7 @@ static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass)
  * Store Job Level (Full, Incremental, ...)
  *
  */
-static void store_level(LEX *lc, struct res_items *item, int index, int pass)
+void store_level(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token, i;
 
@@ -1138,7 +1119,7 @@ static void store_level(LEX *lc, struct res_items *item, int index, int pass)
    /* Store the level pass 2 so that type is defined */
    for (i=0; joblevels[i].level_name; i++) {
       if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
-        ((JOB *)(item->value))->level = joblevels[i].level;
+        *(int *)(item->value) = joblevels[i].level;
         i = 0;
         break;
       }
@@ -1150,7 +1131,7 @@ static void store_level(LEX *lc, struct res_items *item, int index, int pass)
    set_bit(index, res_all.hdr.item_present);
 }
 
-static void store_replace(LEX *lc, struct res_items *item, int index, int pass)
+void store_replace(LEX *lc, struct res_items *item, int index, int pass)
 {
    int token, i;
    token = lex_get_token(lc, T_NAME);