From: Kern Sibbald Date: Sat, 18 May 2002 08:48:40 +0000 (+0000) Subject: 1.20 update -- kes18May02 X-Git-Tag: Release-1.20~8 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=c3009688855647dbb3e9997fc569963fd320783d;p=bacula%2Fbacula 1.20 update -- kes18May02 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@24 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/bc_types.h b/bacula/src/bc_types.h index 52af67ddc6..640463f4f3 100644 --- a/bacula/src/bc_types.h +++ b/bacula/src/bc_types.h @@ -40,6 +40,8 @@ /* ****FIXME***** implement 64 bit file addresses ! */ #define faddr_t long +#define POOLMEM char + /* Types */ /* If sys/types.h does not supply intXX_t, supply them ourselves */ diff --git a/bacula/src/cats/sql_update.c b/bacula/src/cats/sql_update.c index eef77585c8..af77ff3408 100644 --- a/bacula/src/cats/sql_update.c +++ b/bacula/src/cats/sql_update.c @@ -192,7 +192,7 @@ db_update_media_record(B_DB *mdb, MEDIA_DBR *mr) localtime_r(&ttime, &tm); strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm); - Dmsg1(000, "update_media: FirstWritte=%d\n", mr->FirstWritten); + Dmsg1(100, "update_media: FirstWritten=%d\n", mr->FirstWritten); P(mdb->mutex); if (mr->VolMounts == 1) { Mmsg(&mdb->cmd, "UPDATE Media SET FirstWritten=\"%s\"\ diff --git a/bacula/src/console.glade b/bacula/src/console.glade index 5a7fa1c3ec..cf1622a783 100644 --- a/bacula/src/console.glade +++ b/bacula/src/console.glade @@ -1196,12 +1196,13 @@ GtkHBox hbox19 + 22 False 0 0 False - True + False diff --git a/bacula/src/console/console.c b/bacula/src/console/console.c index 24c6e7a8aa..bbe0e3fd8c 100644 --- a/bacula/src/console/console.c +++ b/bacula/src/console/console.c @@ -142,16 +142,9 @@ int main(int argc, char *argv[]) init_stack_dump(); my_name_is(argc, argv, "console"); + init_msg(NULL, NULL); working_directory = "/tmp"; - /* - * Ensure that every message is always printed - */ - for (i=1; i<=M_MAX; i++) { - add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL); - } - - while ((ch = getopt(argc, argv, "bc:d:r:st?")) != -1) { switch (ch) { case 'c': /* configuration file */ diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 92c1f6e200..631a971c5d 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -68,34 +68,14 @@ int do_backup(JCR *jcr) int stat; BSOCK *fd; POOL_DBR pr; -#ifdef needed - MEDIA_DBR mr; -#endif - CLIENT_DBR cr; FILESET_DBR fsr; since[0] = 0; - /* - * Get or Create client record - */ - memset(&cr, 0, sizeof(cr)); - strcpy(cr.Name, jcr->client->hdr.name); - cr.AutoPrune = jcr->client->AutoPrune; - cr.FileRetention = jcr->client->FileRetention; - cr.JobRetention = jcr->client->JobRetention; - if (jcr->client_name) { - free(jcr->client_name); - } - jcr->client_name = bstrdup(jcr->client->hdr.name); - if (!db_create_client_record(jcr->db, &cr)) { - Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), - db_strerror(jcr->db)); + + if (!get_or_create_client_record(jcr)) { backup_cleanup(jcr, JS_ErrorTerminated, since); - return 0; } - jcr->jr.ClientId = cr.ClientId; - Dmsg2(9, "Created Client %s record %d\n", jcr->client->hdr.name, - jcr->jr.ClientId); + /* * Get or Create FileSet record @@ -354,22 +334,12 @@ static void backup_cleanup(JCR *jcr, int TermCode, char *since) int msg_type; MEDIA_DBR mr; - memset(&mr, 0, sizeof(mr)); Dmsg0(100, "Enter backup_cleanup()\n"); - if (jcr->jr.EndTime == 0) { - jcr->jr.EndTime = time(NULL); - } - jcr->end_time = jcr->jr.EndTime; - jcr->jr.JobId = jcr->JobId; - jcr->jr.JobStatus = jcr->JobStatus = TermCode; - jcr->jr.JobFiles = jcr->JobFiles; - jcr->jr.JobBytes = jcr->JobBytes; - jcr->jr.VolSessionId = jcr->VolSessionId; - jcr->jr.VolSessionTime = jcr->VolSessionTime; - if (!db_update_job_end_record(jcr->db, &jcr->jr)) { - Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), - db_strerror(jcr->db)); - } + memset(&mr, 0, sizeof(mr)); + jcr->JobStatus = TermCode; + + update_job_end_record(jcr); /* update database */ + if (!db_get_job_record(jcr->db, &jcr->jr)) { Jmsg(jcr, M_WARNING, 0, _("Error getting job record for stats: %s"), db_strerror(jcr->db)); diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index 3087e87fe9..8b266fd914 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -21,6 +21,7 @@ Director { # define myself SubSysDirectory = "@subsysdir@" Maximum Concurrent Jobs = 1 Password = "@dir_password@" # Console password + Messages = Standard } # Define the backup Job @@ -124,7 +125,7 @@ Messages { Name = Standard mailcommand = "@sbindir@/smtp -h @smtp_host@ -f \"Bacula <%r>\" -s \"Bacula: %t %e of %c %l\" %r" operatorcommand = "@sbindir@/smtp -h @smtp_host@ -f \"Bacula <%r>\" -s \"Bacula: Intervention needed for %j\" %r" - mail = @job_email@ = all, !skipped, !terminate + mail = @job_email@ = all, !skipped operator = @job_email@ = mount console = all, !skipped, !saved } diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index a9a49da782..cc93770be0 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -89,6 +89,7 @@ int main (int argc, char *argv[]) init_stack_dump(); my_name_is(argc, argv, "bacula-dir"); + init_msg(NULL, NULL); /* initialize message handler */ daemon_start_time = time(NULL); memset(&last_job, 0, sizeof(last_job)); @@ -160,29 +161,29 @@ int main (int argc, char *argv[]) configfile = bstrdup(CONFIG_FILE); } - init_msg(NULL, NULL); /* initialize message handler */ parse_config(configfile); if (!check_resources()) { Emsg1(M_ABORT, 0, "Please correct configuration file: %s\n", configfile); } - my_name_is(0, (char **)NULL, director->hdr.name); /* set user defined name */ - - FDConnectTimeout = director->FDConnectTimeout; - SDConnectTimeout = director->SDConnectTimeout; - - if (test_config) { terminate_dird(0); - exit(0); } + my_name_is(0, NULL, director->hdr.name); /* set user defined name */ + + FDConnectTimeout = director->FDConnectTimeout; + SDConnectTimeout = director->SDConnectTimeout; + if (background) { daemon_start(); init_stack_dump(); /* grab new pid */ } + /* 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); + signal(SIGHUP, reload_config); init_console_msg(working_directory); @@ -203,7 +204,6 @@ int main (int argc, char *argv[]) } terminate_dird(0); - exit(0); /* for compiler */ } /* Cleanup and then exit */ @@ -215,6 +215,8 @@ static void terminate_dird(int sig) exit(1); } already_here = TRUE; + delete_pid_file(director->pid_directory, "bacula-dir", + director->DIRport); stop_watchdog(); signal(SIGCHLD, SIG_IGN); /* don't worry about children now */ term_scheduler(); @@ -229,10 +231,10 @@ static void terminate_dird(int sig) } free_config_resources(); term_ua_server(); - close_memory_pool(); /* free memory in pool */ term_msg(); /* terminate message handler */ + close_memory_pool(); /* release free memory in pool */ sm_dump(False); - exit(0); + exit(sig != 0); } /* @@ -291,39 +293,48 @@ static int check_resources() job = (JOB *)GetNextRes(R_JOB, NULL); director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL); if (!director) { - Emsg1(M_WARNING, 0, _("No Director resource defined in %s\n\ + Emsg1(M_FATAL, 0, _("No Director resource defined in %s\n\ Without that I don't know who I am :-(\n"), configfile); OK = FALSE; + } else { + if (!director->working_directory) { + Emsg0(M_FATAL, 0, _("No working directory specified. Cannot continue.\n")); + OK = FALSE; + } + working_directory = director->working_directory; + if (!director->messages) { /* If message resource not specified */ + director->messages = (MSGS *)GetNextRes(R_MSGS, NULL); + if (!director->messages) { + Emsg1(M_FATAL, 0, _("No Messages resource defined in %s\n"), configfile); + OK = FALSE; + } + } + if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) { + Emsg1(M_FATAL, 0, _("Only one Director resource permitted in %s\n"), + configfile); + OK = FALSE; + } } - if (GetNextRes(R_DIRECTOR, (RES *)director) != NULL) { - Emsg1(M_WARNING, 0, _("Only one Director resource permitted in %s\n"), - configfile); - OK = FALSE; - } - if (!director->working_directory) { - Emsg0(M_WARNING, 0, _("No working directory specified. Cannot continue.\n")); - OK = FALSE; - } - working_directory = director->working_directory; + if (!job) { - Emsg1(M_WARNING, 0, _("No Job records defined in %s\n"), configfile); + Emsg1(M_FATAL, 0, _("No Job records defined in %s\n"), configfile); OK = FALSE; } for (job=NULL; (job = (JOB *)GetNextRes(R_JOB, (RES *)job)); ) { if (!job->client) { - Emsg1(M_WARNING, 0, _("No Client record defined for job %s\n"), job->hdr.name); + Emsg1(M_FATAL, 0, _("No Client record defined for job %s\n"), job->hdr.name); OK = FALSE; } if (!job->fs) { - Emsg1(M_WARNING, 0, _("No FileSet record defined for job %s\n"), job->hdr.name); + Emsg1(M_FATAL, 0, _("No FileSet record defined for job %s\n"), job->hdr.name); OK = FALSE; } if (!job->storage && job->JobType != JT_VERIFY) { - Emsg1(M_WARNING, 0, _("No Storage resource defined for job %s\n"), job->hdr.name); + Emsg1(M_FATAL, 0, _("No Storage resource defined for job %s\n"), job->hdr.name); OK = FALSE; } if (!job->pool) { - Emsg1(M_WARNING, 0, _("No Pool resource defined for job %s\n"), job->hdr.name); + Emsg1(M_FATAL, 0, _("No Pool resource defined for job %s\n"), job->hdr.name); OK = FALSE; } if (job->client->catalog) { @@ -337,16 +348,20 @@ Without that I don't know who I am :-(\n"), configfile); db = db_init_database(catalog->db_name, catalog->db_user, catalog->db_password); if (!db_open_database(db)) { - Emsg1(M_WARNING, 0, "%s", db_strerror(db)); + Emsg1(M_FATAL, 0, "%s", db_strerror(db)); } db_close_database(db); } else { - Emsg1(M_WARNING, 0, _("No Catalog resource defined for client %s\n"), + Emsg1(M_FATAL, 0, _("No Catalog resource defined for client %s\n"), job->client->hdr.name); OK = FALSE; } } UnlockRes(); + if (OK) { + close_msg(NULL); /* close temp message handler */ + init_msg(NULL, director->messages); /* open daemon message handler */ + } return OK; } diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 7d327814e2..9043edcab0 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -19,7 +19,7 @@ * * Kern Sibbald, January MM * - * $Id: + * $Id$ */ /* Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker @@ -61,6 +61,8 @@ extern void store_run(LEX *lc, struct res_items *item, int index, int pass); static void store_inc(LEX *lc, struct res_items *item, int index, int pass); static void store_backup(LEX *lc, struct res_items *item, int index, int pass); static void store_restore(LEX *lc, struct res_items *item, int index, int pass); +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); /* We build the current resource here as we are @@ -155,16 +157,20 @@ static struct res_items cat_items[] = { * name handler value code flags default_value */ static 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}, - {"backup", store_backup, ITEM(res_job), JT_BACKUP, 0, 0}, - {"verify", store_backup, ITEM(res_job), JT_VERIFY, 0, 0}, - {"restore", store_restore, ITEM(res_job), JT_RESTORE, 0, 0}, - {"schedule", store_res, ITEM(res_job.schedule), R_SCHEDULE, 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}, - {"maxruntime", store_time, ITEM(res_job.MaxRunTime), 0, 0, 0}, + {"name", store_name, ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0}, + {"description", store_str, ITEM(res_job.hdr.desc), 0, 0, 0}, + {"backup", store_backup, ITEM(res_job), JT_BACKUP, 0, 0}, + {"verify", store_backup, ITEM(res_job), JT_VERIFY, 0, 0}, + {"restore", store_restore, ITEM(res_job), JT_RESTORE, 0, 0}, + {"schedule", store_res, ITEM(res_job.schedule), R_SCHEDULE, 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.fs), R_FILESET, 0, 0}, + {"maxruntime", store_time, ITEM(res_job.MaxRunTime), 0, 0, 0}, {"maxstartdelay", store_time, ITEM(res_job.MaxStartDelay), 0, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -249,7 +255,7 @@ struct s_res resources[] = { /* Keywords (RHS) permitted in Job Level records * - * level_name level level_class + * level_name level job_type */ struct s_jl joblevels[] = { {"Full", L_FULL, JT_BACKUP}, @@ -264,6 +270,18 @@ struct s_jl joblevels[] = { {NULL, 0} }; +/* Keywords (RHS) permitted in Job type records + * + * type_name job_type + */ +struct s_jt jobtypes[] = { + {"backup", JT_BACKUP}, + {"verify", JT_VERIFY}, + {"restore", JT_RESTORE}, + {NULL, 0} +}; + + /* Keywords (RHS) permitted in Backup and Verify records */ static struct s_kw BakVerFields[] = { {"client", 'C'}, @@ -586,6 +604,8 @@ void free_resource(int type) free(res->res_msgs.mail_cmd); if (res->res_msgs.operator_cmd) free(res->res_msgs.operator_cmd); + free_msgs_res((MSGS *)res); /* free message resource */ + res = NULL; break; case R_GROUP: break; @@ -593,13 +613,17 @@ void free_resource(int type) printf("Unknown resource type %d\n", type); } /* Common stuff again -- free the resource, recurse to next one */ - free(res); + if (res) { + free(res); + } resources[rindex].res_head = nres; - if (nres) + if (nres) { free_resource(type); + } } -/* Save the new resource by chaining it into the head list for +/* + * Save the new resource by chaining it into the head list for * the resource. If this is pass 2, we update any resource * pointers (currently only in the Job resource). */ @@ -660,6 +684,23 @@ void save_resource(int type, struct res_items *items, int pass) res->res_job.fs = res_all.res_job.fs; res->res_job.storage = res_all.res_job.storage; res->res_job.pool = res_all.res_job.pool; + if (res->res_job.JobType == 0) { + Emsg1(M_ABORT, 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_ABORT, 0, "Inappropriate level specified in Job resource %s\n", + res_all.res_dir.hdr.name); + } + } break; case R_CLIENT: if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { @@ -679,6 +720,10 @@ void save_resource(int type, struct res_items *items, int pass) free(res_all.res_dir.hdr.name); res_all.res_dir.hdr.name = NULL; } + if (res_all.res_dir.hdr.desc) { + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; + } return; } @@ -730,6 +775,64 @@ 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) +{ + int token, i; + + token = lex_get_token(lc); + if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { + scan_err1(lc, "expected an identifier or string, got: %s", lc->str); + } else { + /* 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; + i = 0; + break; + } + } + if (i != 0) { + scan_err1(lc, "Expected a Job Type keyword, got: %s", lc->str); + } + } + scan_to_eol(lc); + set_bit(index, res_all.hdr.item_present); +} + +/* + * Store Job Level (Full, Incremental, ...) + * + */ +static void store_level(LEX *lc, struct res_items *item, int index, int pass) +{ + int token, i; + + token = lex_get_token(lc); + if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { + scan_err1(lc, "expected an identifier or string, got: %s", lc->str); + } else { + /* 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; + i = 0; + break; + } + } + if (i != 0) { + scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str); + } + } + scan_to_eol(lc); + set_bit(index, res_all.hdr.item_present); +} + + + /* * Store backup/verify info for Job record * @@ -753,7 +856,6 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass) if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a backup/verify keyword, got: %s", lc->str); } else { - lcase(lc->str); Dmsg1(190, "Got keyword: %s\n", lc->str); found = FALSE; for (i=0; BakVerFields[i].name; i++) { @@ -792,9 +894,8 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass) break; case 'L': /* Get level */ - lcase(lc->str); for (i=0; joblevels[i].level_name; i++) { - if (joblevels[i].job_class == item->code && + if (joblevels[i].job_type == item->code && strcasecmp(lc->str, joblevels[i].level_name) == 0) { ((JOB *)(item->value))->level = joblevels[i].level; i = 0; @@ -841,11 +942,10 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass) if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a Restore keyword, got: %s", lc->str); } else { - lcase(lc->str); found = FALSE; for (i=0; RestoreFields[i].name; i++) { Dmsg1(190, "Restore kw=%s\n", lc->str); - if (strcmp(lc->str, RestoreFields[i].name) == 0) { + if (strcasecmp(lc->str, RestoreFields[i].name) == 0) { found = TRUE; if (lex_get_token(lc) != T_EQUALS) { scan_err1(lc, "Expected an equals, got: %s", lc->str); @@ -901,10 +1001,9 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass) if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a keyword name, got: %s", lc->str); } - lcase(lc->str); /* Fix to scan Replacement options */ for (i=0; ReplaceOptions[i].name; i++) { - if (strcmp(lc->str, ReplaceOptions[i].name) == 0) { + if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { ((JOB *)(item->value))->RestoreOptions = ReplaceOptions[i].token; i = 0; break; @@ -945,7 +1044,6 @@ static char *scan_fs_options(LEX *lc, int keyword) if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "expected a FileSet option, got: %s", lc->str); } - lcase(lc->str); if (keyword == FS_KW_VERIFY) { /* special case */ /* ***FIXME**** ensure these are in permitted set */ strcpy(option, "V"); /* indicate Verify */ @@ -953,7 +1051,7 @@ static char *scan_fs_options(LEX *lc, int keyword) strcat(option, ":"); /* terminate it */ } else { for (i=0; FS_options[i].name; i++) { - if (strcmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) { + if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) { option[0] = FS_options[i].option; i = 0; break; @@ -995,9 +1093,8 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) scan_err1(lc, "expected a FileSet option keyword, got: %s", lc->str); } else { keyword = FS_KW_NONE; - lcase(lc->str); for (i=0; FS_option_kw[i].name; i++) { - if (strcmp(lc->str, FS_option_kw[i].name) == 0) { + if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) { keyword = FS_option_kw[i].token; break; } diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index f70441d526..07ca5c20c8 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -61,11 +61,16 @@ struct s_kw { /* Job Level keyword structure */ struct s_jl { - char *level_name; - int level; - int job_class; + char *level_name; /* level keyword */ + int level; /* level */ + int job_type; /* JobType permitting this level */ }; +/* Job Type keyword structure */ +struct s_jt { + char *type_name; + int job_type; +}; /* Definition of the contents of each Resource */ @@ -81,7 +86,7 @@ struct s_res_dir { char *working_directory; /* WorkingDirectory */ char *pid_directory; /* PidDirectory */ char *subsys_directory; /* SubsysDirectory */ - struct s_res_msgs *messages; + struct s_res_msgs *messages; /* Daemon message handler */ int MaxConcurrentJobs; btime_t FDConnectTimeout; /* timeout for connect in seconds */ btime_t SDConnectTimeout; /* timeout in seconds */ @@ -244,7 +249,7 @@ typedef union u_res URES; struct s_run { struct s_run *next; /* points to next run record */ int level; - int job_class; + int job_type; char *since; int level_no; int minute; /* minute to run job */ diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index 539b73cae0..ea2dbd22d9 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -59,7 +59,8 @@ void init_job_server(int max_workers) } /* - * Run a job + * Run a job -- typically called by the scheduler, but may also + * be called by the UA (Console program). * */ void run_job(JCR *jcr) @@ -124,7 +125,11 @@ void run_job(JCR *jcr) Dmsg0(200, "Done run_job()\n"); } -/* This is the engine called by workq_add() */ +/* + * This is the engine called by workq_add() when we were pulled + * from the work queue. + * At this point, we are running in our own thread + */ static void job_thread(void *arg) { time_t now; @@ -137,29 +142,85 @@ static void job_thread(void *arg) if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay < (btime_t)(jcr->start_time - jcr->sched_time)) { Jmsg(jcr, M_FATAL, 0, _("Job cancelled because max delay time exceeded.\n")); - free_jcr(jcr); - } - jcr->JobStatus = JS_Running; + jcr->JobStatus = JS_ErrorTerminated; + update_job_end_record(jcr); + } else { - switch (jcr->JobType) { - case JT_BACKUP: - do_backup(jcr); - break; - case JT_VERIFY: - do_verify(jcr); - break; - case JT_RESTORE: - do_restore(jcr); - break; - default: - Dmsg1(0, "Unimplemented job type: %d\n", jcr->JobType); - break; + /* Run Job */ + jcr->JobStatus = JS_Running; + + switch (jcr->JobType) { + case JT_BACKUP: + do_backup(jcr); + break; + case JT_VERIFY: + do_verify(jcr); + break; + case JT_RESTORE: + do_restore(jcr); + break; + case JT_ADMIN: + /* No actual job */ + break; + default: + Dmsg1(0, "Unimplemented job type: %d\n", jcr->JobType); + break; + } } Dmsg0(50, "Before free jcr\n"); free_jcr(jcr); Dmsg0(50, "======== End Job ==========\n"); } +/* + * Get or create a Client record for this Job + */ +int get_or_create_client_record(JCR *jcr) +{ + CLIENT_DBR cr; + + memset(&cr, 0, sizeof(cr)); + strcpy(cr.Name, jcr->client->hdr.name); + cr.AutoPrune = jcr->client->AutoPrune; + cr.FileRetention = jcr->client->FileRetention; + cr.JobRetention = jcr->client->JobRetention; + if (jcr->client_name) { + free(jcr->client_name); + } + jcr->client_name = bstrdup(jcr->client->hdr.name); + if (!db_create_client_record(jcr->db, &cr)) { + Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), + db_strerror(jcr->db)); + return 0; + } + jcr->jr.ClientId = cr.ClientId; + Dmsg2(9, "Created Client %s record %d\n", jcr->client->hdr.name, + jcr->jr.ClientId); + return 1; +} + + +/* + * Write status and such in DB + */ +void update_job_end_record(JCR *jcr) +{ + if (jcr->jr.EndTime == 0) { + jcr->jr.EndTime = time(NULL); + } + jcr->end_time = jcr->jr.EndTime; + jcr->jr.JobId = jcr->JobId; + jcr->jr.JobStatus = jcr->JobStatus; + jcr->jr.JobFiles = jcr->JobFiles; + jcr->jr.JobBytes = jcr->JobBytes; + jcr->jr.VolSessionId = jcr->VolSessionId; + jcr->jr.VolSessionTime = jcr->VolSessionTime; + if (!db_update_job_end_record(jcr->db, &jcr->jr)) { + Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), + db_strerror(jcr->db)); + } +} + /* * Takes base_name and appends (unique) current * date and time to form unique job name. diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 8cd2a22ba5..7f09c081a6 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -49,6 +49,8 @@ extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname, extern void free_jcr(JCR *jcr); extern void set_jcr_defaults(JCR *jcr, JOB *job); extern void create_unique_job_name(JCR *jcr, char *base_name); +extern void update_job_end_record(JCR *jcr); +extern int get_or_create_client_record(JCR *jcr); /* mountreq.c */ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf); diff --git a/bacula/src/dird/restore.c b/bacula/src/dird/restore.c index 51581b34a6..a63c47eb1f 100644 --- a/bacula/src/dird/restore.c +++ b/bacula/src/dird/restore.c @@ -68,27 +68,12 @@ int do_restore(JCR *jcr) char dt[MAX_TIME_LENGTH]; BSOCK *fd; JOB_DBR rjr; /* restore job record */ - CLIENT_DBR cr; - /* - * Get or Create a client record - */ - memset(&cr, 0, sizeof(cr)); - strcpy(cr.Name, jcr->client->hdr.name); - cr.AutoPrune = jcr->client->AutoPrune; - cr.FileRetention = jcr->client->FileRetention; - cr.JobRetention = jcr->client->JobRetention; - if (jcr->client_name) { - free(jcr->client_name); - } - jcr->client_name = bstrdup(jcr->client->hdr.name); - if (!db_create_client_record(jcr->db, &cr)) { - Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), - db_strerror(jcr->db)); + + if (!get_or_create_client_record(jcr)) { restore_cleanup(jcr, JS_ErrorTerminated); return 0; } - jcr->jr.ClientId = cr.ClientId; memset(&rjr, 0, sizeof(rjr)); jcr->jr.Level = 'F'; /* Full restore */ @@ -258,14 +243,9 @@ static void restore_cleanup(JCR *jcr, int status) char dt[MAX_TIME_LENGTH]; Dmsg0(20, "In restore_cleanup\n"); - if (jcr->jr.EndTime == 0) { - jcr->jr.EndTime = time(NULL); - } - jcr->jr.JobStatus = jcr->JobStatus = status; - if (!db_update_job_end_record(jcr->db, &jcr->jr)) { - Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), - db_strerror(jcr->db)); - } + jcr->JobStatus = status; + + update_job_end_record(jcr); bstrftime(dt, sizeof(dt), jcr->jr.EndTime); Jmsg(jcr, M_INFO, 0, _("%s End Restore Job %s.\n"), diff --git a/bacula/src/dird/run_conf.c b/bacula/src/dird/run_conf.c index 21b69f8944..3fe299354a 100644 --- a/bacula/src/dird/run_conf.c +++ b/bacula/src/dird/run_conf.c @@ -174,11 +174,16 @@ void store_run(LEX *lc, struct res_items *item, int index, int pass) if (token != T_STRING) { scan_err1(lc, _("Expected a Job level identifier, got: %s"), lc->str); } else { - lcase(lc->str); + if (strcasecmp(lc->str, "level")) { + if (lex_get_token(lc) != T_EQUALS) { + scan_err1(lc, "Expected an equals, got: %s", lc->str); + } + token = lex_get_token(lc); + } for (i=0; joblevels[i].level_name; i++) { if (strcasecmp(lc->str, joblevels[i].level_name) == 0) { lrun.level = joblevels[i].level; - lrun.job_class = joblevels[i].job_class; + lrun.job_type = joblevels[i].job_type; i = 0; break; } diff --git a/bacula/src/dird/ua_prune.c b/bacula/src/dird/ua_prune.c index d790e78c82..2111d09e99 100644 --- a/bacula/src/dird/ua_prune.c +++ b/bacula/src/dird/ua_prune.c @@ -5,7 +5,7 @@ * * Kern Sibbald, February MMII * - * $Id: + * $Id$ */ /* @@ -134,7 +134,7 @@ static int count_handler(void *ctx, int num_fields, char **row) /* - * Called here to count entries to be deleted + * Called here to count the number of Jobs to be pruned */ static int file_count_handler(void *ctx, int num_fields, char **row) { @@ -276,7 +276,7 @@ int prune_files(UAContext *ua, CLIENT *client) int i; btime_t now, period; CLIENT_DBR cr; - char ed1[50]; + char ed1[50], ed2[50]; memset(&cr, 0, sizeof(cr)); memset(&del, 0, sizeof(del)); @@ -320,7 +320,12 @@ int prune_files(UAContext *ua, CLIENT *client) db_sql_query(ua->db, query, file_delete_handler, (void *)&del); for (i=0; i < del.num_ids; i++) { + struct s_count_ctx cnt; Dmsg1(050, "Delete JobId=%d\n", del.JobId[i]); + Mmsg(&query, "SELECT count(*) FROM File WHERE JobId=%d", del.JobId[i]); + cnt.count = 0; + db_sql_query(ua->db, query, count_handler, (void *)&cnt); + del.tot_ids += cnt.count; Mmsg(&query, "DELETE FROM File WHERE JobId=%d", del.JobId[i]); db_sql_query(ua->db, query, NULL, (void *)NULL); /* @@ -333,8 +338,10 @@ int prune_files(UAContext *ua, CLIENT *client) db_sql_query(ua->db, query, NULL, (void *)NULL); Dmsg1(050, "Del sql=%s\n", query); } - bsendmsg(ua, _("Pruned %d Files for client %s from %s catalog.\n"), del.num_ids, - client->hdr.name, client->catalog->hdr.name); + edit_uint64_with_commas(del.tot_ids, ed1); + edit_uint64_with_commas(del.num_ids, ed2); + bsendmsg(ua, _("Pruned %s Files from %s Jobs for client %s from %s catalog.\n"), + ed1, ed2, client->hdr.name, client->catalog->hdr.name); bail_out: if (del.JobId) { diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index 552d8d9096..b2c4a50215 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -8,7 +8,7 @@ * * Kern Sibbald, February MMII * - * $Id: + * $Id$ */ /* diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index f0329268a6..5992c63f49 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -4,7 +4,7 @@ * * Kern Sibbald, October MMI * - * $Id: + * $Id$ */ /* diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index 8c3c63d9b9..ea1b9583f8 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -54,7 +54,7 @@ static char OKverify[] = "2000 OK verify\n"; static char OKlevel[] = "2000 OK level\n"; /* Forward referenced functions */ -static void verify_cleanup(JCR *jcr); +static void verify_cleanup(JCR *jcr, int TermCode); static void prt_fname(JCR *jcr); static int missing_handler(void *ctx, int num_fields, char **row); @@ -70,25 +70,11 @@ int do_verify(JCR *jcr) BSOCK *fd; JOB_DBR jr; int last_full_id; - CLIENT_DBR cr; - - memset(&cr, 0, sizeof(cr)); - cr.AutoPrune = jcr->client->AutoPrune; - cr.FileRetention = jcr->client->FileRetention; - cr.JobRetention = jcr->client->JobRetention; - strcpy(cr.Name, jcr->client->hdr.name); - if (jcr->client_name) { - free(jcr->client_name); - } - jcr->client_name = bstrdup(jcr->client->hdr.name); - if (!db_create_client_record(jcr->db, &cr)) { - Jmsg(jcr, M_ERROR, 0, _("Could not create Client record. %s"), - db_strerror(jcr->db)); - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + + if (!get_or_create_client_record(jcr)) { + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } - jcr->jr.ClientId = cr.ClientId; Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name); @@ -101,8 +87,7 @@ int do_verify(JCR *jcr) if (!db_find_last_full_verify(jcr->db, &jr)) { Jmsg(jcr, M_FATAL, 0, _("Unable to find last full verify. %s"), db_strerror(jcr->db)); - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } last_full_id = jr.JobId; @@ -114,8 +99,7 @@ int do_verify(JCR *jcr) jcr->jr.Level = jcr->level; if (!db_update_job_start_record(jcr->db, &jcr->jr)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } @@ -134,8 +118,7 @@ int do_verify(JCR *jcr) jr.JobId = last_full_id; if (!db_get_job_record(jcr->db, &jr)) { Jmsg(jcr, M_ERROR, 0, _("Could not get job record. %s"), db_strerror(jcr->db)); - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } Jmsg(jcr, M_INFO, 0, _("Verifying against Init JobId %d run %s\n"), @@ -148,8 +131,7 @@ int do_verify(JCR *jcr) */ jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */ if (!connect_to_file_daemon(jcr, 10, FDConnectTimeout, 1)) { - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } @@ -157,15 +139,13 @@ int do_verify(JCR *jcr) Dmsg0(30, ">filed: Send include list\n"); if (!send_include_list(jcr)) { - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } Dmsg0(30, ">filed: Send exclude list\n"); if (!send_exclude_list(jcr)) { - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } @@ -188,15 +168,13 @@ int do_verify(JCR *jcr) break; default: Emsg1(M_FATAL, 0, _("Unimplemented save level %d\n"), jcr->level); - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } Dmsg1(20, ">filed: %s", fd->msg); bnet_fsend(fd, levelcmd, level, " "); if (!response(fd, OKlevel, "Level")) { - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } @@ -205,8 +183,7 @@ int do_verify(JCR *jcr) */ bnet_fsend(fd, verifycmd); if (!response(fd, OKverify, "Verify")) { - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } @@ -227,12 +204,11 @@ int do_verify(JCR *jcr) } else { Emsg1(M_FATAL, 0, _("Unimplemented save level %d\n"), jcr->level); - jcr->JobStatus = JS_ErrorTerminated; - verify_cleanup(jcr); + verify_cleanup(jcr, JS_ErrorTerminated); return 0; } - verify_cleanup(jcr); + verify_cleanup(jcr, JS_Terminated); return 1; } @@ -240,40 +216,28 @@ int do_verify(JCR *jcr) * Release resources allocated during backup. * */ -static void verify_cleanup(JCR *jcr) +static void verify_cleanup(JCR *jcr, int TermCode) { char sdt[50], edt[50]; char ec1[30]; char term_code[100]; char *term_msg; int msg_type; - int TermCode; int last_full_id; Dmsg0(100, "Enter verify_cleanup()\n"); last_full_id = jcr->jr.JobId; + jcr->JobStatus = TermCode; - - if (jcr->jr.EndTime == 0) { - jcr->jr.EndTime = time(NULL); - } - jcr->end_time = jcr->jr.EndTime; - jcr->jr.JobId = jcr->JobId; - jcr->jr.JobStatus = jcr->JobStatus; - TermCode = jcr->JobStatus; - - if (!db_update_job_end_record(jcr->db, &jcr->jr)) { - Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"), - db_strerror(jcr->db)); - } + update_job_end_record(jcr); msg_type = M_INFO; /* by default INFO message */ switch (TermCode) { case JS_Terminated: term_msg = _("Verify OK"); break; - case JS_Errored: + case JS_ErrorTerminated: term_msg = _("*** Verify Error ***"); msg_type = M_ERROR; /* Generate error message */ break; diff --git a/bacula/src/filed/filed.c b/bacula/src/filed/filed.c index 5a40ade9fb..83dc02ed44 100644 --- a/bacula/src/filed/filed.c +++ b/bacula/src/filed/filed.c @@ -48,6 +48,7 @@ int win32_client = 0; static char *configfile = NULL; static int foreground = 0; static workq_t dir_workq; /* queue of work from Director */ +static CLIENT *me; /* my resource */ static void usage() { @@ -78,11 +79,11 @@ int main (int argc, char *argv[]) int ch; int no_signals = FALSE; int test_config = FALSE; - CLIENT *me; /* my resource */ DIRRES *director; init_stack_dump(); my_name_is(argc, argv, "filed"); + init_msg(NULL, NULL); daemon_start_time = time(NULL); memset(&last_job, 0, sizeof(last_job)); @@ -143,8 +144,6 @@ int main (int argc, char *argv[]) configfile = bstrdup(CONFIG_FILE); } - - init_msg(NULL, NULL); parse_config(configfile); LockRes(); @@ -162,7 +161,17 @@ int main (int argc, char *argv[]) Emsg1(M_ABORT, 0, _("No File daemon resource defined in %s\n\ Without that I don't know who I am :-(\n"), configfile); } else { - my_name_is(0, (char **)NULL, me->hdr.name); + my_name_is(0, NULL, me->hdr.name); + if (!me->messages) { + LockRes(); + me->messages = (MSGS *)GetNextRes(R_MSGS, NULL); + UnlockRes(); + if (!me->messages) { + Emsg1(M_ABORT, 0, _("No Messages resource defined in %s\n"), configfile); + } + } + close_msg(NULL); /* close temp message handler */ + init_msg(NULL, me->messages); /* open user specified message handler */ } working_directory = me->working_directory; @@ -175,6 +184,8 @@ Without that I don't know who I am :-(\n"), configfile); init_stack_dump(); /* set new pid */ } + create_pid_file(me->pid_directory, "bacula-fd", me->FDport); + #ifdef BOMB me += 1000000; #endif @@ -198,9 +209,10 @@ void terminate_filed(int sig) if (debug_level > 5) { print_memory_pool_stats(); } + delete_pid_file(me->pid_directory, "bacula-fd", me->FDport); free_config_resources(); - close_memory_pool(); /* free memory in pool */ term_msg(); + close_memory_pool(); /* release free memory in pool */ sm_dump(False); /* dump orphaned buffers */ exit(1); } diff --git a/bacula/src/filed/filed_conf.c b/bacula/src/filed/filed_conf.c index 708fafbd2b..21a756765e 100644 --- a/bacula/src/filed/filed_conf.c +++ b/bacula/src/filed/filed_conf.c @@ -72,9 +72,10 @@ static struct res_items cli_items[] = { {"name", store_name, ITEM(res_client.hdr.name), 0, ITEM_REQUIRED, 0}, {"description", store_str, ITEM(res_client.hdr.desc), 0, 0, 0}, {"fdport", store_pint, ITEM(res_client.FDport), 0, ITEM_REQUIRED, 0}, - {"workingdirectory", store_dir, ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0}, - {"piddirectory", store_dir, ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0}, + {"workingdirectory", store_dir, ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0}, + {"piddirectory", store_dir, ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0}, {"subsysdirectory", store_dir, ITEM(res_client.subsys_directory), 0, ITEM_REQUIRED, 0}, + {"messages", store_res, ITEM(res_client.messages), R_MSGS, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -128,6 +129,10 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); + if (res->res_msgs.mail_cmd) + sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd); + if (res->res_msgs.operator_cmd) + sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd); break; default: sendit(sock, "Unknown resource type %d\n", type); @@ -182,12 +187,16 @@ void free_resource(int type) free(res->res_msgs.mail_cmd); if (res->res_msgs.operator_cmd) free(res->res_msgs.operator_cmd); + free_msgs_res((MSGS *)res); /* free message resource */ + res = NULL; break; default: printf("Unknown resource type %d\n", type); } /* Common stuff again -- free the resource, recurse to next one */ - free(res); + if (res) { + free(res); + } resources[rindex].res_head = nres; if (nres) { free_resource(type); @@ -227,9 +236,15 @@ void save_resource(int type, struct res_items *items, int pass) /* Resources not containing a resource */ case R_MSGS: case R_DIRECTOR: - case R_CLIENT: break; + /* Resources containing another resource */ + case R_CLIENT: + if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) { + Emsg1(M_ABORT, 0, "Cannot find Client resource %s\n", res_all.res_dir.hdr.name); + } + res->res_client.messages = res_all.res_client.messages; + break; default: Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type); error = 1; @@ -266,7 +281,7 @@ void save_resource(int type, struct res_items *items, int pass) } /* Common */ if (!error) { - res = (URES *) malloc(size); + res = (URES *)malloc(size); memcpy(res, &res_all, size); res->res_dir.hdr.next = resources[rindex].res_head; resources[rindex].res_head = (RES *)res; diff --git a/bacula/src/filed/filed_conf.h b/bacula/src/filed/filed_conf.h index 3edffcc3f6..c2547a99eb 100644 --- a/bacula/src/filed/filed_conf.h +++ b/bacula/src/filed/filed_conf.h @@ -26,37 +26,38 @@ /* * Resource codes -- they must be sequential for indexing */ -#define R_FIRST 1001 +#define R_FIRST 1001 -#define R_DIRECTOR 1001 -#define R_CLIENT 1002 -#define R_MSGS 1003 +#define R_DIRECTOR 1001 +#define R_CLIENT 1002 +#define R_MSGS 1003 -#define R_LAST R_MSGS +#define R_LAST R_MSGS /* * Some resource attributes */ -#define R_NAME 1020 -#define R_ADDRESS 1021 -#define R_PASSWORD 1022 -#define R_TYPE 1023 +#define R_NAME 1020 +#define R_ADDRESS 1021 +#define R_PASSWORD 1022 +#define R_TYPE 1023 /* Definition of the contents of each Resource */ struct s_res_dir { - RES hdr; - char *password; /* Director password */ - char *address; /* Director address or zero */ + RES hdr; + char *password; /* Director password */ + char *address; /* Director address or zero */ }; typedef struct s_res_dir DIRRES; struct s_res_client { - RES hdr; - int FDport; /* where we listen for Directors */ + RES hdr; + int FDport; /* where we listen for Directors */ char *working_directory; char *pid_directory; char *subsys_directory; + struct s_res_msgs *messages; /* daemon message handler */ }; typedef struct s_res_client CLIENT; @@ -66,9 +67,9 @@ typedef struct s_res_client CLIENT; * resource structure definitions. */ union u_res { - struct s_res_dir res_dir; - struct s_res_client res_client; - struct s_res_msgs res_msgs; + struct s_res_dir res_dir; + struct s_res_client res_client; + struct s_res_msgs res_msgs; RES hdr; }; diff --git a/bacula/src/filed/win32/winmain.cpp b/bacula/src/filed/win32/winmain.cpp index 7c54033d46..938aba1d63 100755 --- a/bacula/src/filed/win32/winmain.cpp +++ b/bacula/src/filed/win32/winmain.cpp @@ -264,7 +264,7 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) } - // Now enter the message handling loop until told to quit! + // Now enter the Windows message handling loop until told to quit! MSG msg; while (GetMessage(&msg, NULL, 0,0) ) { TranslateMessage(&msg); @@ -281,7 +281,7 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) // Tell the service manager that we've stopped. ReportStatus(SERVICE_STOPPED, g_error, 0); } - kill(main_pid, SIGTERM); + kill(main_pid, SIGTERM); /* ask main thread to terminate */ _exit(0); } diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index e25ed3ab86..48b0eae699 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -46,6 +46,8 @@ #define JT_VERIFY 'V' #define JT_RESTORE 'R' #define JT_CONSOLE 'C' /* console program */ +#define JT_ADMIN 'D' /* admin job */ +#define JT_ARCHIVE 'A' /* Job Status */ #define JS_Created 'C' @@ -95,12 +97,10 @@ struct s_jcr { time_t start_time; /* when job actually started */ time_t run_time; /* used for computing speed */ time_t end_time; /* job end time */ - char *VolumeName; /* Volume name desired -- pool_memory */ + POOLMEM *VolumeName; /* Volume name desired -- pool_memory */ char *client_name; /* client name */ char *sd_auth_key; /* SD auth key */ MSGS *msgs; /* Message resource */ - DEST *dest_chain; /* Job message destination chain */ - char send_msg[nbytes_for_bits(M_MAX+1)]; /* message bit mask */ /* Daemon specific part of JCR */ /* This should be empty in the library */ diff --git a/bacula/src/lib/mem_pool.c b/bacula/src/lib/mem_pool.c index 251d5dcc10..1762cea4bc 100644 --- a/bacula/src/lib/mem_pool.c +++ b/bacula/src/lib/mem_pool.c @@ -69,9 +69,9 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; #define HEAD_SIZE BALIGN(sizeof(struct abufhead)) -extern void *sm_malloc(char *fname, int lineno, int nbytes); +extern POOLMEM *sm_malloc(char *fname, int lineno, int nbytes); -void *sm_get_pool_memory(char *fname, int lineno, int pool) +POOLMEM *sm_get_pool_memory(char *fname, int lineno, int pool) { struct abufhead *buf; @@ -90,7 +90,7 @@ void *sm_get_pool_memory(char *fname, int lineno, int pool) V(mutex); Dmsg3(150, "sm_get_pool_memory reuse %x to %s:%d\n", buf, fname, lineno); sm_new_owner(fname, lineno, (char *)buf); - return (void *)((char *)buf+HEAD_SIZE); + return (POOLMEM *)((char *)buf+HEAD_SIZE); } if ((buf = (struct abufhead *) sm_malloc(fname, lineno, pool_ctl[pool].size+HEAD_SIZE)) == NULL) { @@ -105,11 +105,11 @@ void *sm_get_pool_memory(char *fname, int lineno, int pool) } V(mutex); Dmsg3(150, "sm_get_pool_memory give %x to %s:%d\n", buf, fname, lineno); - return (void *)((char *)buf+HEAD_SIZE); + return (POOLMEM *)((char *)buf+HEAD_SIZE); } /* Get nonpool memory of size requested */ -void *sm_get_memory(char *fname, int lineno, size_t size) +POOLMEM *sm_get_memory(char *fname, int lineno, size_t size) { struct abufhead *buf; int pool = 0; @@ -124,12 +124,12 @@ void *sm_get_memory(char *fname, int lineno, size_t size) pool_ctl[pool].in_use++; if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) pool_ctl[pool].max_used = pool_ctl[pool].in_use; - return (void *)(((char *)buf)+HEAD_SIZE); + return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } #else -void *get_pool_memory(int pool) +POOLMEM *get_pool_memory(int pool) { struct abufhead *buf; @@ -138,7 +138,7 @@ void *get_pool_memory(int pool) buf = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf->next; V(mutex); - return (void *)((char *)buf+HEAD_SIZE); + return (POOLMEM *)((char *)buf+HEAD_SIZE); } if ((buf=malloc(pool_ctl[pool].size+HEAD_SIZE)) == NULL) { @@ -153,11 +153,11 @@ void *get_pool_memory(int pool) pool_ctl[pool].max_used = pool_ctl[pool].in_use; } V(mutex); - return (void *)(((char *)buf)+HEAD_SIZE); + return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } /* Get nonpool memory of size requested */ -void *get_memory(size_t size) +POOLMEM *get_memory(size_t size) { struct abufhead *buf; int pool = 0; @@ -172,14 +172,14 @@ void *get_memory(size_t size) if (pool_ctl[pool].in_use > pool_ctl[pool].max_used) { pool_ctl[pool].max_used = pool_ctl[pool].in_use; } - return (void *)(((char *)buf)+HEAD_SIZE); + return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } #endif /* SMARTALLOC */ /* Free a memory buffer */ -void free_pool_memory(void *obuf) +void free_pool_memory(POOLMEM *obuf) { struct abufhead *buf; int pool; @@ -202,7 +202,7 @@ void free_pool_memory(void *obuf) /* Return the size of a memory buffer */ -size_t sizeof_pool_memory(void *obuf) +size_t sizeof_pool_memory(POOLMEM *obuf) { char *cp = (char *)obuf; @@ -213,7 +213,7 @@ size_t sizeof_pool_memory(void *obuf) } /* Realloc pool memory buffer */ -void *realloc_pool_memory(void *obuf, size_t size) +POOLMEM *realloc_pool_memory(POOLMEM *obuf, size_t size) { char *cp = (char *)obuf; void *buf; @@ -235,10 +235,10 @@ void *realloc_pool_memory(void *obuf, size_t size) } V(mutex); sm_check(__FILE__, __LINE__, False); - return (void *)(((char *)buf)+HEAD_SIZE); + return (POOLMEM *)(((char *)buf)+HEAD_SIZE); } -void *check_pool_memory_size(void *obuf, size_t size) +POOLMEM *check_pool_memory_size(POOLMEM *obuf, size_t size) { sm_check(__FILE__, __LINE__, False); ASSERT(obuf); @@ -263,6 +263,7 @@ void close_memory_pool() free((char *)buf); buf = next; } + pool_ctl[i].free_buf = NULL; } V(mutex); } diff --git a/bacula/src/lib/mem_pool.h b/bacula/src/lib/mem_pool.h index 9bccd8b058..17f8d5671b 100644 --- a/bacula/src/lib/mem_pool.h +++ b/bacula/src/lib/mem_pool.h @@ -26,22 +26,22 @@ #ifdef SMARTALLOC #define get_pool_memory(pool) sm_get_pool_memory(__FILE__, __LINE__, pool) -extern void *sm_get_pool_memory(char *file, int line, int pool); +extern POOLMEM *sm_get_pool_memory(char *file, int line, int pool); #define get_memory(size) sm_get_memory(__FILE__, __LINE__, size) -extern void *sm_get_memory(char *fname, int line, size_t size); +extern POOLMEM *sm_get_memory(char *fname, int line, size_t size); #else -extern void *get_pool_memory(int pool); -extern void *get_memory(size_t size); +extern POOLMEM *get_pool_memory(int pool); +extern POOLMEM *get_memory(size_t size); #endif #define free_memory(x) free_pool_memory(x) -extern void free_pool_memory(void *buf); -extern size_t sizeof_pool_memory(void *buf); -extern void *realloc_pool_memory(void *buf, size_t size); -extern void *check_pool_memory_size(void *buf, size_t size); +extern void free_pool_memory(POOLMEM *buf); +extern size_t sizeof_pool_memory(POOLMEM *buf); +extern POOLMEM *realloc_pool_memory(POOLMEM *buf, size_t size); +extern POOLMEM *check_pool_memory_size(POOLMEM *buf, size_t size); extern void close_memory_pool(); extern void print_memory_pool_stats(); diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index ec5cb38061..41e804e37d 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -46,7 +46,10 @@ FILE *con_fd = NULL; /* Imported functions */ -static MSGS daemon_msg; /* global messages */ + +/* Static storage */ + +static MSGS *daemon_msgs; /* global messages */ /* * Set daemon name. Also, find canonical execution @@ -120,35 +123,64 @@ void my_name_is(int argc, char *argv[], char *name) } } -/* Initialize message handler */ +/* + * Initialize message handler for a daemon or a Job + * + * NULL for jcr -> initialize global messages for daemon + * non-NULL -> initialize jcr using Message resource + */ void init_msg(void *vjcr, MSGS *msg) { DEST *d, *dnew, *temp_chain = NULL; JCR *jcr = (JCR *)vjcr; - if (!msg) { /* If nothing specified, use */ - msg = &daemon_msg; /* daemon global message resource */ + /* + * If msg is NULL, initialize global chain for STDOUT and syslog + */ + if (msg == NULL) { + int i; + daemon_msgs = (MSGS *)malloc(sizeof(MSGS)); + memset(daemon_msgs, 0, sizeof(MSGS)); + for (i=1; i<=M_MAX; i++) { + add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL); + add_msg_dest(daemon_msgs, MD_SYSLOG, i, NULL, NULL); + } + Dmsg1(050, "Create daemon global message resource 0x%x\n", daemon_msgs); + return; } - if (!jcr) { - memset(msg, 0, sizeof(msg)); /* init daemon global message */ - } else { /* init for job */ - /* Walk down the global chain duplicating it - * for the current Job. No need to duplicate - * the attached strings. - */ - for (d=daemon_msg.dest_chain; d; d=d->next) { - dnew = (DEST *) malloc(sizeof(DEST)); - memcpy(dnew, d, sizeof(DEST)); - dnew->next = temp_chain; - dnew->fd = NULL; - dnew->mail_filename = NULL; - temp_chain = dnew; + + /* + * Walk down the message resource chain duplicating it + * for the current Job. + */ + for (d=msg->dest_chain; d; d=d->next) { + dnew = (DEST *) malloc(sizeof(DEST)); + memcpy(dnew, d, sizeof(DEST)); + dnew->next = temp_chain; + dnew->fd = NULL; + dnew->mail_filename = NULL; + if (d->mail_cmd) { + dnew->mail_cmd = bstrdup(d->mail_cmd); + } + if (d->where) { + dnew->where = bstrdup(d->where); } + temp_chain = dnew; + } - jcr->dest_chain = temp_chain; - memcpy(jcr->send_msg, daemon_msg.send_msg, sizeof(daemon_msg.send_msg)); + if (jcr) { + jcr->msgs = (MSGS *)malloc(sizeof(MSGS)); + memset(jcr->msgs, 0, sizeof(MSGS)); + jcr->msgs->dest_chain = temp_chain; + memcpy(jcr->msgs->send_msg, msg->send_msg, sizeof(msg->send_msg)); + } else { + daemon_msgs = (MSGS *)malloc(sizeof(MSGS)); + memset(daemon_msgs, 0, sizeof(MSGS)); + daemon_msgs->dest_chain = temp_chain; + memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg)); } + Dmsg2(050, "Copy message resource 0x%x to 0x%x\n", msg, temp_chain); } /* Initialize so that the console (User Agent) can @@ -187,27 +219,27 @@ void init_console_msg(char *wd) void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mail_cmd) { DEST *d; - - /* First search the existing chain and see if we + /* + * First search the existing chain and see if we * can simply add this msg_type to an existing entry. */ - for (d=daemon_msg.dest_chain; d; d=d->next) { + for (d=msg->dest_chain; d; d=d->next) { if (dest_code == d->dest_code && ((where == NULL && d->where == NULL) || (strcmp(where, d->where) == 0))) { Dmsg4(200, "Add to existing d=%x msgtype=%d destcode=%d where=%s\n", d, msg_type, dest_code, where); set_bit(msg_type, d->msg_types); - set_bit(msg_type, daemon_msg.send_msg); /* set msg_type bit in our local */ + set_bit(msg_type, msg->send_msg); /* set msg_type bit in our local */ return; } } /* Not found, create a new entry */ - d = (DEST *) malloc(sizeof(DEST)); + d = (DEST *)malloc(sizeof(DEST)); memset(d, 0, sizeof(DEST)); - d->next = daemon_msg.dest_chain; + d->next = msg->dest_chain; d->dest_code = dest_code; set_bit(msg_type, d->msg_types); /* set type bit in structure */ - set_bit(msg_type, daemon_msg.send_msg); /* set type bit in our local */ + set_bit(msg_type, msg->send_msg); /* set type bit in our local */ if (where) { d->where = bstrdup(where); } @@ -217,7 +249,7 @@ void add_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where, char *mai Dmsg5(200, "add new d=%x msgtype=%d destcode=%d where=%s mailcmd=%s\n", d, msg_type, dest_code, where?where:"(null)", d->mail_cmd?d->mail_cmd:"(null)"); - daemon_msg.dest_chain = d; + msg->dest_chain = d; } /* @@ -229,7 +261,7 @@ void rem_msg_dest(MSGS *msg, int dest_code, int msg_type, char *where) { DEST *d; - for (d=daemon_msg.dest_chain; d; d=d->next) { + for (d=msg->dest_chain; d; d=d->next) { Dmsg2(200, "Remove_msg_dest d=%x where=%s\n", d, d->where); if (bit_is_set(msg_type, d->msg_types) && (dest_code == d->dest_code) && ((where == NULL && d->where == NULL) || @@ -457,36 +489,39 @@ static FILE *open_mail_pipe(JCR *jcr, char **cmd, DEST *d) Dmsg1(200, "mailcmd=%s\n", cmd); pfd = popen(*cmd, "w"); if (!pfd) { - Emsg2(M_ERROR, 0, "popen %s failed: ERR=%s\n", cmd, strerror(errno)); - if (jcr) { - Jmsg(jcr, M_ERROR, 0, "mail popen %s failed: ERR=%s\n", cmd, strerror(errno)); - } + Jmsg(jcr, M_ERROR, 0, "mail popen %s failed: ERR=%s\n", cmd, strerror(errno)); } return pfd; } /* - * Close the messages for this job, which means to close + * Close the messages for this Messages resource, which means to close * any open files, and dispatch any pending email messages. - * - * This closes messages only for this job, other jobs can - * still send messages. - * - * Note, we free our local message destination chain, but - * the global chain remains allowing other jobs to - * start. */ void close_msg(void *vjcr) { - DEST *d, *old; + MSGS *msgs; + JCR *jcr = (JCR *)vjcr; + DEST *d; FILE *pfd; - char *cmd, *line; + POOLMEM *cmd, *line; int len; - JCR *jcr = (JCR *)vjcr; - Dmsg0(200, "Close_msg\n"); - cmd = (char *)get_pool_memory(PM_MESSAGE); - for (d=jcr->dest_chain; d; ) { + Dmsg1(050, "Close_msg jcr=0x%x\n", jcr); + + if (jcr == NULL) { /* NULL -> global chain */ + msgs = daemon_msgs; + daemon_msgs = NULL; + } else { + msgs = jcr->msgs; + jcr->msgs = NULL; + } + if (msgs == NULL) { + return; + } + Dmsg1(050, "close msg resource at 0x%x\n", msgs); + cmd = get_pool_memory(PM_MESSAGE); + for (d=msgs->dest_chain; d; ) { if (d->fd) { switch (d->dest_code) { case MD_FILE: @@ -500,7 +535,7 @@ void close_msg(void *vjcr) if (!d->fd) { break; } - if (d->dest_code == MD_MAIL_ON_ERROR && + if (d->dest_code == MD_MAIL_ON_ERROR && jcr && jcr->JobStatus == JS_Terminated) { goto rem_temp_file; } @@ -510,7 +545,7 @@ void close_msg(void *vjcr) goto rem_temp_file; } len = d->max_len+10; - line = (char *)get_memory(len); + line = get_memory(len); rewind(d->fd); while (fgets(line, len, d->fd)) { fputs(line, pfd); @@ -529,43 +564,48 @@ rem_temp_file: } d->fd = NULL; } + d = d->next; /* point to next buffer */ + } + free_pool_memory(cmd); + + free_msgs_res(msgs); +} + +/* + * Free memory associated with Messages resource + */ +void free_msgs_res(MSGS *msgs) +{ + DEST *d, *old; + + for (d=msgs->dest_chain; d; ) { + if (d->where) { + free(d->where); + } + if (d->mail_cmd) { + free(d->mail_cmd); + } old = d; /* save pointer to release */ d = d->next; /* point to next buffer */ free(old); /* free the destination item */ } - free_pool_memory(cmd); - jcr->dest_chain = NULL; + msgs->dest_chain = NULL; + free(msgs); } /* * Terminate the message handler for good. * Release the global destination chain. + * + * Also, clean up a few other items (cons, exepath). Note, + * these really should be done elsewhere. */ void term_msg() { - DEST *d, *n; - - for (d=daemon_msg.dest_chain; d; d=n) { - if (d->fd) { - if (d->dest_code == MD_FILE || d->dest_code == MD_APPEND) { - fclose(d->fd); /* close open file descriptor */ - d->fd = NULL; - } else if (d->dest_code == MD_MAIL || d->dest_code == MD_MAIL_ON_ERROR) { - fclose(d->fd); - d->fd = NULL; - unlink(d->mail_filename); - free_pool_memory(d->mail_filename); - d->mail_filename = NULL; - } - } - n = d->next; - if (d->where) - free(d->where); /* free destination address */ - if (d->mail_cmd) - free(d->mail_cmd); - free(d); - } + Dmsg0(100, "Enter term_msg\n"); + close_msg(NULL); /* close global chain */ + daemon_msgs = NULL; if (con_fd) { fflush(con_fd); fclose(con_fd); @@ -589,9 +629,11 @@ void term_msg() void dispatch_message(void *vjcr, int type, int level, char *buf) { DEST *d; - char cmd[MAXSTRING], *mcmd; + char cmd[MAXSTRING]; + POOLMEM *mcmd; JCR *jcr = (JCR *) vjcr; int len; + MSGS *msgs; Dmsg2(200, "Enter dispatch_msg type=%d msg=%s\n", type, buf); @@ -600,12 +642,14 @@ void dispatch_message(void *vjcr, int type, int level, char *buf) } /* Now figure out where to send the message */ + msgs = NULL; if (jcr) { - d = jcr->dest_chain; /* use job message chain */ - } else { - d = daemon_msg.dest_chain; /* use global chain */ + msgs = jcr->msgs; + } + if (msgs == NULL) { + msgs = daemon_msgs; } - for ( ; d; d=d->next) { + for (d=msgs->dest_chain; d; d=d->next) { if (bit_is_set(type, d->msg_types)) { switch (d->dest_code) { case MD_CONSOLE: @@ -639,7 +683,7 @@ void dispatch_message(void *vjcr, int type, int level, char *buf) break; case MD_OPERATOR: Dmsg1(200, "OPERATOR for following err: %s\n", buf); - mcmd = (char *) get_pool_memory(PM_MESSAGE); + mcmd = get_pool_memory(PM_MESSAGE); d->fd = open_mail_pipe(jcr, &mcmd, d); free_pool_memory(mcmd); if (d->fd) { @@ -771,7 +815,7 @@ d_msg(char *file, int line, int level, char *fmt,...) void e_msg(char *file, int line, int type, int level, char *fmt,...) { - char buf[1000]; + char buf[2000]; va_list arg_ptr; int i; @@ -779,7 +823,8 @@ e_msg(char *file, int line, int type, int level, char *fmt,...) * Check if we have a message destination defined. * We always report M_ABORT */ - if (type != M_ABORT && !bit_is_set(type, daemon_msg.send_msg)) + if (!daemon_msgs || (type != M_ABORT && + !bit_is_set(type, daemon_msgs->send_msg))) return; /* no destination */ switch (type) { case M_ABORT: @@ -841,7 +886,7 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...) * Check if we have a message destination defined. * We always report M_ABORT */ - if (type != M_ABORT && !bit_is_set(type, jcr->send_msg)) { + if (type != M_ABORT && jcr->msgs && !bit_is_set(type, jcr->msgs->send_msg)) { Dmsg1(200, "No bit set for type %d\n", type); return; /* no destination */ } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index cc114032ec..470c2560d1 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -22,130 +22,131 @@ */ /* base64.c */ -void base64_init __PROTO((void)); -int to_base64 __PROTO((intmax_t value, char *where)); -int from_base64 __PROTO((intmax_t *value, char *where)); -void encode_stat __PROTO((char *buf, struct stat *statp)); -void decode_stat __PROTO((char *buf, struct stat *statp)); -int bin_to_base64 __PROTO((char *buf, char *bin, int len)); +void base64_init __PROTO((void)); +int to_base64 __PROTO((intmax_t value, char *where)); +int from_base64 __PROTO((intmax_t *value, char *where)); +void encode_stat __PROTO((char *buf, struct stat *statp)); +void decode_stat __PROTO((char *buf, struct stat *statp)); +int bin_to_base64 __PROTO((char *buf, char *bin, int len)); /* bmisc.c */ -void *b_malloc (char *file, int line, size_t size); +void *b_malloc (char *file, int line, size_t size); #ifndef DEBUG -void *bmalloc (size_t size); +void *bmalloc (size_t size); #endif -void *brealloc (void *buf, size_t size); -void *bcalloc (size_t size1, size_t size2); -int bsnprintf (char *str, size_t size, const char *format, ...); -int bvsnprintf (char *str, size_t size, const char *format, va_list ap); -int pool_sprintf (char *pool_buf, char *fmt, ...); -int create_pid_file (char *dir, char *progname, int port, char *errmsg); -int delete_pid_file (char *dir, char *progname, int port); +void *brealloc (void *buf, size_t size); +void *bcalloc (size_t size1, size_t size2); +int bsnprintf (char *str, size_t size, const char *format, ...); +int bvsnprintf (char *str, size_t size, const char *format, va_list ap); +int pool_sprintf (char *pool_buf, char *fmt, ...); +void create_pid_file (char *dir, char *progname, int port); +int delete_pid_file (char *dir, char *progname, int port); /* bnet.c */ -int32_t bnet_recv __PROTO((BSOCK *bsock)); -int bnet_send __PROTO((BSOCK *bsock)); -int bnet_fsend (BSOCK *bs, char *fmt, ...); -int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw); -int bnet_sig (BSOCK *bs, int sig); -BSOCK * bnet_connect (void *jcr, int retry_interval, - int max_retry_time, char *name, char *host, char *service, - int port, int verbose); -int bnet_wait_data (BSOCK *bsock, int sec); -void bnet_close __PROTO((BSOCK *bsock)); -BSOCK * init_bsock __PROTO((int sockfd, char *who, char *ip, int port)); -BSOCK * dup_bsock __PROTO((BSOCK *bsock)); -void term_bsock __PROTO((BSOCK *bsock)); -char * bnet_strerror __PROTO((BSOCK *bsock)); -char * bnet_sig_to_ascii __PROTO((BSOCK *bsock)); -int bnet_wait_data __PROTO((BSOCK *bsock, int sec)); +int32_t bnet_recv __PROTO((BSOCK *bsock)); +int bnet_send __PROTO((BSOCK *bsock)); +int bnet_fsend (BSOCK *bs, char *fmt, ...); +int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw); +int bnet_sig (BSOCK *bs, int sig); +BSOCK * bnet_connect (void *jcr, int retry_interval, + int max_retry_time, char *name, char *host, char *service, + int port, int verbose); +int bnet_wait_data (BSOCK *bsock, int sec); +void bnet_close __PROTO((BSOCK *bsock)); +BSOCK * init_bsock __PROTO((int sockfd, char *who, char *ip, int port)); +BSOCK * dup_bsock __PROTO((BSOCK *bsock)); +void term_bsock __PROTO((BSOCK *bsock)); +char * bnet_strerror __PROTO((BSOCK *bsock)); +char * bnet_sig_to_ascii __PROTO((BSOCK *bsock)); +int bnet_wait_data __PROTO((BSOCK *bsock, int sec)); /* cram-md5.c */ int cram_md5_get_auth(BSOCK *bs, char *password); int cram_md5_auth(BSOCK *bs, char *password); void hmac_md5(uint8_t* text, int text_len, uint8_t* key, - int key_len, uint8_t *hmac); + int key_len, uint8_t *hmac); /* create_file.c */ int create_file(void *jcr, char *fname, char *ofile, char *lname, - int type, struct stat *statp, int *ofd); + int type, struct stat *statp, int *ofd); int set_statp(void *jcr, char *fname, char *ofile, char *lname, int type, - struct stat *statp); + struct stat *statp); /* crc32.c */ uint32_t bcrc32(uint8_t *buf, int len); /* daemon.c */ -void daemon_start __PROTO(()); +void daemon_start __PROTO(()); /* lex.c */ -LEX * lex_close_file __PROTO((LEX *lf)); -LEX * lex_open_file __PROTO((LEX *lf, char *fname)); -int lex_get_char __PROTO((LEX *lf)); -void lex_unget_char __PROTO((LEX *lf)); -char * lex_tok_to_str __PROTO((int token)); -int lex_get_token __PROTO((LEX *lf)); +LEX * lex_close_file __PROTO((LEX *lf)); +LEX * lex_open_file __PROTO((LEX *lf, char *fname)); +int lex_get_char __PROTO((LEX *lf)); +void lex_unget_char __PROTO((LEX *lf)); +char * lex_tok_to_str __PROTO((int token)); +int lex_get_token __PROTO((LEX *lf)); /* makepath.c */ int make_path( - void *jcr, - const char *argpath, - int mode, - int parent_mode, - uid_t owner, - gid_t group, - int preserve_existing, - char *verbose_fmt_string); + void *jcr, + const char *argpath, + int mode, + int parent_mode, + uid_t owner, + gid_t group, + int preserve_existing, + char *verbose_fmt_string); /* message.c */ -void my_name_is __PROTO((int argc, char *argv[], char *name)); -void init_msg __PROTO((void *jcr, MSGS *msg)); -void term_msg __PROTO((void)); -void close_msg __PROTO((void *jcr)); -void add_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where, char *dest_code)); -void rem_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where)); -void Jmsg (void *jcr, int type, int level, char *fmt, ...); -void dispatch_message __PROTO((void *jcr, int type, int level, char *buf)); -void init_console_msg __PROTO((char *wd)); +void my_name_is __PROTO((int argc, char *argv[], char *name)); +void init_msg __PROTO((void *jcr, MSGS *msg)); +void term_msg __PROTO((void)); +void close_msg __PROTO((void *jcr)); +void add_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where, char *dest_code)); +void rem_msg_dest __PROTO((MSGS *msg, int dest, int type, char *where)); +void Jmsg (void *jcr, int type, int level, char *fmt, ...); +void dispatch_message __PROTO((void *jcr, int type, int level, char *buf)); +void init_console_msg __PROTO((char *wd)); +void free_msgs_res(MSGS *msgs); /* bnet_server.c */ -void bnet_thread_server(int port, int max_clients, workq_t *client_wq, - void handle_client_request(void *bsock)); -void bnet_server __PROTO((int port, void handle_client_request(BSOCK *bsock))); -int net_connect __PROTO((int port)); -BSOCK * bnet_bind __PROTO((int port)); -BSOCK * bnet_accept __PROTO((BSOCK *bsock, char *who)); +void bnet_thread_server(int port, int max_clients, workq_t *client_wq, + void handle_client_request(void *bsock)); +void bnet_server __PROTO((int port, void handle_client_request(BSOCK *bsock))); +int net_connect __PROTO((int port)); +BSOCK * bnet_bind __PROTO((int port)); +BSOCK * bnet_accept __PROTO((BSOCK *bsock, char *who)); /* signal.c */ -void init_signals __PROTO((void terminate(int sig))); -void init_stack_dump (void); +void init_signals __PROTO((void terminate(int sig))); +void init_stack_dump (void); /* util.c */ -void lcase __PROTO((char *str)); -void bash_spaces __PROTO((char *str)); -void unbash_spaces __PROTO((char *str)); -void strip_trailing_junk __PROTO((char *str)); -void strip_trailing_slashes __PROTO((char *dir)); -int skip_spaces __PROTO((char **msg)); -int skip_nonspaces __PROTO((char **msg)); -int fstrsch __PROTO((char *a, char *b)); -char * encode_time __PROTO((time_t time, char *buf)); -char * encode_mode __PROTO((mode_t mode, char *buf)); -char * edit_uint64_with_commas __PROTO((uint64_t val, char *buf)); -char * add_commas __PROTO((char *val, char *buf)); -char * edit_uint64 (uint64_t val, char *buf); -int do_shell_expansion (char *name); -int is_a_number (const char *num); -int string_to_btime(char *str, btime_t *value); -char *edit_btime(btime_t val, char *buf); +void lcase __PROTO((char *str)); +void bash_spaces __PROTO((char *str)); +void unbash_spaces __PROTO((char *str)); +void strip_trailing_junk __PROTO((char *str)); +void strip_trailing_slashes __PROTO((char *dir)); +int skip_spaces __PROTO((char **msg)); +int skip_nonspaces __PROTO((char **msg)); +int fstrsch __PROTO((char *a, char *b)); +char * encode_time __PROTO((time_t time, char *buf)); +char * encode_mode __PROTO((mode_t mode, char *buf)); +char * edit_uint64_with_commas __PROTO((uint64_t val, char *buf)); +char * add_commas __PROTO((char *val, char *buf)); +char * edit_uint64 (uint64_t val, char *buf); +int do_shell_expansion (char *name); +int is_a_number (const char *num); +int string_to_btime(char *str, btime_t *value); +char *edit_btime(btime_t val, char *buf); /* - *void print_ls_output __PROTO((char *fname, char *lname, int type, struct stat *statp)); + *void print_ls_output __PROTO((char *fname, char *lname, int type, struct stat *statp)); */ /* watchdog.c */ diff --git a/bacula/src/lib/signal.c b/bacula/src/lib/signal.c index de9fdfe691..5cb3c147be 100644 --- a/bacula/src/lib/signal.c +++ b/bacula/src/lib/signal.c @@ -64,7 +64,7 @@ static void signal_handler(int sig) if (already_dead) { _exit(1); } - already_dead = TRUE; + already_dead = sig; if (sig == SIGTERM) { Emsg1(M_TERM, -1, "Shutting down Bacula service: %s ...\n", my_name); } else { @@ -78,7 +78,7 @@ static void signal_handler(int sig) static char btpath[400]; pid_t pid; - Dmsg1(000, "Kaboom! Got signal %d. Attempting traceback\n", sig); + fprintf(stderr, "Kaboom! Got signal %d. Attempting traceback.\n", sig); if (strlen(exepath) + 12 > (int)sizeof(btpath)) { strcpy(btpath, "btraceback"); } else { @@ -97,6 +97,7 @@ static void signal_handler(int sig) Dmsg1(300, "exepath=%s\n", exepath); switch (pid = fork()) { case -1: /* error */ + fprintf(stderr, "Fork error: ERR=%s\n", strerror(errno)); break; case 0: /* child */ argv[0] = btpath; /* path to btraceback */ @@ -118,6 +119,7 @@ static void signal_handler(int sig) if (pid > 0) { Dmsg0(500, "Doing waitpid\n"); waitpid(pid, NULL, 0); /* wait for child to produce dump */ + fprintf(stderr, "Traceback complete, attempting cleanup ...\n"); Dmsg0(500, "Done waitpid\n"); exit_handler(1); /* clean up if possible */ Dmsg0(500, "Done exit_handler\n"); @@ -125,6 +127,7 @@ static void signal_handler(int sig) Dmsg0(500, "Doing sleep\n"); sleep(30); } + fprintf(stderr, "It looks like the traceback worked ...\n"); } #endif diff --git a/bacula/src/lib/smartall.c b/bacula/src/lib/smartall.c index cbde11df75..dfc822c4d6 100644 --- a/bacula/src/lib/smartall.c +++ b/bacula/src/lib/smartall.c @@ -42,8 +42,6 @@ #undef malloc #undef free -#define FULL_SM_CHECK 1 - /*LINTLIBRARY*/ @@ -104,9 +102,7 @@ static void *smalloc(char *fname, int lineno, unsigned int nbytes) buf[nbytes - 1] = (((long) buf) & 0xFF) ^ 0xC5; buf += HEAD_SIZE; /* Increment to user data start */ } -#ifdef FULL_SM_CHECK sm_check(fname, lineno, True); -#endif Dmsg4(1150, "smalloc %d at %x from %s:%d\n", nbytes, buf, fname, lineno); return (void *) buf; } @@ -132,9 +128,7 @@ void sm_free(char *file, int line, void *fp) char *cp = (char *) fp; struct b_queue *qp; -#ifdef FULL_SM_CHECK sm_check(__FILE__, __LINE__, True); -#endif if (cp == NULL) { Emsg2(M_ABORT, 0, "Attempt to free NULL called from %s:%d\n", file, line); } @@ -224,9 +218,7 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size) void *buf; char *cp = (char *) ptr; -#ifdef FULL_SM_CHECK sm_check(fname, lineno, True); -#endif if (size <= 0) { e_msg(fname, lineno, M_ABORT, 0, "sm_realloc size: %d\n", size); } @@ -266,9 +258,7 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size) sm_free(__FILE__, __LINE__, ptr); } Dmsg4(150, "sm_realloc %d at %x from %s:%d\n", size, buf, fname, lineno); -#ifdef FULL_SM_CHECK sm_check(fname, lineno, True); -#endif return buf; } @@ -311,8 +301,10 @@ void actuallyfree(void *cp) } /* SM_DUMP -- Print orphaned buffers (and dump them if BUFDUMP is - True). */ - + * True). + * N.B. DO NOT USE any Bacula print routines (Dmsg, Jmsg, Emsg, ...) + * as they have all been shut down at this point. + */ void sm_dump(Boolean bufdump) { struct abufhead *ap = (struct abufhead *) abqueue.qnext; @@ -364,6 +356,7 @@ void sm_dump(Boolean bufdump) } } +#undef sm_check /* SM_CHECK -- Check the buffers and dump if any damage exists. */ void sm_check(char *fname, int lineno, Boolean bufdump) { @@ -373,6 +366,7 @@ void sm_check(char *fname, int lineno, Boolean bufdump) } } +#undef sm_check_rtn /* SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */ int sm_check_rtn(char *fname, int lineno, Boolean bufdump) { diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index a3c21f92f1..0ef4c84b27 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -4,6 +4,8 @@ * * Kern E. Sibbald * + * $Id$ + * */ /* Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker @@ -58,11 +60,12 @@ static void my_free_jcr(JCR *jcr) int main (int argc, char *argv[]) { - int ch, i; + int ch; FILE *fd; char line[1000]; my_name_is(argc, argv, "bextract"); + init_msg(NULL, NULL); /* setup message handler */ memset(ff, 0, sizeof(FF_PKT)); init_include_exclude_files(ff); @@ -117,13 +120,6 @@ int main (int argc, char *argv[]) usage(); } - /* - * Ensure that every message is always printed - */ - for (i=1; i<=M_MAX; i++) { - add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL); - } - jcr = new_jcr(sizeof(JCR), my_free_jcr); jcr->VolSessionId = 1; jcr->VolSessionTime = (uint32_t)time(NULL); diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 012014edc2..9b648a6a6f 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -123,7 +123,7 @@ void free_block(DEV_BLOCK *block) Dmsg1(199, "free_block buffer %x\n", block->buf); free_memory(block->buf); Dmsg1(199, "free_block block %x\n", block); - free_memory(block); + free_memory((POOLMEM *)block); } /* Empty the block -- for writing */ diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 5fa23b504a..fbbdb52a52 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -2,6 +2,7 @@ * * Dumb program to do an "ls" of a Bacula 1.0 mortal file. * + * $Id$ */ /* Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker @@ -67,6 +68,7 @@ int main (int argc, char *argv[]) char line[1000]; my_name_is(argc, argv, "bls"); + init_msg(NULL, NULL); /* initialize message handler */ memset(&ff, 0, sizeof(ff)); init_include_exclude_files(&ff); @@ -144,20 +146,12 @@ int main (int argc, char *argv[]) add_fname_to_include_list(&ff, 0, "/"); } - /* - * Ensure that every message is always printed - */ - for (i=1; i<=M_MAX; i++) { - add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL); - } - /* Try default device */ if (default_tape) { do_ls(DEFAULT_TAPE_DRIVE); return 0; } - for (i=0; i < argc; i++) { if (list_blocks) { do_blocks(argv[i]); diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 6738d866c8..b3483fbe99 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -6,6 +6,8 @@ * * Kern E. Sibbald, December 2001 * + * + * $Id$ */ /* Copyright (C) 2001, 2002 Kern Sibbald and John Walker @@ -56,9 +58,10 @@ static void my_free_jcr(JCR *jcr) int main (int argc, char *argv[]) { - int ch, i; + int ch; my_name_is(argc, argv, "bscan"); + init_msg(NULL, NULL); while ((ch = getopt(argc, argv, "d:?")) != -1) { @@ -83,13 +86,6 @@ int main (int argc, char *argv[]) usage(); } - /* - * Ensure that every message is always printed - */ - for (i=1; i<=M_MAX; i++) { - add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL); - } - jcr = new_jcr(sizeof(JCR), my_free_jcr); jcr->VolSessionId = 1; jcr->VolSessionTime = (uint32_t)time(NULL); diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index b6e606a2c9..9dcb553dd9 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -10,6 +10,8 @@ * Note, this program reads stored.conf, and will only * talk to devices that are configured. * + * $Id$ + * */ /* Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker @@ -98,7 +100,7 @@ int read_dev(DEVICE *dev, char *buf, size_t len) */ int main(int argc, char *argv[]) { - int ch, i; + int ch; /* Sanity checks */ if (TAPE_BSIZE % DEV_BSIZE != 0 || TAPE_BSIZE / DEV_BSIZE == 0) { @@ -147,6 +149,7 @@ int main(int argc, char *argv[]) my_name_is(argc, argv, "btape"); + init_msg(NULL, NULL); if (signals) { init_signals(terminate_btape); @@ -160,13 +163,6 @@ int main(int argc, char *argv[]) parse_config(configfile); - /* - * Ensure that every message is always printed - */ - for (i=1; i<=M_MAX; i++) { - add_msg_dest(NULL, MD_STDOUT, i, NULL, NULL); - } - /* See if we can open a device */ if (argc) { diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 5333f91b5a..a5fa9399a1 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -1017,13 +1017,13 @@ term_dev(DEVICE *dev) dev->dev_name = NULL; } if (dev->errmsg) { - free_memory(dev->errmsg); + free_pool_memory(dev->errmsg); dev->errmsg = NULL; } pthread_mutex_destroy(&dev->mutex); pthread_cond_destroy(&dev->wait); pthread_cond_destroy(&dev->wait_next_vol); if (dev->state & ST_MALLOC) { - free_memory(dev); + free_pool_memory((POOLMEM *)dev); } } diff --git a/bacula/src/stored/record.c b/bacula/src/stored/record.c index 2b021fb2ec..92a8ea1536 100644 --- a/bacula/src/stored/record.c +++ b/bacula/src/stored/record.c @@ -104,7 +104,7 @@ void free_record(DEV_RECORD *rec) Dmsg0(150, "Enter free_record.\n"); free_pool_memory(rec->data); Dmsg0(150, "Data buf is freed.\n"); - free_pool_memory(rec); + free_pool_memory((POOLMEM *)rec); Dmsg0(150, "Leave free_record.\n"); } diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index cfe86abc75..8164dd0491 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -93,6 +93,7 @@ int main (int argc, char *argv[]) init_stack_dump(); my_name_is(argc, argv, "stored"); + init_msg(NULL, NULL); daemon_start_time = time(NULL); memset(&last_job, 0, sizeof(last_job)); @@ -162,7 +163,6 @@ int main (int argc, char *argv[]) configfile = bstrdup(CONFIG_FILE); } - init_msg(NULL, NULL); parse_config(configfile); check_config(); @@ -176,6 +176,8 @@ int main (int argc, char *argv[]) init_stack_dump(); /* pick up new pid */ } + create_pid_file(me->pid_directory, "bacula-sd", me->SDport); + /* ****FIXME**** clean this up */ /* Create and attach to shared memory. This is a * hold over from the days of child processes. @@ -318,6 +320,15 @@ static void check_config() Emsg1(M_ABORT, 0, _("No Device resource defined in %s. Cannot continue.\n"), configfile); } + if (!me->messages) { + me->messages = (MSGS *)GetNextRes(R_MSGS, NULL); + if (!me->messages) { + Emsg1(M_ABORT, 0, _("No Messages resource defined in %s. Cannot continue.\n"), + configfile); + } + } + close_msg(NULL); /* close temp message handler */ + init_msg(NULL, me->messages); /* open daemon message handler */ UnlockRes(); @@ -347,6 +358,7 @@ void terminate_stored(int sig) } in_here = TRUE; + delete_pid_file(me->pid_directory, "bacula-sd", me->SDport); stop_watchdog(); Dmsg0(200, "In terminate_stored()\n"); @@ -363,13 +375,15 @@ void terminate_stored(int sig) free(configfile); free_config_resources(); - if (debug_level > 10) + if (debug_level > 10) { print_memory_pool_stats(); + } + term_msg(); close_memory_pool(); - if (shm) - free(shm); - term_msg(); + if (shm) { + free(shm); + } sm_dump(False); /* dump orphaned buffers */ exit(1); diff --git a/bacula/src/stored/stored_conf.c b/bacula/src/stored/stored_conf.c index 7781e8c1dd..1c97cff4bb 100644 --- a/bacula/src/stored/stored_conf.c +++ b/bacula/src/stored/stored_conf.c @@ -53,6 +53,7 @@ static struct res_items store_items[] = { {"name", store_name, ITEM(res_store.hdr.name), 0, ITEM_REQUIRED, 0}, {"description", store_str, ITEM(res_dir.hdr.desc), 0, 0, 0}, {"address", store_str, ITEM(res_store.address), 0, ITEM_REQUIRED, 0}, + {"messages", store_res, ITEM(res_store.messages), 0, R_MSGS, 0}, {"sdport", store_int, ITEM(res_store.SDport), 0, ITEM_REQUIRED, 0}, {"sddport", store_int, ITEM(res_store.SDDport), 0, 0, 0}, /* depricated */ {"workingdirectory", store_dir, ITEM(res_store.working_directory), 0, ITEM_REQUIRED, 0}, @@ -194,6 +195,10 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); + if (res->res_msgs.mail_cmd) + sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd); + if (res->res_msgs.operator_cmd) + sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd); break; default: sendit(sock, _("Warning: unknown resource type %d\n"), type); @@ -253,16 +258,21 @@ void free_resource(int type) free(res->res_msgs.mail_cmd); if (res->res_msgs.operator_cmd) free(res->res_msgs.operator_cmd); + free_msgs_res((MSGS *)res); /* free message resource */ + res = NULL; break; default: Dmsg1(0, "Unknown resource type %d\n", type); break; } /* Common stuff again -- free the resource, recurse to next one */ - free(res); + if (res) { + free(res); + } resources[rindex].res_head = (RES *)nres; - if (nres) + if (nres) { free_resource(type); + } } /* Save the new resource by chaining it into the head list for @@ -299,16 +309,26 @@ void save_resource(int type, struct res_items *items, int pass) */ if (pass == 2) { switch (type) { + /* Resources not containing a resource */ case R_DIRECTOR: - case R_STORAGE: case R_DEVICE: case R_MSGS: break; + + /* Resources containing a resource */ + case R_STORAGE: + if ((res = (URES *)GetResWithName(R_STORAGE, res_all.res_dir.hdr.name)) == NULL) { + Emsg1(M_ABORT, 0, "Cannot find Storage resource %s\n", res_all.res_dir.hdr.name); + } + res->res_store.messages = res_all.res_store.messages; + break; default: printf("Unknown resource type %d\n", type); error = 1; break; } + + if (res_all.res_dir.hdr.name) { free(res_all.res_dir.hdr.name); res_all.res_dir.hdr.name = NULL; diff --git a/bacula/src/stored/stored_conf.h b/bacula/src/stored/stored_conf.h index 7855a392b1..dcbc813396 100644 --- a/bacula/src/stored/stored_conf.h +++ b/bacula/src/stored/stored_conf.h @@ -21,72 +21,73 @@ */ -#define R_FIRST 3001 +#define R_FIRST 3001 -#define R_DIRECTOR 3001 -#define R_STORAGE 3002 -#define R_DEVICE 3003 -#define R_MSGS 3004 +#define R_DIRECTOR 3001 +#define R_STORAGE 3002 +#define R_DEVICE 3003 +#define R_MSGS 3004 -#define R_LAST R_MSGS +#define R_LAST R_MSGS -#define R_NAME 3020 -#define R_ADDRESS 3021 -#define R_PASSWORD 3022 -#define R_TYPE 3023 -#define R_BACKUP 3024 +#define R_NAME 3020 +#define R_ADDRESS 3021 +#define R_PASSWORD 3022 +#define R_TYPE 3023 +#define R_BACKUP 3024 #define STORAGE_DAEMON 1 /* Definition of the contents of each Resource */ struct s_res_dir { - RES hdr; + RES hdr; - char *password; /* Director password */ - char *address; /* Director IP address or zero */ + char *password; /* Director password */ + char *address; /* Director IP address or zero */ }; typedef struct s_res_dir DIRRES; /* Storage daemon "global" definitions */ struct s_res_store { - RES hdr; + RES hdr; char *address; - int SDport; /* Where we listen for Directors */ + int SDport; /* Where we listen for Directors */ int SDDport; /* "Data" port where we listen for File daemons */ - char *working_directory; /* working directory for checkpoints */ + char *working_directory; /* working directory for checkpoints */ char *pid_directory; char *subsys_directory; uint32_t max_concurrent_jobs; /* maximum concurrent jobs to run */ + struct s_res_msgs *messages; /* Daemon message handler */ }; typedef struct s_res_store STORES; /* Device specific definitions */ struct s_res_dev { - RES hdr; + RES hdr; char *media_type; char *device_name; - int cap_bits; - uint32_t max_rewind_wait; /* maximum secs to wait for rewind */ - uint32_t min_block_size; /* min block size */ - uint32_t max_block_size; /* max block size */ - uint32_t max_volume_jobs; /* max jobs to put on one volume */ - int64_t max_volume_files; /* max files to put on one volume */ - int64_t max_volume_size; /* max bytes to put on one volume */ - int64_t max_file_size; /* max file size in bytes */ - int64_t volume_capacity; /* advisory capacity */ + int cap_bits; + uint32_t max_rewind_wait; /* maximum secs to wait for rewind */ + uint32_t min_block_size; /* min block size */ + uint32_t max_block_size; /* max block size */ + uint32_t max_volume_jobs; /* max jobs to put on one volume */ + int64_t max_volume_files; /* max files to put on one volume */ + int64_t max_volume_size; /* max bytes to put on one volume */ + int64_t max_file_size; /* max file size in bytes */ + int64_t volume_capacity; /* advisory capacity */ DEVICE *dev; }; typedef struct s_res_dev DEVRES; union u_res { - struct s_res_dir res_dir; - struct s_res_store res_store; - struct s_res_dev res_dev; - struct s_res_msgs res_msgs; + struct s_res_dir res_dir; + struct s_res_store res_store; + struct s_res_dev res_dev; + struct s_res_msgs res_msgs; RES hdr; }; typedef union u_res URES; diff --git a/bacula/src/version.h b/bacula/src/version.h index ee81553dff..a9e51fb515 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ -#define VERSION "1.19" +#define VERSION "1.20" #define VSTRING "1" -#define DATE "10 May 2002" -#define LSMDATE "10May02" +#define DATE "16 May 2002" +#define LSMDATE "16May02" /* Debug flags */ #define DEBUG 1