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}; \
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"
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
# 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
}
/* 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;
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()
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);
}
*/
static int check_resources()
{
- int OK = TRUE;
+ bool OK = true;
JOB *job;
LockRes();
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;
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.
}
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;
- }
}
}
/* 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
*
* 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},
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]);
+ }
}
}
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) {
* 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;
/* 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;
}
* 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;
/* 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;
}
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);