From 28a45733fdb9131af7db083f5e40a44e173c679d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 19 Jun 2004 20:53:12 +0000 Subject: [PATCH] First cut SIGHUM + misc git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1428 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 16 +++- bacula/src/dird/dird.c | 52 +++++++++---- bacula/src/dird/dird_conf.c | 22 +++--- bacula/src/dird/fd_cmds.c | 18 ++--- bacula/src/dird/inc_conf.c | 26 +++---- bacula/src/dird/msgchan.c | 5 +- bacula/src/dird/query.sql | 35 ++++++--- bacula/src/lib/bnet.c | 12 +-- bacula/src/lib/edit.c | 10 +-- bacula/src/lib/jcr.c | 10 +++ bacula/src/lib/message.c | 2 + bacula/src/lib/parse_conf.c | 50 ++++++------ bacula/src/lib/watchdog.c | 66 ++++++++-------- bacula/src/stored/askdir.c | 4 - bacula/src/stored/btape.c | 2 +- bacula/src/stored/butil.c | 1 - bacula/src/stored/dircmd.c | 14 +++- bacula/src/stored/job.c | 7 -- bacula/src/stored/label.c | 20 ++--- bacula/src/stored/mount.c | 149 ++++++++++++++++++++---------------- bacula/src/stored/protos.h | 8 +- bacula/src/stored/stored.c | 8 +- bacula/src/version.h | 7 +- 23 files changed, 310 insertions(+), 234 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 6aab00fe4b..c7de681b1b 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -3,18 +3,20 @@ 1.35 Items to do: - Implement SIGHUP in Dir -- Implement fast tree insert (doubly linked list?) + (Implement resources on a single pointer) - Do tape alerts -- see tapealert.txt - When restore started from console, report jobid. -- Feedback while the tree is being built. - Win32 inc problem when new directory added. - On Win95 The error I when I installed 1.34.2 clients: The BACULA-FD file is linked to missing export KERNEL32.DLL:GetFileAttributesExA. - Add link to doc in message when authentication fails. -- Disallow using Internal database - Add better error codes to run_program (10000+) +- When passwords do not match, print message that points the + user to the doc. +- Make Verify jobs require exclusive use of Volume as Restore + jobs do. Documentation to do: (any release a little bit at a time) @@ -56,6 +58,8 @@ For 1.33 Testing/Documentation: non-existent directories will not be restored properly. Wish list: +- Sort Scheduled jobs status listing by start time. +- Add priority to Scheduled jobs status listing. - Add multiple-media-types.txt - look at mxt-changer.html - Document a get out of jail procedure if everything breaks if you lost/broke @@ -1069,3 +1073,9 @@ Block Position: 0 mount it. - Implement Fixed storage LabelFormat test. - Add reporting in attr despooling. + +==== Done in 1.35.0 +- Implement fast tree insert (doubly linked list?) +- Disallow using Internal database +- Feedback while the tree is being built. + diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 109b582d57..e866dcfad1 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -216,7 +216,7 @@ int main (int argc, char *argv[]) drop(uid, gid); /* reduce priveleges if requested */ - /* signal(SIGHUP, reload_config); */ + signal(SIGHUP, reload_config); init_console_msg(working_directory); @@ -272,7 +272,7 @@ static void terminate_dird(int sig) term_msg(); /* terminate message handler */ stop_watchdog(); close_memory_pool(); /* release free memory in pool */ - sm_dump(false); + sm_dump(false); exit(sig); } @@ -296,6 +296,10 @@ static void free_saved_resources(int table) { int num = r_last - r_first + 1; RES **res_tab = reload_table[table].res_table; + if (!res_tab) { + Dmsg1(000, "res_tab for table %d already released.\n", table); + return; + } Dmsg1(000, "Freeing resources for table %d\n", table); for (int j=0; jreload_id == 0) { + return; /* nothing to do */ + } int i = jcr->reload_id - 1; - Dmsg1(000, "reload job_end JobId=%d\n", jcr->JobId); + Dmsg3(000, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId, + i, reload_table[i].job_count); lock_jcr_chain(); LockRes(); if (--reload_table[i].job_count <= 0) { @@ -323,10 +330,9 @@ static void reload_job_end_cb(JCR *jcr) } UnlockRes(); unlock_jcr_chain(); -#endif } -static int find_free_table() +static int find_free_reload_table_entry() { int table = -1; for (int i=0; i < max_reloads; i++) { @@ -351,22 +357,22 @@ void reload_config(int sig) int njobs = 0; int table, rtable; - Jmsg(NULL, M_ERROR, 0, _("Command not implemented\n")); - return; - if (already_here) { abort(); /* Oops, recursion -> die */ } already_here = true; - sigfillset(&set); + sigemptyset(&set); + sigaddset(&set, SIGHUP); sigprocmask(SIG_BLOCK, &set, NULL); +// Jmsg(NULL, M_INFO, 0, "Entering experimental reload config code. Bug reports will not be accepted.\n"); + lock_jcr_chain(); LockRes(); - table = find_free_table(); + table = find_free_reload_table_entry(); if (table < 0) { - Jmsg(NULL, M_ERROR, 0, _("Too many reload requests.\n")); + Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n")); goto bail_out; } @@ -375,7 +381,7 @@ void reload_config(int sig) * reload_id == 0 */ foreach_jcr(jcr) { - if (jcr->reload_id == 0) { + if (jcr->reload_id == 0 && jcr->JobType != JT_SYSTEM) { reload_table[table].job_count++; jcr->reload_id = table + 1; job_end_push(jcr, reload_job_end_cb); @@ -392,9 +398,10 @@ void reload_config(int sig) Dmsg0(000, "Reloaded config file\n"); if (!check_resources()) { - rtable = find_free_table(); /* save new, bad table */ + rtable = find_free_reload_table_entry(); /* save new, bad table */ if (rtable < 0) { - Jmsg(NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); + Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); + Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n")); } else { Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); } @@ -406,6 +413,15 @@ void reload_config(int sig) resources[i].res_head = res_tab[i]; } table = rtable; /* release new, bad, saved table below */ + if (njobs != 0) { + foreach_jcr(jcr) { + if (jcr->reload_id == table) { + jcr->reload_id = 0; + } + free_locked_jcr(jcr); + } + } + njobs = 0; /* force bad tabel to be released below */ } /* Reset globals */ @@ -414,8 +430,10 @@ void reload_config(int sig) SDConnectTimeout = director->SDConnectTimeout; Dmsg0(0, "Director's configuration file reread.\n"); - /* Now release saved resources */ - free_saved_resources(table); + /* Now release saved resources, if no jobs using the resources */ + if (njobs == 0) { + free_saved_resources(table); + } bail_out: UnlockRes(); diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index bbb568aeaa..6800fead5f 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -1094,7 +1094,7 @@ void save_resource(int type, RES_ITEM *items, int pass) memcpy(res, &res_all, size); if (!resources[rindex].res_head) { resources[rindex].res_head = (RES *)res; /* store first entry */ - Dmsg3(200, "Inserting first %s res: %s index=%d\n", res_to_str(type), + Dmsg3(900, "Inserting first %s res: %s index=%d\n", res_to_str(type), res->res_dir.hdr.name, rindex); } else { RES *next; @@ -1107,7 +1107,7 @@ void save_resource(int type, RES_ITEM *items, int pass) } } next->next = (RES *)res; - Dmsg4(200, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(type), + Dmsg4(900, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(type), res->res_dir.hdr.name, rindex, pass); } } @@ -1193,10 +1193,10 @@ void store_acl(LEX *lc, RES_ITEM *item, int index, int pass) if (pass == 1) { if (((alist **)item->value)[item->code] == NULL) { ((alist **)item->value)[item->code] = new alist(10, owned_by_alist); -// Dmsg1(400, "Defined new ACL alist at %d\n", item->code); +// Dmsg1(900, "Defined new ACL alist at %d\n", item->code); } ((alist **)item->value)[item->code]->append(bstrdup(lc->str)); -// Dmsg2(400, "Appended to %d %s\n", item->code, lc->str); +// Dmsg2(900, "Appended to %d %s\n", item->code, lc->str); } token = lex_get_token(lc, T_ALL); if (token == T_COMMA) { @@ -1229,12 +1229,12 @@ static void store_backup(LEX *lc, RES_ITEM *item, int index, int pass) while ((token = lex_get_token(lc, T_ALL)) != T_EOL) { bool found = false; - Dmsg1(150, "store_backup got token=%s\n", lex_tok_to_str(token)); + Dmsg1(900, "store_backup got token=%s\n", lex_tok_to_str(token)); if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a backup/verify keyword, got: %s", lc->str); } - Dmsg1(190, "Got keyword: %s\n", lc->str); + Dmsg1(900, "Got keyword: %s\n", lc->str); for (i=0; BakVerFields[i].name; i++) { if (strcasecmp(lc->str, BakVerFields[i].name) == 0) { found = true; @@ -1242,7 +1242,7 @@ static void store_backup(LEX *lc, RES_ITEM *item, int index, int pass) scan_err1(lc, "Expected an equals, got: %s", lc->str); } token = lex_get_token(lc, T_NAME); - Dmsg1(190, "Got value: %s\n", lc->str); + Dmsg1(900, "Got value: %s\n", lc->str); switch (BakVerFields[i].token) { case 'C': /* Find Client Resource */ @@ -1306,7 +1306,7 @@ static void store_restore(LEX *lc, RES_ITEM *item, int index, int pass) lc->options |= LOPT_NO_IDENT; /* make spaces significant */ - Dmsg0(190, "Enter store_restore()\n"); + Dmsg0(900, "Enter store_restore()\n"); ((JOB *)(item->value))->JobType = item->code; while ((token = lex_get_token(lc, T_ALL)) != T_EOL) { @@ -1316,14 +1316,14 @@ static void store_restore(LEX *lc, RES_ITEM *item, int index, int pass) scan_err1(lc, "expected a name, got: %s", lc->str); } for (i=0; RestoreFields[i].name; i++) { - Dmsg1(190, "Restore kw=%s\n", lc->str); + Dmsg1(900, "Restore kw=%s\n", lc->str); if (strcasecmp(lc->str, RestoreFields[i].name) == 0) { found = true; if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, "Expected an equals, got: %s", lc->str); } token = lex_get_token(lc, T_ALL); - Dmsg1(190, "Restore value=%s\n", lc->str); + Dmsg1(900, "Restore value=%s\n", lc->str); switch (RestoreFields[i].token) { case 'B': /* Bootstrap */ @@ -1363,7 +1363,7 @@ static void store_restore(LEX *lc, RES_ITEM *item, int index, int pass) } errno = 0; res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0); - Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId); + Dmsg1(900, "RestorJobId=%d\n", res_all.res_job.RestoreJobId); if (errno != 0) { scan_err1(lc, "expected an integer number, got: %s", lc->str); } diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index bf26e7b68c..fcd5aebad7 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -265,11 +265,11 @@ static int send_list(JCR *jcr, int list) } else { bstrncpy(buf, "0 ", sizeof(buf)); } - Dmsg1(100, "Opts=%s\n", buf); + Dmsg1(500, "Opts=%s\n", buf); optlen = strlen(buf); while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) { fd->msglen = Mmsg(&fd->msg, "%s", buf); - Dmsg2(200, "Inc/exc len=%d: %s", fd->msglen, fd->msg); + Dmsg2(500, "Inc/exc len=%d: %s", fd->msglen, fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); goto bail_out; @@ -295,7 +295,7 @@ static int send_list(JCR *jcr, int list) } else { bstrncpy(buf, "0 ", sizeof(buf)); } - Dmsg1(100, "Opts=%s\n", buf); + Dmsg1(500, "Opts=%s\n", buf); optlen = strlen(buf); while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) { fd->msglen = Mmsg(&fd->msg, "%s", buf); @@ -311,14 +311,14 @@ static int send_list(JCR *jcr, int list) /* Note, fall through wanted */ default: if (ie->num_opts) { - Dmsg2(100, "numopts=%d opts=%s\n", ie->num_opts, NPRT(ie->opts_list[0]->opts)); + Dmsg2(500, "numopts=%d opts=%s\n", ie->num_opts, NPRT(ie->opts_list[0]->opts)); pm_strcpy(&fd->msg, ie->opts_list[0]->opts); pm_strcat(&fd->msg, " "); } else { pm_strcpy(&fd->msg, "0 "); } fd->msglen = pm_strcat(&fd->msg, p); - Dmsg1(100, "Inc/Exc name=%s\n", fd->msg); + Dmsg1(500, "Inc/Exc name=%s\n", fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); goto bail_out; @@ -404,11 +404,11 @@ static int send_fileset(JCR *jcr) goto bail_out; } bstrncpy(buf, "F ", sizeof(buf)); - Dmsg1(100, "Opts=%s\n", buf); + Dmsg1(500, "Opts=%s\n", buf); optlen = strlen(buf); while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) { fd->msglen = Mmsg(&fd->msg, "%s", buf); - Dmsg2(200, "Inc/exc len=%d: %s", fd->msglen, fd->msg); + Dmsg2(500, "Inc/exc len=%d: %s", fd->msglen, fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); goto bail_out; @@ -428,7 +428,7 @@ static int send_fileset(JCR *jcr) goto bail_out; } bstrncpy(buf, "F ", sizeof(buf)); - Dmsg1(100, "Opts=%s\n", buf); + Dmsg1(500, "Opts=%s\n", buf); optlen = strlen(buf); while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) { fd->msglen = Mmsg(&fd->msg, "%s", buf); @@ -445,7 +445,7 @@ static int send_fileset(JCR *jcr) default: pm_strcpy(&fd->msg, "F "); fd->msglen = pm_strcat(&fd->msg, p); - Dmsg1(100, "Inc/Exc name=%s\n", fd->msg); + Dmsg1(500, "Inc/Exc name=%s\n", fd->msg); if (!bnet_send(fd)) { Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n")); goto bail_out; diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index f363e99caf..b4c26c3f8b 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -204,7 +204,7 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) bstrncat(opts, "V", optlen); /* indicate Verify */ bstrncat(opts, lc->str, optlen); bstrncat(opts, ":", optlen); /* terminate it */ - Dmsg3(100, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); + Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); /* * Standard keyword options for Include/Exclude @@ -223,7 +223,7 @@ static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen) scan_err1(lc, "Expected a FileSet option keyword, got:%s:", lc->str); } else { /* add option */ bstrncat(opts, option, optlen); - Dmsg3(100, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); + Dmsg3(900, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen); } } @@ -300,10 +300,10 @@ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) } setup_current_opts(); bstrncpy(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS); - Dmsg2(100, "old pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts); + Dmsg2(900, "old pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts); /* Create incexe structure */ - Dmsg0(200, "Create INCEXE structure\n"); + Dmsg0(900, "Create INCEXE structure\n"); incexe = (INCEXE *)malloc(sizeof(INCEXE)); memcpy(incexe, &res_incexe, sizeof(INCEXE)); memset(&res_incexe, 0, sizeof(INCEXE)); @@ -315,7 +315,7 @@ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) sizeof(INCEXE *) * (res_all.res_fs.num_includes + 1)); } res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe; - Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes); + Dmsg1(900, "num_includes=%d\n", res_all.res_fs.num_includes); } else { /* exclude */ if (res_all.res_fs.num_excludes == 0) { res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *)); @@ -324,7 +324,7 @@ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) sizeof(INCEXE *) * (res_all.res_fs.num_excludes + 1)); } res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe; - Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes); + Dmsg1(900, "num_excludes=%d\n", res_all.res_fs.num_excludes); } /* Pickup include/exclude names. They are stored in INCEXE @@ -346,7 +346,7 @@ void store_inc(LEX *lc, RES_ITEM *item, int index, int pass) incexe->name_list.init(10, true); } incexe->name_list.append(bstrdup(lc->str)); - Dmsg1(200, "Add to name_list %s\n", lc->str); + Dmsg1(900, "Add to name_list %s\n", lc->str); break; default: scan_err1(lc, "Expected a filename, got: %s", lc->str); @@ -422,7 +422,7 @@ static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass) sizeof(INCEXE *) * (res_all.res_fs.num_includes + 1)); } res_all.res_fs.include_items[res_all.res_fs.num_includes++] = incexe; - Dmsg1(200, "num_includes=%d\n", res_all.res_fs.num_includes); + Dmsg1(900, "num_includes=%d\n", res_all.res_fs.num_includes); } else { /* exclude */ if (res_all.res_fs.num_excludes == 0) { res_all.res_fs.exclude_items = (INCEXE **)malloc(sizeof(INCEXE *)); @@ -431,7 +431,7 @@ static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass) sizeof(INCEXE *) * (res_all.res_fs.num_excludes + 1)); } res_all.res_fs.exclude_items[res_all.res_fs.num_excludes++] = incexe; - Dmsg1(200, "num_excludes=%d\n", res_all.res_fs.num_excludes); + Dmsg1(900, "num_excludes=%d\n", res_all.res_fs.num_excludes); } } scan_to_eol(lc); @@ -453,7 +453,7 @@ static void store_regex(LEX *lc, RES_ITEM *item, int index, int pass) case T_UNQUOTED_STRING: case T_QUOTED_STRING: res_incexe.current_opts->regex.append(bstrdup(lc->str)); - Dmsg3(200, "set regex %p size=%d %s\n", + Dmsg3(900, "set regex %p size=%d %s\n", res_incexe.current_opts, res_incexe.current_opts->regex.size(),lc->str); break; default: @@ -498,7 +498,7 @@ static void store_wild(LEX *lc, RES_ITEM *item, int index, int pass) case T_UNQUOTED_STRING: case T_QUOTED_STRING: res_incexe.current_opts->wild.append(bstrdup(lc->str)); - Dmsg3(200, "set wild %p size=%d %s\n", + Dmsg3(900, "set wild %p size=%d %s\n", res_incexe.current_opts, res_incexe.current_opts->wild.size(),lc->str); break; default: @@ -537,7 +537,7 @@ static void store_fname(LEX *lc, RES_ITEM *item, int index, int pass) incexe->name_list.init(10, true); } incexe->name_list.append(bstrdup(lc->str)); - Dmsg1(200, "Add to name_list %s\n", lc->str); + Dmsg1(900, "Add to name_list %s\n", lc->str); break; default: scan_err1(lc, _("Expected a filename, got: %s"), lc->str); @@ -619,7 +619,7 @@ static void store_opts(LEX *lc, RES_ITEM *item, int index, int pass) scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts)); if (pass == 1) { bstrncat(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS); - Dmsg2(100, "new pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts); + Dmsg2(900, "new pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts); } scan_to_eol(lc); } diff --git a/bacula/src/dird/msgchan.c b/bacula/src/dird/msgchan.c index 62ea608768..8b8ee68f29 100644 --- a/bacula/src/dird/msgchan.c +++ b/bacula/src/dird/msgchan.c @@ -178,9 +178,11 @@ int start_storage_daemon_message_thread(JCR *jcr) jcr->sd_msg_thread_done = false; jcr->SD_msg_chan = 0; V(jcr->mutex); + Dmsg0(100, "Start SD msg_thread.\n"); if ((status=pthread_create(&thid, NULL, msg_thread, (void *)jcr)) != 0) { Jmsg1(jcr, M_ABORT, 0, _("Cannot create message thread: %s\n"), strerror(status)); } + Dmsg0(100, "SD msg_thread started.\n"); /* Wait for thread to start */ while (jcr->SD_msg_chan == 0) { bmicrosleep(0, 50); @@ -220,12 +222,11 @@ void *msg_thread(void *arg) pthread_detach(pthread_self()); jcr->SD_msg_chan = pthread_self(); pthread_cleanup_push(msg_thread_cleanup, arg); - Dmsg0(200, "msg_thread\n"); sd = jcr->store_bsock; /* Read the Storage daemon's output. */ - Dmsg0(200, "Start msg_thread loop\n"); + Dmsg0(100, "Start msg_thread loop\n"); while ((stat=bget_dirmsg(sd)) >= 0) { Dmsg1(200, "msg); if (sscanf(sd->msg, Job_start, &Job) == 1) { diff --git a/bacula/src/dird/query.sql b/bacula/src/dird/query.sql index a145cc6d2c..164ba9d1d3 100644 --- a/bacula/src/dird/query.sql +++ b/bacula/src/dird/query.sql @@ -12,7 +12,9 @@ SELECT Job.JobId as JobId, Client.Name as Client, FROM Client,Job,File,Filename,Path WHERE Client.ClientId=Job.ClientId AND JobStatus='T' AND Job.JobId=File.JobId AND Path.PathId=File.PathId AND Filename.FilenameId=File.FilenameId - AND Filename.Name='%1' ORDER BY Job.StartTime LIMIT 20; + AND Filename.Name='%1' + GROUP BY Job.JobId + ORDER BY Job.StartTime LIMIT 20; # 3 :List where the most recent copies of a file are saved: *Enter path with trailing slash: @@ -29,23 +31,25 @@ SELECT Job.JobId,StartTime AS JobStartTime,VolumeName,Client.Name AS ClientName AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId AND Client.ClientId=Job.ClientId + GROUP BY Job.JobId ORDER BY Job.StartTime DESC LIMIT 5; # 4 :List last 20 Full Backups for a Client: *Enter Client name: -Select Job.JobId,Client.Name as Client,StartTime,JobFiles,JobBytes, +SELECT Job.JobId,Client.Name AS Client,StartTime,JobFiles,JobBytes, JobMedia.StartFile as VolFile,VolumeName FROM Client,Job,JobMedia,Media WHERE Client.Name='%1' AND Client.ClientId=Job.ClientId AND Level='F' AND JobStatus='T' AND JobMedia.JobId=Job.JobId AND JobMedia.MediaId=Media.MediaId + GROUP BY Job.JobId ORDER BY Job.StartTime DESC LIMIT 20; # 5 :List all backups for a Client after a specified time *Enter Client Name: *Enter time in YYYY-MM-DD HH:MM:SS format: -Select Job.JobId,Client.Name as Client,Level,StartTime,JobFiles,JobBytes,VolumeName +SELECT Job.JobId,Client.Name as Client,Level,StartTime,JobFiles,JobBytes,VolumeName FROM Client,Job,JobMedia,Media WHERE Client.Name='%1' AND Client.ClientId=Job.ClientId @@ -57,7 +61,7 @@ Select Job.JobId,Client.Name as Client,Level,StartTime,JobFiles,JobBytes,VolumeN # 6 :List all backups for a Client *Enter Client Name: -Select Job.JobId,Client.Name as Client,Level,StartTime,JobFiles,JobBytes,VolumeName +SELECT Job.JobId,Client.Name as Client,Level,StartTime,JobFiles,JobBytes,VolumeName FROM Client,Job,JobMedia,Media WHERE Client.Name='%1' AND Client.ClientId=Job.ClientId @@ -71,7 +75,7 @@ Select Job.JobId,Client.Name as Client,Level,StartTime,JobFiles,JobBytes,VolumeN SELECT Slot,MaxVolBytes,VolCapacityBytes,VolStatus,Recycle,VolRetention, VolUseDuration,MaxVolJobs,MaxVolFiles FROM Media - WHERE Volumename='%1'; + WHERE VolumeName='%1'; # 8 :List Volumes used by selected JobId: *Enter JobId: @@ -79,7 +83,8 @@ SELECT Job.JobId,VolumeName FROM Job,JobMedia,Media WHERE Job.JobId=%1 AND Job.JobId=JobMedia.JobId - AND JobMedia.MediaId=Media.MediaId; + AND JobMedia.MediaId=Media.MediaId + GROUP BY VolumeName; # 9 :List Volumes to Restore All Files: *Enter Client Name: @@ -164,8 +169,16 @@ SELECT Path.Path,Filename.Name FROM File, SELECT Job.JobId,Job.Name,Job.StartTime,Job.Type, Job.Level,Job.JobFiles,Job.JobBytes,Job.JobStatus FROM JobMedia,Job - WHERE JobMedia.JobId = Job.JobId - AND JobMedia.MediaId = %1; -SELECT MediaId,VolumeName,VolStatus,VolBytes,VolFiles, - VolRetention,Recycle,Slot,MediaType,LastWritten - FROM Media WHERE MediaId = %1; + WHERE JobMedia.JobId=Job.JobId + AND JobMedia.MediaId=%1 + GROUP BY Job.JobId; +# 15 +:List Jobs stored for a given Volume name: +*Enter Volume name: +SELECT Job.JobId,Job.Name,Job.StartTime,Job.Type, + Job.Level,Job.JobFiles,Job.JobBytes,Job.JobStatus + FROM Media,JobMedia,Job + WHERE Media.VolumeName='%1' + AND Media.MediaId=JobMedia.MediaId + AND JobMedia.JobId=Job.JobId + GROUP BY Job.JobId; diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index df0680a1cf..70f39143bf 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -44,11 +44,13 @@ extern time_t watchdog_time; #endif #ifdef HAVE_WIN32 -#define socketRead(fd, buf, len) recv(fd, buf, len, 0) +#define socketRead(fd, buf, len) recv(fd, buf, len, 0) #define socketWrite(fd, buf, len) send(fd, buf, len, 0) +#define socketClose(fd) closesocket(fd) #else -#define socketRead(fd, buf, len) read(fd, buf, len) +#define socketRead(fd, buf, len) read(fd, buf, len) #define socketWrite(fd, buf, len) write(fd, buf, len) +#define socketClose(fd) close(fd) #endif @@ -634,7 +636,7 @@ bnet_open(JCR *jcr, const char *name, char *host, char *service, int port, int * free(addr_list); if (!connected) { - close(sockfd); + socketClose(sockfd); return NULL; } return init_bsock(jcr, sockfd, name, host, port, &tcp_serv_addr); @@ -866,7 +868,7 @@ dup_bsock(BSOCK *osock) if (osock->host) { bsock->host = bstrdup(osock->host); } - bsock->duped = TRUE; + bsock->duped = true; return bsock; } @@ -882,7 +884,7 @@ bnet_close(BSOCK *bsock) if (bsock->timed_out) { shutdown(bsock->fd, 2); /* discard any pending I/O */ } - close(bsock->fd); /* normal close */ + socketClose(bsock->fd); /* normal close */ } term_bsock(bsock); } diff --git a/bacula/src/lib/edit.c b/bacula/src/lib/edit.c index b6271e6b1c..10b3e5a9e5 100644 --- a/bacula/src/lib/edit.c +++ b/bacula/src/lib/edit.c @@ -123,13 +123,13 @@ static bool get_modifier(char *str, char *mod, int mod_len) /* If nothing found, error */ if (i == 0) { - Dmsg2(200, "error i=%d len=%d\n", i, len); + Dmsg2(900, "error i=%d len=%d\n", i, len); return false; } /* Move modifier to its location */ bstrncpy(mod, &str[i], mod_len); - Dmsg2(200, "in=%s mod=%s:\n", str, mod); + Dmsg2(900, "in=%s mod=%s:\n", str, mod); /* Backup over any spaces in front of modifier */ for ( ; i > 0; i--) { @@ -141,7 +141,7 @@ static bool get_modifier(char *str, char *mod, int mod_len) } /* The remainder (beginning) should be our number */ if (!is_a_number(str)) { - Dmsg0(200, "input not a number\n"); + Dmsg0(900, "input not a number\n"); return false; } return true; @@ -180,7 +180,7 @@ int duration_to_utime(char *str, utime_t *value) if (mod[i] == NULL) { i = 1; /* no modifier, assume 1 */ } - Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]); + Dmsg2(900, "str=%s: mult=%d\n", str, mult[i]); errno = 0; val = strtod(str, NULL); if (errno != 0 || val < 0) { @@ -251,7 +251,7 @@ int size_to_uint64(char *str, int str_len, uint64_t *value) if (mod[i] == NULL) { i = 0; /* no modifier found, assume 1 */ } - Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]); + Dmsg2(900, "str=%s: mult=%d\n", str, mult[i]); errno = 0; val = strtod(str, NULL); if (errno != 0 || val < 0) { diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 4d18839ab3..10dd419d6b 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -519,12 +519,19 @@ void set_jcr_job_status(JCR *jcr, int JobStatus) } } +#ifdef TRACE_JCR_CHAIN +static int lock_count = 0; +#endif + /* * Lock the chain */ void lock_jcr_chain() { int errstat; +#ifdef TRACE_JCR_CHAIN + Dmsg1(000, "Lock jcr chain %d.\n", ++lock_count); +#endif if ((errstat=rwl_writelock(&lock)) != 0) { Emsg1(M_ABORT, 0, "rwl_writelock failure. ERR=%s\n", strerror(errstat)); @@ -537,6 +544,9 @@ void lock_jcr_chain() void unlock_jcr_chain() { int errstat; +#ifdef TRACE_JCR_CHAIN + Dmsg1(000, "Unlock jcr chain %d\n", lock_count--); +#endif if ((errstat=rwl_writeunlock(&lock)) != 0) { Emsg1(M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n", strerror(errstat)); diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 794fe4f9ce..98bc6c36c0 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -1169,6 +1169,7 @@ void Qmsg(JCR *jcr, int type, int level, const char *fmt,...) } else { /* Queue message for later sending */ jcr->msg_queue->append(item); +// Dmsg1(000, "queue item=%lu\n", (long unsigned)item); } V(msg_queue_mutex); free_memory(pool_buf); @@ -1183,6 +1184,7 @@ void dequeue_messages(JCR *jcr) P(msg_queue_mutex); jcr->dequeuing = true; foreach_dlist(item, jcr->msg_queue) { +// Dmsg1(000, "dequeue item=%lu\n", (long unsigned)item); Jmsg(jcr, item->type, item->level, "%s", item->msg); } jcr->msg_queue->destroy(); diff --git a/bacula/src/lib/parse_conf.c b/bacula/src/lib/parse_conf.c index 2e46a4ce79..1d5a78793b 100755 --- a/bacula/src/lib/parse_conf.c +++ b/bacula/src/lib/parse_conf.c @@ -171,7 +171,7 @@ void init_resource(int type, RES_ITEM *items) res_all.hdr.refcnt = 1; for (i=0; items[i].name; i++) { - Dmsg3(300, "Item=%s def=%s defval=%d\n", items[i].name, + Dmsg3(900, "Item=%s def=%s defval=%d\n", items[i].name, (items[i].flags & ITEM_DEFAULT) ? "yes" : "no", items[i].default_value); if (items[i].flags & ITEM_DEFAULT && items[i].default_value != 0) { @@ -204,7 +204,7 @@ void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass) POOLMEM *dest; int dest_len; - Dmsg2(300, "store_msgs pass=%d code=%d\n", pass, item->code); + Dmsg2(900, "store_msgs pass=%d code=%d\n", pass, item->code); if (pass == 1) { switch (item->code) { case MD_STDOUT: @@ -235,7 +235,7 @@ void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass) } pm_strcat(&dest, lc->str); dest_len += lc->str_len; - Dmsg2(100, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest)); + Dmsg2(900, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest)); token = lex_get_token(lc, T_ALL); if (token == T_COMMA) { continue; /* get another destination */ @@ -245,10 +245,10 @@ void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass) } break; } - Dmsg1(300, "mail_cmd=%s\n", NPRT(cmd)); + Dmsg1(900, "mail_cmd=%s\n", NPRT(cmd)); scan_types(lc, (MSGS *)(item->value), item->code, dest, cmd); free_pool_memory(dest); - Dmsg0(300, "done with dest codes\n"); + Dmsg0(900, "done with dest codes\n"); break; case MD_FILE: /* file */ case MD_APPEND: /* append */ @@ -258,13 +258,13 @@ void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass) pm_strcpy(&dest, lc->str); dest_len = lc->str_len; token = lex_get_token(lc, T_ALL); - Dmsg1(300, "store_msgs dest=%s:\n", NPRT(dest)); + Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest)); if (token != T_EQUALS) { scan_err1(lc, _("expected an =, got: %s"), lc->str); } scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL); free_pool_memory(dest); - Dmsg0(300, "done with dest codes\n"); + Dmsg0(900, "done with dest codes\n"); break; default: @@ -274,7 +274,7 @@ void store_msgs(LEX *lc, RES_ITEM *item, int index, int pass) } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); - Dmsg0(300, "Done store_msgs\n"); + Dmsg0(900, "Done store_msgs\n"); } /* @@ -325,10 +325,10 @@ static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd if (lc->ch != ',') { break; } - Dmsg0(300, "call lex_get_token() to eat comma\n"); + Dmsg0(900, "call lex_get_token() to eat comma\n"); lex_get_token(lc, T_ALL); /* eat comma */ } - Dmsg0(300, "Done scan_types()\n"); + Dmsg0(900, "Done scan_types()\n"); } @@ -461,7 +461,7 @@ void store_defs(LEX *lc, RES_ITEM *item, int index, int pass) lex_get_token(lc, T_NAME); if (pass == 2) { - Dmsg2(300, "Code=%d name=%s\n", item->code, lc->str); + Dmsg2(900, "Code=%d name=%s\n", item->code, lc->str); res = GetResWithName(item->code, lc->str); if (res == NULL) { scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"), @@ -471,9 +471,9 @@ void store_defs(LEX *lc, RES_ITEM *item, int index, int pass) #ifdef xxx for (int i=0; item->name;; i++, item++) { if (bit_is_set(i, res->item_present)) { - Dmsg2(300, "Item %d is present in %s\n", i, res->name); + Dmsg2(900, "Item %d is present in %s\n", i, res->name); } else { - Dmsg2(300, "Item %d is not present in %s\n", i, res->name); + Dmsg2(900, "Item %d is not present in %s\n", i, res->name); } } /* ***FIXME **** add code */ @@ -518,7 +518,7 @@ void store_size(LEX *lc, RES_ITEM *item, int index, int pass) int token; uint64_t uvalue; - Dmsg0(400, "Enter store_size\n"); + Dmsg0(900, "Enter store_size\n"); token = lex_get_token(lc, T_ALL); errno = 0; switch (token) { @@ -536,7 +536,7 @@ void store_size(LEX *lc, RES_ITEM *item, int index, int pass) } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); - Dmsg0(400, "Leave store_size\n"); + Dmsg0(900, "Leave store_size\n"); } @@ -697,15 +697,15 @@ parse_config(const char *cf, int exit_on_error) /* Make two passes. The first builds the name symbol table, * and the second picks up the items. */ - Dmsg0(300, "Enter parse_config()\n"); + Dmsg0(900, "Enter parse_config()\n"); for (pass=1; pass <= 2; pass++) { - Dmsg1(300, "parse_config pass %d\n", pass); + Dmsg1(900, "parse_config pass %d\n", pass); if ((lc = lex_open_file(lc, cf, NULL)) == NULL) { set_exit_on_error(1); /* Never reached if exit_on_error == 1 */ return 0; } while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { - Dmsg1(300, "parse got token=%s\n", lex_tok_to_str(token)); + Dmsg1(900, "parse got token=%s\n", lex_tok_to_str(token)); switch (state) { case p_none: if (token == T_EOL) { @@ -747,14 +747,14 @@ parse_config(const char *cf, int exit_on_error) * scan for = after the keyword */ if (!(items[i].flags & ITEM_NO_EQUALS)) { token = lex_get_token(lc, T_ALL); - Dmsg1 (300, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); + Dmsg1 (900, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); if (token != T_EQUALS) { scan_err1(lc, _("expected an equals, got: %s"), lc->str); set_exit_on_error(1); /* Never reached if exit_on_error == 1 */ return 0; } } - Dmsg1(300, "calling handler for %s\n", items[i].name); + Dmsg1(900, "calling handler for %s\n", items[i].name); /* Call item handler */ items[i].handler(lc, &items[i], i, pass); i = -1; @@ -762,8 +762,8 @@ parse_config(const char *cf, int exit_on_error) } } if (i >= 0) { - Dmsg2(300, "level=%d id=%s\n", level, lc->str); - Dmsg1(300, "Keyword = %s\n", lc->str); + Dmsg2(900, "level=%d id=%s\n", level, lc->str); + Dmsg1(900, "Keyword = %s\n", lc->str); scan_err1(lc, _("Keyword \"%s\" not permitted in this resource.\n" "Perhaps you left the trailing brace off of the previous resource."), lc->str); set_exit_on_error(1); /* Never reached if exit_on_error == 1 */ @@ -774,7 +774,7 @@ parse_config(const char *cf, int exit_on_error) case T_EOB: level--; state = p_none; - Dmsg0(300, "T_EOB => define new resource\n"); + Dmsg0(900, "T_EOB => define new resource\n"); save_resource(res_type, items, pass); /* save resource */ break; @@ -799,7 +799,7 @@ parse_config(const char *cf, int exit_on_error) set_exit_on_error(1); /* Never reached if exit_on_error == 1 */ return 0; } - if (debug_level > 50 && pass == 2) { + if (debug_level >= 900 && pass == 2) { int i; for (i=r_first; i<=r_last; i++) { dump_resource(i, resources[i-r_first].res_head, prtmsg, NULL); @@ -807,7 +807,7 @@ parse_config(const char *cf, int exit_on_error) } lc = lex_close_file(lc); } - Dmsg0(300, "Leave parse_config()\n"); + Dmsg0(900, "Leave parse_config()\n"); set_exit_on_error(1); return 1; } diff --git a/bacula/src/lib/watchdog.c b/bacula/src/lib/watchdog.c index 28ac35f0bd..8f261f4585 100755 --- a/bacula/src/lib/watchdog.c +++ b/bacula/src/lib/watchdog.c @@ -31,9 +31,9 @@ #include "jcr.h" /* Exported globals */ -time_t watchdog_time = 0; /* this has granularity of SLEEP_TIME */ +time_t watchdog_time = 0; /* this has granularity of SLEEP_TIME */ -#define SLEEP_TIME 1 /* examine things every second */ +#define SLEEP_TIME 1 /* examine things every second */ /* Forward referenced functions */ extern "C" void *watchdog_thread(void *arg); @@ -44,7 +44,7 @@ static void wd_unlock(); /* Static globals */ static bool quit = false;; static bool wd_is_init = false; -static brwlock_t lock; /* watchdog lock */ +static brwlock_t lock; /* watchdog lock */ static pthread_t wd_tid; static dlist *wd_queue; @@ -54,7 +54,7 @@ static dlist *wd_inactive; * Start watchdog thread * * Returns: 0 on success - * errno on failure + * errno on failure */ int start_watchdog(void) { @@ -70,7 +70,7 @@ int start_watchdog(void) if ((errstat=rwl_init(&lock)) != 0) { Emsg1(M_ABORT, 0, _("Unable to initialize watchdog lock. ERR=%s\n"), - strerror(errstat)); + strerror(errstat)); } wd_queue = new dlist(wd_queue, &dummy->link); wd_inactive = new dlist(wd_inactive, &dummy->link); @@ -86,7 +86,7 @@ int start_watchdog(void) * Terminate the watchdog thread * * Returns: 0 on success - * errno on failure + * errno on failure */ int stop_watchdog(void) { @@ -97,7 +97,7 @@ int stop_watchdog(void) return 0; } - quit = true; /* notify watchdog thread to stop */ + quit = true; /* notify watchdog thread to stop */ wd_is_init = false; stat = pthread_join(wd_tid, NULL); @@ -107,7 +107,7 @@ int stop_watchdog(void) wd_queue->remove(item); p = (watchdog_t *)item; if (p->destructor != NULL) { - p->destructor(p); + p->destructor(p); } free(p); } @@ -119,7 +119,7 @@ int stop_watchdog(void) wd_inactive->remove(item); p = (watchdog_t *)item; if (p->destructor != NULL) { - p->destructor(p); + p->destructor(p); } free(p); } @@ -182,17 +182,17 @@ bool unregister_watchdog_unlocked(watchdog_t *wd) foreach_dlist(p, wd_queue) { if (wd == p) { - wd_queue->remove(wd); + wd_queue->remove(wd); Dmsg1(400, "Unregistered watchdog %p\n", wd); - return true; + return true; } } foreach_dlist(p, wd_inactive) { if (wd == p) { - wd_inactive->remove(wd); + wd_inactive->remove(wd); Dmsg1(400, "Unregistered inactive watchdog %p\n", wd); - return true; + return true; } } @@ -236,27 +236,27 @@ extern "C" void *watchdog_thread(void *arg) watchdog_time = time(NULL); foreach_dlist(p, wd_queue) { - if (p->next_fire < watchdog_time) { - /* Run the callback */ - p->callback(p); + if (p->next_fire < watchdog_time) { + /* Run the callback */ + p->callback(p); /* Reschedule (or move to inactive list if it's a one-shot timer) */ - if (p->one_shot) { - /* - * Note, when removing an item while walking the list - * we must get the previous pointer (q) and set the - * current pointer (p) to this previous pointer after + if (p->one_shot) { + /* + * Note, when removing an item while walking the list + * we must get the previous pointer (q) and set the + * current pointer (p) to this previous pointer after * removing the current pointer, otherwise, we won't - * walk the rest of the list. - */ - q = (watchdog_t *)wd_queue->prev(p); - wd_queue->remove(p); - wd_inactive->append(p); - p = q; - } else { - p->next_fire = watchdog_time + p->interval; - } - } + * walk the rest of the list. + */ + q = (watchdog_t *)wd_queue->prev(p); + wd_queue->remove(p); + wd_inactive->append(p); + p = q; + } else { + p->next_fire = watchdog_time + p->interval; + } + } } wd_unlock(); unlock_jcr_chain(); @@ -277,7 +277,7 @@ static void wd_lock() int errstat; if ((errstat=rwl_writelock(&lock)) != 0) { Emsg1(M_ABORT, 0, "rwl_writelock failure. ERR=%s\n", - strerror(errstat)); + strerror(errstat)); } } @@ -291,6 +291,6 @@ static void wd_unlock() int errstat; if ((errstat=rwl_writeunlock(&lock)) != 0) { Emsg1(M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n", - strerror(errstat)); + strerror(errstat)); } } diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 935906d837..d7698b9a75 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -216,10 +216,6 @@ int dir_update_volume_info(JCR *jcr, DEVICE *dev, int label) Jmsg0(jcr, M_ERROR, 0, _("Attempt to update_volume_info in read mode!!!\n")); return 0; } - if (!dev_state(dev, ST_LABEL)) { - Jmsg0(jcr, M_ERROR, 0, _("Attempt to update_volume_info on non-labeled Volume!!!\n")); - return 0; - } Dmsg1(100, "Update cat VolFiles=%d\n", dev->file); /* Just labeled or relabeled the tape */ diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 112c5d8082..15c407b7d3 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -338,7 +338,7 @@ static void labelcmd() } } rewind_dev(dev); - write_volume_label_to_dev(jcr, jcr->device, cmd, "Default"); + write_new_volume_label_to_dev(jcr, jcr->device, cmd, "Default"); Pmsg1(-1, "Wrote Volume label for volume \"%s\".\n", cmd); } diff --git a/bacula/src/stored/butil.c b/bacula/src/stored/butil.c index 82cffafb3d..ada7ddacc0 100644 --- a/bacula/src/stored/butil.c +++ b/bacula/src/stored/butil.c @@ -212,7 +212,6 @@ static void my_free_jcr(JCR *jcr) free_dcr(jcr->dcr); jcr->dcr = NULL; } - return; } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 39c33bfecc..9a7560f4dc 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -118,7 +118,7 @@ static struct s_cmds cmds[] = { * - We execute the command * - We continue or exit depending on the return status */ -void *connection_request(void *arg) +void *handle_connection_request(void *arg) { BSOCK *bs = (BSOCK *)arg; JCR *jcr; @@ -129,6 +129,7 @@ void *connection_request(void *arg) if (bnet_recv(bs) <= 0) { Emsg0(M_ERROR, 0, _("Connection request failed.\n")); + bnet_close(bs); return NULL; } @@ -137,6 +138,8 @@ void *connection_request(void *arg) */ if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)-25) { Emsg1(M_ERROR, 0, _("Invalid Dir connection. Len=%d\n"), bs->msglen); + bnet_close(bs); + return NULL; } /* * See if this is a File daemon connection. If so @@ -152,6 +155,13 @@ void *connection_request(void *arg) jcr = new_jcr(sizeof(JCR), stored_free_jcr); /* create Job Control Record */ jcr->dir_bsock = bs; /* save Director bsock */ jcr->dir_bsock->jcr = jcr; + /* Initialize FD start condition variable */ + int errstat = pthread_cond_init(&jcr->job_start_wait, NULL); + if (errstat != 0) { + Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat)); + free_jcr(jcr); + return NULL; + } Dmsg0(1000, "stored in start_job\n"); @@ -393,7 +403,7 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname, /* Fall through wanted! */ case VOL_IO_ERROR: case VOL_NO_LABEL: - if (!write_volume_label_to_dev(jcr, jcr->device, newname, poolname)) { + if (!write_new_volume_label_to_dev(jcr, jcr->device, newname, poolname)) { bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev)); break; } diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index 9451ea3735..0e76449a55 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -133,12 +133,6 @@ int job_cmd(JCR *jcr) free_memory(fileset_name); free_memory(fileset_md5); - /* Initialize FD start condition variable */ - if ((errstat = pthread_cond_init(&jcr->job_start_wait, NULL)) != 0) { - Jmsg1(jcr, M_FATAL, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat)); - set_jcr_job_status(jcr, JS_ErrorTerminated); - return 0; - } jcr->authenticated = false; /* @@ -166,7 +160,6 @@ int job_cmd(JCR *jcr) timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + 30 * 60; /* wait 30 minutes */ - Dmsg1(100, "%s waiting on FD to contact SD\n", jcr->Job); /* * Wait for the File daemon to contact us to start the Job, diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 79a3b3b8eb..f4d25b95b6 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -238,10 +238,10 @@ int unser_volume_label(DEVICE *dev, DEV_RECORD *rec) /* * Put a volume label into the block * - * Returns: 0 on failure - * 1 on success + * Returns: false on failure + * true on success */ -int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) +bool write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) { DEV_RECORD rec; @@ -257,12 +257,12 @@ int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) free_pool_memory(rec.data); Jmsg1(jcr, M_FATAL, 0, _("Cannot write Volume label to block for device %s\n"), dev_name(dev)); - return 0; + return false; } else { Dmsg1(90, "Wrote label of %d bytes to block\n", rec.data_len); } free_pool_memory(rec.data); - return 1; + return true; } /* @@ -374,12 +374,12 @@ void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName) * * This routine should be used only when labeling a blank tape. */ -int write_volume_label_to_dev(JCR *jcr, DEVRES *device, const char *VolName, const char *PoolName) +bool write_new_volume_label_to_dev(JCR *jcr, DEVRES *device, const char *VolName, const char *PoolName) { DEVICE *dev = device->dev; DEV_RECORD rec; DEV_BLOCK *block; - int stat = 1; + bool stat = true; Dmsg0(99, "write_volume_label()\n"); @@ -389,7 +389,7 @@ int write_volume_label_to_dev(JCR *jcr, DEVRES *device, const char *VolName, con memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); Dmsg2(30, "Bad status on %s from rewind. ERR=%s\n", dev_name(dev), strerror_dev(dev)); if (!forge_on) { - return 0; + return false; } } @@ -404,7 +404,7 @@ int write_volume_label_to_dev(JCR *jcr, DEVRES *device, const char *VolName, con memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); free_block(block); free_pool_memory(rec.data); - return 0; + return false; } else { Dmsg2(30, "Wrote label of %d bytes to %s\n", rec.data_len, dev_name(dev)); } @@ -414,7 +414,7 @@ int write_volume_label_to_dev(JCR *jcr, DEVRES *device, const char *VolName, con if (!write_block_to_dev(jcr->dcr, block)) { memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); Dmsg2(30, "Bad Label write on %s. ERR=%s\n", dev_name(dev), strerror_dev(dev)); - stat = 9; + stat = false; } Dmsg0(99, " Wrote block to device\n"); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index de9d151826..4f23f83c58 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -30,6 +30,9 @@ #include "bacula.h" /* pull in global headers */ #include "stored.h" /* pull in Storage Deamon headers */ +static bool rewrite_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *bloc, bool recycle); + + /* * If release is set, we rewind the current volume, * which we no longer want, and ask the user (console) @@ -42,7 +45,7 @@ * impossible to get the requested Volume. * */ -int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release) +int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool release) { int retry = 0; bool ask = false, recycle, autochanger; @@ -187,12 +190,9 @@ read_volume: /* If not removable, Volume is broken */ if (!dev_cap(dev, CAP_REM)) { - bstrncpy(jcr->VolCatInfo.VolCatStatus, "Error", - sizeof(jcr->VolCatInfo.VolCatStatus)); - memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(dev->VolCatInfo)); - dir_update_volume_info(jcr, dev, 1); /* indicate tape labeled */ - Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s. Volume marked in error.\n"), + Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"), jcr->VolumeName, dev_name(dev)); + mark_volume_in_error(jcr, dev); goto mount_next_vol; } @@ -249,7 +249,8 @@ read_volume: (!dev_is_tape(dev) && strcmp(jcr->VolCatInfo.VolCatStatus, "Recycle") == 0))) { Dmsg0(100, "Create volume label\n"); - if (!write_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName, + /* Create a new Volume label and write it to the device */ + if (!write_new_volume_label_to_dev(jcr, (DEVRES *)dev->device, jcr->VolumeName, jcr->pool_name)) { Dmsg0(100, "!write_vol_label\n"); goto mount_next_vol; @@ -264,12 +265,9 @@ read_volume: } /* If not removable, Volume is broken */ if (!dev_cap(dev, CAP_REM)) { - bstrncpy(jcr->VolCatInfo.VolCatStatus, "Error", - sizeof(jcr->VolCatInfo.VolCatStatus)); - memcpy(&dev->VolCatInfo, &jcr->VolCatInfo, sizeof(dev->VolCatInfo)); - dir_update_volume_info(jcr, dev, 1); /* indicate tape labeled */ - Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s. Volume marked in error.\n"), + Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"), jcr->VolumeName, dev_name(dev)); + mark_volume_in_error(jcr, dev); goto mount_next_vol; } /* NOTE! Fall-through wanted. */ @@ -299,63 +297,9 @@ read_volume: * If the tape is marked as Recycle, we rewrite the label. */ if (dev->VolHdr.LabelType == PRE_LABEL || recycle) { - Dmsg1(190, "ready_for_append found freshly labeled volume. dev=%x\n", dev); - dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */ - write_volume_label_to_block(jcr, dev, block); - /* - * If we are not dealing with a streaming device, - * write the block now to ensure we have write permission. - * It is better to find out now rather than later. - */ - if (!dev_cap(dev, CAP_STREAM)) { - if (!rewind_dev(dev)) { - Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device \"%s\". ERR=%s\n"), - dev_name(dev), strerror_dev(dev)); - } - if (recycle) { - if (!truncate_dev(dev)) { - Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device \"%s\". ERR=%s\n"), - dev_name(dev), strerror_dev(dev)); - } - } - /* Attempt write to check write permission */ - if (!write_block_to_dev(jcr->dcr, block)) { - Jmsg2(jcr, M_ERROR, 0, _("Unable to write device \"%s\". ERR=%s\n"), - dev_name(dev), strerror_dev(dev)); - goto mount_next_vol; - } - } - /* Set or reset Volume statistics */ - dev->VolCatInfo.VolCatJobs = 0; - dev->VolCatInfo.VolCatFiles = 0; - dev->VolCatInfo.VolCatBytes = 1; - dev->VolCatInfo.VolCatErrors = 0; - dev->VolCatInfo.VolCatBlocks = 0; - dev->VolCatInfo.VolCatRBytes = 0; - if (recycle) { - dev->VolCatInfo.VolCatMounts++; - dev->VolCatInfo.VolCatRecycles++; - } else { - dev->VolCatInfo.VolCatMounts = 1; - dev->VolCatInfo.VolCatRecycles = 0; - dev->VolCatInfo.VolCatWrites = 1; - dev->VolCatInfo.VolCatReads = 1; - } - Dmsg0(100, "dir_update_vol_info. Set Append\n"); - bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus)); - dir_update_volume_info(jcr, dev, 1); /* indicate doing relabel */ - if (recycle) { - Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\" on device \"%s\", all previous data lost.\n"), - jcr->VolumeName, dev_name(dev)); - } else { - Jmsg(jcr, M_INFO, 0, _("Wrote label to prelabeled Volume \"%s\" on device \"%s\"\n"), - jcr->VolumeName, dev_name(dev)); + if (!rewrite_volume_label(jcr, dev, block, recycle)) { + goto mount_next_vol; } - /* - * End writing real Volume label (from pre-labeled tape), or recycling - * the volume. - */ - } else { /* * OK, at this point, we have a valid Bacula label, but @@ -399,6 +343,75 @@ The number of files mismatch! Volume=%u Catalog=%u\n"), return 1; } +/* + * Write a volume label. + * Returns: true if OK + * false if unable to write it + */ +static bool rewrite_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool recycle) +{ + Dmsg1(190, "ready_for_append found freshly labeled volume. dev=%x\n", dev); + dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */ + if (!write_volume_label_to_block(jcr, dev, block)) { + return false; + } + /* + * If we are not dealing with a streaming device, + * write the block now to ensure we have write permission. + * It is better to find out now rather than later. + */ + if (!dev_cap(dev, CAP_STREAM)) { + if (!rewind_dev(dev)) { + Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device \"%s\". ERR=%s\n"), + dev_name(dev), strerror_dev(dev)); + } + if (recycle) { + if (!truncate_dev(dev)) { + Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device \"%s\". ERR=%s\n"), + dev_name(dev), strerror_dev(dev)); + } + } + /* Attempt write to check write permission */ + if (!write_block_to_dev(jcr->dcr, block)) { + Jmsg2(jcr, M_ERROR, 0, _("Unable to write device \"%s\". ERR=%s\n"), + dev_name(dev), strerror_dev(dev)); + return false; + } + } + /* Set or reset Volume statistics */ + dev->VolCatInfo.VolCatJobs = 0; + dev->VolCatInfo.VolCatFiles = 0; + dev->VolCatInfo.VolCatBytes = 1; + dev->VolCatInfo.VolCatErrors = 0; + dev->VolCatInfo.VolCatBlocks = 0; + dev->VolCatInfo.VolCatRBytes = 0; + if (recycle) { + dev->VolCatInfo.VolCatMounts++; + dev->VolCatInfo.VolCatRecycles++; + } else { + dev->VolCatInfo.VolCatMounts = 1; + dev->VolCatInfo.VolCatRecycles = 0; + dev->VolCatInfo.VolCatWrites = 1; + dev->VolCatInfo.VolCatReads = 1; + } + Dmsg0(100, "dir_update_vol_info. Set Append\n"); + bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus)); + dir_update_volume_info(jcr, dev, 1); /* indicate doing relabel */ + if (recycle) { + Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\" on device \"%s\", all previous data lost.\n"), + jcr->VolumeName, dev_name(dev)); + } else { + Jmsg(jcr, M_INFO, 0, _("Wrote label to prelabeled Volume \"%s\" on device \"%s\"\n"), + jcr->VolumeName, dev_name(dev)); + } + /* + * End writing real Volume label (from pre-labeled tape), or recycling + * the volume. + */ + return true; +} + + /* * Mark volume in error in catalog */ diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 819251964f..e37159ad78 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -133,7 +133,7 @@ void set_new_file_parameters(JCR *jcr, DEVICE *dev); int device_is_unmounted(DEVICE *dev); /* From dircmd.c */ -void *connection_request(void *arg); +void *handle_connection_request(void *arg); /* From fd_cmds.c */ @@ -148,9 +148,9 @@ void handle_filed_connection(BSOCK *fd, char *job_name); int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); void create_session_label(JCR *jcr, DEV_RECORD *rec, int label); void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName); -int write_volume_label_to_dev(JCR *jcr, DEVRES *device, const char *VolName, const char *PoolName); +bool write_new_volume_label_to_dev(JCR *jcr, DEVRES *device, const char *VolName, const char *PoolName); int write_session_label(JCR *jcr, DEV_BLOCK *block, int label); -int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +bool write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); void dump_volume_label(DEVICE *dev); void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); int unser_volume_label(DEVICE *dev, DEV_RECORD *rec); @@ -165,7 +165,7 @@ BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev); bool match_set_eof(BSR *bsr, DEV_RECORD *rec); /* From mount.c */ -int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release); +int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, bool release); int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); void release_volume(JCR *jcr, DEVICE *dev); void mark_volume_in_error(JCR *jcr, DEVICE *dev); diff --git a/bacula/src/stored/stored.c b/bacula/src/stored/stored.c index fe12febbea..7646be3221 100644 --- a/bacula/src/stored/stored.c +++ b/bacula/src/stored/stored.c @@ -228,7 +228,7 @@ int main (int argc, char *argv[]) /* Single server used for Director and File daemon */ bnet_thread_server(me->SDaddr, me->SDport, me->max_concurrent_jobs * 2 + 1, - &dird_workq, connection_request); + &dird_workq, handle_connection_request); exit(1); /* to keep compiler quiet */ } @@ -324,6 +324,12 @@ void *device_allocation(void *arg) JCR *jcr; DCR *dcr; jcr = new_jcr(sizeof(JCR), stored_free_jcr); + jcr->JobType = JT_SYSTEM; + /* Initialize FD start condition variable */ + int errstat = pthread_cond_init(&jcr->job_start_wait, NULL); + if (errstat != 0) { + Jmsg1(jcr, M_ABORT, 0, _("Unable to init job cond variable: ERR=%s\n"), strerror(errstat)); + } jcr->device = device; dcr = new_dcr(jcr, device->dev); switch (read_dev_volume_label(jcr, device->dev, dcr->block)) { diff --git a/bacula/src/version.h b/bacula/src/version.h index 5e3765645d..27fb0a9f1d 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -2,8 +2,8 @@ #undef VERSION #define VERSION "1.35.0" #define VSTRING "1" -#define BDATE "18 June 2004" -#define LSMDATE "18Jun04" +#define BDATE "19 June 2004" +#define LSMDATE "19Jun04" /* Debug flags */ #undef DEBUG @@ -12,6 +12,9 @@ #define SMCHECK #define TRACE_FILE 1 +// #define TRACE_JCR_CHAIN 1 +// #define TRACE_RES 1 + /* #define FULL_DEBUG 1 */ /* normally on for testing only */ /* Turn this on ONLY if you want all Dmsg() to append to the -- 2.39.5