From: Kern Sibbald Date: Mon, 2 Jun 2003 20:23:51 +0000 (+0000) Subject: Split out routines into new files + Implement Verify VolumeToCatalog using BSR X-Git-Tag: Release-1.31~95 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=363e996c0d6e3109e6fffb02866df7e47ef10160;p=bacula%2Fbacula Split out routines into new files + Implement Verify VolumeToCatalog using BSR git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@561 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index 79bfbfcc7b..4f37ad34ed 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -30,12 +30,12 @@ Testing to do: (painful) - Figure out how to use ssh or stunnel to protect Bacula communications. For 1.31 release: +- Make bootstrap filename unique. - Implement FileSet VolIndex. - Sort JobIds entered into recover tree. - The bsr for Dan's job has file indexes covering the whole range rather than only the range contained on the volume. Constrain FileIndex to be within range for Volume. -- Fix Verify VolumeToCatalog to use BSRs -- it is broken. - Should Bacula make an Append tape as Purged when purging? - Test a second language e.g. french. - Start working on Base jobs. @@ -915,3 +915,5 @@ Done: (see kernsdone for more) - Bytes restored is wrong. - The "List last 20 Jobs run" doesnt work correctly in restore. It doesnt show the last 20 jobs , but some older ones. +- Fix Verify VolumeToCatalog to use BSRs -- it is broken. + diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index 70cef3fe39..f225dc41e5 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -58,6 +58,11 @@ void free_ua_context(UAContext *ua) if (ua->args) { free_pool_memory(ua->args); } + if (ua->prompt) { + free(ua->prompt); + ua->prompt = NULL; + ua->max_prompts = 0; + } } /* diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 976f7151dc..7200a043d5 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -306,18 +306,27 @@ int wait_for_job_termination(JCR *jcr) /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/Errors */ wait_for_storage_daemon_termination(jcr); - /* Return the first error status we find FD or SD */ - if (fd_ok && jcr->JobStatus != JS_Terminated) { - return jcr->JobStatus; + /* Return values from FD */ + if (fd_ok) { + jcr->JobFiles = JobFiles; + jcr->Errors = Errors; + jcr->ReadBytes = ReadBytes; + jcr->JobBytes = JobBytes; } + +// Dmsg4(000, "fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", fd_ok, jcr->FDJobStatus, +// jcr->JobStatus, jcr->SDJobStatus); + + /* Return the first error status we find Dir, FD, or SD */ if (!fd_ok || is_bnet_error(fd)) { - return JS_ErrorTerminated; + jcr->FDJobStatus = JS_ErrorTerminated; + } + if (jcr->JobStatus != JS_Terminated) { + return jcr->JobStatus; + } + if (jcr->FDJobStatus != JS_Terminated) { + return jcr->FDJobStatus; } - /* Return values from FD */ - jcr->JobFiles = JobFiles; - jcr->Errors = Errors; - jcr->ReadBytes = ReadBytes; - jcr->JobBytes = JobBytes; return jcr->SDJobStatus; } diff --git a/bacula/src/dird/bsr.c b/bacula/src/dird/bsr.c index 38aa67d2ee..e8e3508be5 100644 --- a/bacula/src/dird/bsr.c +++ b/bacula/src/dird/bsr.c @@ -41,7 +41,7 @@ static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd); /* * Create new FileIndex entry for BSR */ -static RBSR_FINDEX *new_findex() +RBSR_FINDEX *new_findex() { RBSR_FINDEX *fi = (RBSR_FINDEX *)bmalloc(sizeof(RBSR_FINDEX)); memset(fi, 0, sizeof(RBSR_FINDEX)); @@ -160,7 +160,8 @@ int write_bsr_file(UAContext *ua, RBSR *bsr) bsendmsg(ua, _("Bootstrap records written to %s\n"), fname); /* Tell the user what he will need to mount */ - bsendmsg(ua, _("\nThe restore job will require the following Volumes:\n")); + bsendmsg(ua, "\n"); + bsendmsg(ua, _("The restore job will require the following Volumes:\n")); /* Create Unique list of Volumes using prompt list */ start_prompt(ua, ""); for (RBSR *nbsr=bsr; nbsr; nbsr=nbsr->next) { diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 2d08770bc4..3353180ee3 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -42,9 +42,10 @@ static char jobcmd[] = "JobId=%d Job=%s SDid=%u SDtime=%u Authorization=%s\ /* Responses received from File daemon */ -static char OKinc[] = "2000 OK include\n"; -static char OKexc[] = "2000 OK exclude\n"; -static char OKjob[] = "2000 OK Job"; +static char OKinc[] = "2000 OK include\n"; +static char OKexc[] = "2000 OK exclude\n"; +static char OKjob[] = "2000 OK Job"; +static char OKbootstrap[] = "2000 OK bootstrap\n"; /* Forward referenced functions */ @@ -271,6 +272,45 @@ int send_exclude_list(JCR *jcr) } +/* + * Send bootstrap file if any to the File daemon. + * This is used for restore and verify VolumeToCatalog + */ +int send_bootstrap_file(JCR *jcr) +{ + FILE *bs; + char buf[1000]; + BSOCK *fd = jcr->file_bsock; + char *bootstrap = "bootstrap\n"; + + Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap); + if (!jcr->RestoreBootstrap) { + return 1; + } + bs = fopen(jcr->RestoreBootstrap, "r"); + if (!bs) { + Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), + jcr->RestoreBootstrap, strerror(errno)); + set_jcr_job_status(jcr, JS_ErrorTerminated); + return 0; + } + strcpy(fd->msg, bootstrap); + fd->msglen = strlen(fd->msg); + bnet_send(fd); + while (fgets(buf, sizeof(buf), bs)) { + fd->msglen = Mmsg(&fd->msg, "%s", buf); + bnet_send(fd); + } + bnet_sig(fd, BNET_EOD); + fclose(bs); + if (!response(jcr, fd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) { + set_jcr_job_status(jcr, JS_ErrorTerminated); + return 0; + } + return 1; +} + + /* * Read the attributes from the File daemon for * a Verify job and store them in the catalog. diff --git a/bacula/src/dird/msgchan.c b/bacula/src/dird/msgchan.c index e3289d9b9d..b227ffe584 100644 --- a/bacula/src/dird/msgchan.c +++ b/bacula/src/dird/msgchan.c @@ -197,7 +197,7 @@ static void msg_thread_cleanup(void *arg) Dmsg0(200, "End msg_thread\n"); db_end_transaction(jcr, jcr->db); /* terminate any open transaction */ P(jcr->mutex); - jcr->msg_thread_done = TRUE; + jcr->sd_msg_thread_done = true; pthread_cond_broadcast(&jcr->term_wait); /* wakeup any waiting threads */ V(jcr->mutex); free_jcr(jcr); /* release jcr */ @@ -219,6 +219,7 @@ static void *msg_thread(void *arg) int stat; pthread_cleanup_push(msg_thread_cleanup, arg); + jcr->sd_msg_thread_done = false; Dmsg0(200, "msg_thread\n"); sd = jcr->store_bsock; pthread_detach(pthread_self()); @@ -254,9 +255,9 @@ void wait_for_storage_daemon_termination(JCR *jcr) { int cancel_count = 0; /* Now wait for Storage daemon to terminate our message thread */ - P(jcr->mutex); set_jcr_job_status(jcr, JS_WaitSD); - while (!jcr->msg_thread_done) { + P(jcr->mutex); + while (!jcr->sd_msg_thread_done) { struct timeval tv; struct timezone tz; struct timespec timeout; @@ -275,5 +276,5 @@ void wait_for_storage_daemon_termination(JCR *jcr) } } V(jcr->mutex); - set_jcr_job_status(jcr, jcr->SDJobStatus); + set_jcr_job_status(jcr, JS_Terminated); } diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index f65d8c8671..3aed86ca04 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -47,6 +47,7 @@ void free_bsr(RBSR *bsr); int complete_bsr(UAContext *ua, RBSR *bsr); int write_bsr_file(UAContext *ua, RBSR *bsr); void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex); +RBSR_FINDEX *new_findex(); /* catreq.c */ @@ -61,6 +62,7 @@ extern int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time, int verbose); extern int send_include_list(JCR *jcr); extern int send_exclude_list(JCR *jcr); +extern int send_bootstrap_file(JCR *jcr); extern int get_attributes_and_put_in_catalog(JCR *jcr); extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId); extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname, diff --git a/bacula/src/dird/restore.c b/bacula/src/dird/restore.c index 7a448a3e2f..a017ab6184 100644 --- a/bacula/src/dird/restore.c +++ b/bacula/src/dird/restore.c @@ -1,5 +1,4 @@ /* - * * Bacula Director -- restore.c -- responsible for restoring files * * Kern Sibbald, November MM @@ -51,11 +50,9 @@ static char sessioncmd[] = "session %s %ld %ld %ld %ld %ld %ld\n"; static char OKrestore[] = "2000 OK restore\n"; static char OKstore[] = "2000 OK storage\n"; static char OKsession[] = "2000 OK session\n"; -static char OKbootstrap[] = "2000 OK bootstrap\n"; /* Forward referenced functions */ static void restore_cleanup(JCR *jcr, int status); -static int send_bootstrap_file(JCR *jcr); /* External functions */ @@ -342,37 +339,3 @@ Termination: %s\n\n"), Dmsg0(20, "Leaving restore_cleanup\n"); } - -static int send_bootstrap_file(JCR *jcr) -{ - FILE *bs; - char buf[1000]; - BSOCK *fd = jcr->file_bsock; - char *bootstrap = "bootstrap\n"; - - Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap); - if (!jcr->RestoreBootstrap) { - return 1; - } - bs = fopen(jcr->RestoreBootstrap, "r"); - if (!bs) { - Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), - jcr->RestoreBootstrap, strerror(errno)); - set_jcr_job_status(jcr, JS_ErrorTerminated); - return 0; - } - strcpy(fd->msg, bootstrap); - fd->msglen = strlen(fd->msg); - bnet_send(fd); - while (fgets(buf, sizeof(buf), bs)) { - fd->msglen = Mmsg(&fd->msg, "%s", buf); - bnet_send(fd); - } - bnet_sig(fd, BNET_EOD); - fclose(bs); - if (!response(jcr, fd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) { - set_jcr_job_status(jcr, JS_ErrorTerminated); - return 0; - } - return 1; -} diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 62a6ada498..44eaf6935a 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -507,6 +507,8 @@ static void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op) pr->MaxVolJobs = pool->MaxVolJobs; pr->MaxVolFiles = pool->MaxVolFiles; pr->MaxVolBytes = pool->MaxVolBytes; + pr->AutoPrune = pool->AutoPrune; + pr->Recycle = pool->Recycle; if (pool->label_format) { strcpy(pr->LabelFormat, pool->label_format); } else { diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index d72f18962a..e33543e408 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -511,8 +511,8 @@ When: %s\n"), start_prompt(ua, _("Levels:\n")); add_prompt(ua, _("Initialize Catalog")); add_prompt(ua, _("Verify Catalog")); - add_prompt(ua, _("Verify Volume")); - add_prompt(ua, _("Verify Volume Data")); + add_prompt(ua, _("Verify Volume to Catalog")); + add_prompt(ua, _("Verify Volume Data (not yet implemented)")); switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { case 0: jcr->JobLevel = L_VERIFY_INIT; diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index 4df5ca6eb6..31bc11d251 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -4,12 +4,6 @@ * * Kern Sibbald, October MM * - * This routine is run as a separate thread. There may be more - * work to be done to make it totally reentrant!!!! - * - * Current implementation is Catalog verification only (i.e. no - * verification versus tape). - * * Basic tasks done here: * Open DB * Open connection with File daemon and pass him commands @@ -74,6 +68,7 @@ int do_verify(JCR *jcr) BSOCK *fd; JOB_DBR jr; JobId_t JobId = 0; + int stat; if (!get_or_create_client_record(jcr)) { goto bail_out; @@ -85,8 +80,9 @@ int do_verify(JCR *jcr) * we must look up the time and date of the * last full verify. */ - if (jcr->JobLevel == L_VERIFY_CATALOG || jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { - memcpy(&jr, &(jcr->jr), sizeof(jr)); + if (jcr->JobLevel == L_VERIFY_CATALOG || + jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { + memcpy(&jr, &jcr->jr, sizeof(jr)); if (!db_find_last_jobid(jcr, jcr->db, &jr)) { if (jcr->JobLevel == L_VERIFY_CATALOG) { Jmsg(jcr, M_FATAL, 0, _( @@ -112,7 +108,7 @@ int do_verify(JCR *jcr) } if (!jcr->fname) { - jcr->fname = (char *) get_pool_memory(PM_FNAME); + jcr->fname = get_pool_memory(PM_FNAME); } jcr->jr.JobId = JobId; /* save target JobId */ @@ -121,7 +117,8 @@ int do_verify(JCR *jcr) Jmsg(jcr, M_INFO, 0, _("Start Verify JobId %d Job=%s\n"), jcr->JobId, jcr->Job); - if (jcr->JobLevel == L_VERIFY_CATALOG || jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { + if (jcr->JobLevel == L_VERIFY_CATALOG || + jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { memset(&jr, 0, sizeof(jr)); jr.JobId = JobId; if (!db_get_job_record(jcr, jcr->db, &jr)) { @@ -139,12 +136,36 @@ int do_verify(JCR *jcr) } /* - * If we are verifing a Volume, we need the Storage + * If we are verifying a Volume, we need the Storage * daemon, so open a connection, otherwise, just * create a dummy authorization key (passed to * File daemon but not used). */ if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { + RBSR *bsr = new_bsr(); + UAContext ua; + bsr->JobId = jr.JobId; + create_ua_context(jcr, &ua); + complete_bsr(&ua, bsr); + bsr->fi = new_findex(); + bsr->fi->findex = 1; + bsr->fi->findex2 = jr.JobFiles; + if (!write_bsr_file(&ua, bsr)) { + free_ua_context(&ua); + free_bsr(bsr); + goto bail_out; + } + free_ua_context(&ua); + free_bsr(bsr); + if (jcr->RestoreBootstrap) { + free(jcr->RestoreBootstrap); + } + POOLMEM *fname = get_pool_memory(PM_MESSAGE); + Mmsg(&fname, "%s/restore.bsr", working_directory); + jcr->RestoreBootstrap = bstrdup(fname); + free_pool_memory(fname); + +#ifdef xxx /* * Now find the Volumes we will need for the Verify */ @@ -156,6 +177,7 @@ int do_verify(JCR *jcr) goto bail_out; } Dmsg1(20, "Got job Volume Names: %s\n", jcr->VolumeName); +#endif /* * Start conversation with Storage daemon */ @@ -206,23 +228,35 @@ int do_verify(JCR *jcr) * as the Storage address if appropriate. */ switch (jcr->JobLevel) { - case L_VERIFY_INIT: - level = "init"; - break; - case L_VERIFY_CATALOG: - level = "catalog"; - break; - case L_VERIFY_VOLUME_TO_CATALOG: - /* - * send Storage daemon address to the File daemon - */ - if (jcr->store->SDDport == 0) { - jcr->store->SDDport = jcr->store->SDport; - } - bnet_fsend(fd, storaddr, jcr->store->address, jcr->store->SDDport); - if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) { - goto bail_out; - } + case L_VERIFY_INIT: + level = "init"; + break; + case L_VERIFY_CATALOG: + level = "catalog"; + break; + case L_VERIFY_VOLUME_TO_CATALOG: + /* + * send Storage daemon address to the File daemon + */ + if (jcr->store->SDDport == 0) { + jcr->store->SDDport = jcr->store->SDport; + } + bnet_fsend(fd, storaddr, jcr->store->address, jcr->store->SDDport); + if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) { + goto bail_out; + } + + /* + * Send the bootstrap file -- what Volumes/files to restore + */ + if (!send_bootstrap_file(jcr)) { + goto bail_out; + } + + /* + * The following code is deprecated + */ + if (!jcr->RestoreBootstrap) { /* * Pass the VolSessionId, VolSessionTime, Start and * end File and Blocks on the session command. @@ -235,14 +269,15 @@ int do_verify(JCR *jcr) if (!response(jcr, fd, OKsession, "Session", DISPLAY_ERROR)) { goto bail_out; } - level = "volume"; - break; - case L_VERIFY_DATA: - level = "data"; - break; - default: - Jmsg1(jcr, M_FATAL, 0, _("Unimplemented save level %d\n"), jcr->JobLevel); - goto bail_out; + } + level = "volume"; + break; + case L_VERIFY_DATA: + level = "data"; + break; + default: + Jmsg1(jcr, M_FATAL, 0, _("Unimplemented save level %d\n"), jcr->JobLevel); + goto bail_out; } /* @@ -262,27 +297,21 @@ int do_verify(JCR *jcr) switch (jcr->JobLevel) { case L_VERIFY_CATALOG: Dmsg0(10, "Verify level=catalog\n"); + jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ + jcr->SDJobStatus = JS_Terminated; get_attributes_and_compare_to_catalog(jcr, JobId); break; case L_VERIFY_VOLUME_TO_CATALOG: - int stat; Dmsg0(10, "Verify level=volume\n"); get_attributes_and_compare_to_catalog(jcr, JobId); - stat = jcr->JobStatus; - set_jcr_job_status(jcr, JS_WaitSD); - wait_for_storage_daemon_termination(jcr); - /* If we terminate normally, use SD term code, else, use ours */ - if (stat == JS_Terminated) { - set_jcr_job_status(jcr, jcr->SDJobStatus); - } else { - set_jcr_job_status(jcr, stat); - } break; case L_VERIFY_INIT: /* Build catalog */ Dmsg0(10, "Verify level=init\n"); + jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */ + jcr->SDJobStatus = JS_Terminated; get_attributes_and_put_in_catalog(jcr); break; @@ -291,7 +320,9 @@ int do_verify(JCR *jcr) goto bail_out; } - verify_cleanup(jcr, jcr->JobStatus); + stat = wait_for_job_termination(jcr); + + verify_cleanup(jcr, stat); return 1; bail_out: @@ -307,12 +338,12 @@ static void verify_cleanup(JCR *jcr, int TermCode) { char sdt[50], edt[50]; char ec1[30]; - char term_code[100]; + char term_code[100], fd_term_msg[100], sd_term_msg[100]; char *term_msg; int msg_type; JobId_t JobId; - Dmsg0(100, "Enter verify_cleanup()\n"); +// Dmsg1(000, "Enter verify_cleanup() TermCod=%d\n", TermCode); JobId = jcr->jr.JobId; set_jcr_job_status(jcr, TermCode); @@ -321,28 +352,31 @@ static void verify_cleanup(JCR *jcr, int TermCode) msg_type = M_INFO; /* by default INFO message */ switch (TermCode) { - case JS_Terminated: - term_msg = _("Verify OK"); - break; - case JS_ErrorTerminated: - term_msg = _("*** Verify Error ***"); - msg_type = M_ERROR; /* Generate error message */ - break; - case JS_Canceled: - term_msg = _("Verify Canceled"); - break; - case JS_Differences: - term_msg = _("Verify Differences"); - break; - default: - term_msg = term_code; - sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode); - break; + case JS_Terminated: + term_msg = _("Verify OK"); + break; + case JS_ErrorTerminated: + term_msg = _("*** Verify Error ***"); + msg_type = M_ERROR; /* Generate error message */ + break; + case JS_Canceled: + term_msg = _("Verify Canceled"); + break; + case JS_Differences: + term_msg = _("Verify Differences"); + break; + default: + term_msg = term_code; + sprintf(term_code, _("Inappropriate term code: %c\n"), TermCode); + break; } bstrftime(sdt, sizeof(sdt), jcr->jr.StartTime); bstrftime(edt, sizeof(edt), jcr->jr.EndTime); - Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n\ + jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg)); + if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { + jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg)); + Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n\ JobId: %d\n\ Job: %s\n\ FileSet: %s\n\ @@ -351,18 +385,49 @@ Client: %s\n\ Start time: %s\n\ End time: %s\n\ Files Examined: %s\n\ +Non-fatal FD errors: %d\n\ +FD termination status: %s\n\ +SD termination status: %s\n\ Termination: %s\n\n"), - edt, - jcr->jr.JobId, - jcr->jr.Job, - jcr->fileset->hdr.name, - level_to_str(jcr->JobLevel), - jcr->client->hdr.name, - sdt, - edt, - edit_uint64_with_commas(jcr->JobFiles, ec1), - term_msg); - + edt, + jcr->jr.JobId, + jcr->jr.Job, + jcr->fileset->hdr.name, + level_to_str(jcr->JobLevel), + jcr->client->hdr.name, + sdt, + edt, + edit_uint64_with_commas(jcr->JobFiles, ec1), + jcr->Errors, + fd_term_msg, + sd_term_msg, + term_msg); + } else { + Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n\ +JobId: %d\n\ +Job: %s\n\ +FileSet: %s\n\ +Verify Level: %s\n\ +Client: %s\n\ +Start time: %s\n\ +End time: %s\n\ +Files Examined: %s\n\ +Non-fatal FD errors: %d\n\ +FD termination status: %s\n\ +Termination: %s\n\n"), + edt, + jcr->jr.JobId, + jcr->jr.Job, + jcr->fileset->hdr.name, + level_to_str(jcr->JobLevel), + jcr->client->hdr.name, + sdt, + edt, + edit_uint64_with_commas(jcr->JobFiles, ec1), + jcr->Errors, + fd_term_msg, + term_msg); + } Dmsg0(100, "Leave verify_cleanup()\n"); if (jcr->fname) { free_memory(jcr->fname); diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 45cbdeca61..41e83b349a 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -638,7 +638,7 @@ static int verify_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; BSOCK *sd = jcr->store_bsock; - char level[100]; + char level[100], ed1[50], ed2[50]; jcr->JobType = JT_VERIFY; if (sscanf(dir->msg, verifycmd, level) != 1) { @@ -691,6 +691,13 @@ static int verify_cmd(JCR *jcr) return 0; } + bnet_sig(dir, BNET_EOD); + + /* Send termination status back to Dir */ + bnet_fsend(dir, EndJob, jcr->JobStatus, jcr->JobFiles, + edit_uint64(jcr->ReadBytes, ed1), + edit_uint64(jcr->JobBytes, ed2), jcr->Errors); + /* Inform Director that we are done */ bnet_sig(dir, BNET_TERMINATE); return 0; /* return and terminate command loop */ diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index 211f62e9d7..65b1607f8c 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -38,8 +38,7 @@ static int verify_file(FF_PKT *ff_pkt, void *my_pkt); */ void do_verify(JCR *jcr) { - BSOCK *dir = jcr->dir_bsock; - + set_jcr_job_status(jcr, JS_Running); jcr->buf_size = MAX_NETWORK_BUFFER_SIZE; if ((jcr->big_buf = (char *) malloc(jcr->buf_size)) == NULL) { Jmsg1(jcr, M_ABORT, 0, _("Cannot malloc %d network read buffer\n"), MAX_NETWORK_BUFFER_SIZE); @@ -50,12 +49,11 @@ void do_verify(JCR *jcr) find_files(jcr, (FF_PKT *)jcr->ff, verify_file, (void *)jcr); Dmsg0(10, "End find files\n"); - bnet_sig(dir, BNET_EOD); /* signal end of data */ - if (jcr->big_buf) { free(jcr->big_buf); jcr->big_buf = NULL; } + set_jcr_job_status(jcr, JS_Terminated); } /* @@ -187,7 +185,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) } Dmsg2(20, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg); if (!stat) { - Jmsg(jcr, M_ERROR, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir)); + Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir)); if (is_bopen(&bfd)) { bclose(&bfd); } @@ -205,6 +203,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) if (n < 0) { Jmsg(jcr, M_ERROR, -1, _("Error reading file %s: ERR=%s\n"), ff_pkt->fname, berror(&bfd)); + jcr->Errors++; } MD5Final(signature, &md5c); @@ -223,6 +222,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) if (n < 0) { Jmsg(jcr, M_ERROR, -1, _("Error reading file %s: ERR=%s\n"), ff_pkt->fname, berror(&bfd)); + jcr->Errors++; } SHA1Final(&sha1c, signature); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 02bc36c4f9..19968c0a3c 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -113,7 +113,7 @@ struct JCR { time_t end_time; /* job end time */ POOLMEM *VolumeName; /* Volume name desired -- pool_memory */ POOLMEM *client_name; /* client name */ - char *RestoreBootstrap; /* Bootstrap file to restore */ + POOLMEM *RestoreBootstrap; /* Bootstrap file to restore */ char *sd_auth_key; /* SD auth key */ MSGS *jcr_msgs; /* Copy of message resource -- actually used */ uint32_t ClientId; /* Client associated with Job */ @@ -126,7 +126,7 @@ struct JCR { pthread_t SD_msg_chan; /* Message channel thread id */ pthread_cond_t term_wait; /* Wait for job termination */ workq_ele_t *work_item; /* Work queue item if scheduled */ - volatile int msg_thread_done; /* Set when Storage message thread terms */ + volatile bool sd_msg_thread_done; /* Set when Storage message thread terms */ BSOCK *ua; /* User agent */ JOB *job; /* Job resource */ STORE *store; /* Storage resource */ diff --git a/bacula/src/lib/smartall.c b/bacula/src/lib/smartall.c index 32aa392f07..5950cf794d 100644 --- a/bacula/src/lib/smartall.c +++ b/bacula/src/lib/smartall.c @@ -485,11 +485,13 @@ void sm_static(int mode) void * operator new(size_t size) { +// Dmsg1(000, "new called %d\n", size); return sm_malloc(__FILE__, __LINE__, size); } void operator delete(void *buf) { +// Dmsg1(000, "free called 0x%x\n", buf); sm_free(__FILE__, __LINE__, buf); }