From ad70b1e906c59a38fbcd72c6e6688c74c8decb2d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 27 Dec 2003 13:14:12 +0000 Subject: [PATCH] Finish JobDefs implementation + fix Makefile.in cats directory scripts git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@957 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/Makefile.in | 15 +-- bacula/src/dird/bacula-dir.conf.in | 30 +++--- bacula/src/dird/dird.c | 148 ++++++++++++++++++++++------- bacula/src/dird/dird_conf.c | 83 +++++++--------- 4 files changed, 167 insertions(+), 109 deletions(-) diff --git a/bacula/Makefile.in b/bacula/Makefile.in index 997d7f9867..d2a4c677ad 100755 --- a/bacula/Makefile.in +++ b/bacula/Makefile.in @@ -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}; \ diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index 01ac8dcdeb..474f6ae97b 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -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 } diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 8a0c47ed52..f68da92bd2 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -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; - } } } diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index b6738d5f83..f741addf9e 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -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); -- 2.39.5