]> git.sur5r.net Git - bacula/bacula/commitdiff
Split out routines into new files + Implement Verify VolumeToCatalog using BSR
authorKern Sibbald <kern@sibbald.com>
Mon, 2 Jun 2003 20:23:51 +0000 (20:23 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 2 Jun 2003 20:23:51 +0000 (20:23 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@561 91ce42f0-d328-0410-95d8-f526ca767f89

15 files changed:
bacula/kernstodo
bacula/src/dird/autoprune.c
bacula/src/dird/backup.c
bacula/src/dird/bsr.c
bacula/src/dird/fd_cmds.c
bacula/src/dird/msgchan.c
bacula/src/dird/protos.h
bacula/src/dird/restore.c
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_run.c
bacula/src/dird/verify.c
bacula/src/filed/job.c
bacula/src/filed/verify.c
bacula/src/jcr.h
bacula/src/lib/smartall.c

index 79bfbfcc7b847ec22ca3b279d06f511baacdf778..4f37ad34ed193b3f5f20ea2775d1f59aedb9ab8f 100644 (file)
@@ -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.
+
index 70cef3fe39d35c9e3c37435bf3d56f9c502e9053..f225dc41e5863672b8393b8e86ffc753cf408bf2 100644 (file)
@@ -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;
+   }
 }
 
 /*
index 976f7151dceb58dbb0a9fd71d9cbd471528f9004..7200a043d5970ea512b0b8fdb3b1b27d5c6012bb 100644 (file)
@@ -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;
 }
 
index 38aa67d2eeb39022603dbbf37a8dfce934b565eb..e8e3508be5060263693fdee7098b7665c9c84916 100644 (file)
@@ -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) {
index 2d08770bc42209224d74752cb3f26b10f58cfe97..3353180ee3f08c77e0c7e7cc66e5e60adf74251b 100644 (file)
@@ -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.
index e3289d9b9d8402f620877e122bb9e09f77d976cc..b227ffe584bea04d7b23dd9bb2c658d85098d3e5 100644 (file)
@@ -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);
 }
index f65d8c8671adcc0178a825323c9ef0fa8ce170b1..3aed86ca04b88eafc565db6da71c8090bf0ea7d5 100644 (file)
@@ -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, 
index 7a448a3e2f79722cb83b5fd30e22d3b7bd265621..a017ab61844f65d0a9cb61d2490f27ff1166e840 100644 (file)
@@ -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;
-}
index 62a6ada498f294e4cbf5decf22f4922e7ba02462..44eaf6935a3876e0148832414bbf1082ccb65d75 100644 (file)
@@ -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 {
index d72f18962a201652531c7a3f04718c1679a1e370..e33543e4083ec22ae89605b6a92ebdb17a23c424 100644 (file)
@@ -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;
index 4df5ca6eb6feb6138dc8e7d40c574e1aa271d7e1..31bc11d25199f64796c211a20c7b144947a0fbdb 100644 (file)
@@ -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);
index 45cbdeca6126f60da2bff9d30eb94a6c214e97f2..41e83b349a8bcbb3df1966d9e5537781e6c9b385 100644 (file)
@@ -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 */
index 211f62e9d7b6f93c049dbab13cf9b2f6c943f26b..65b1607f8ccd93a590138ec2c63c854c785ea8ba 100644 (file)
@@ -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);
 
index 02bc36c4f9dff2b114e7059f60cd95f7f352b6c1..19968c0a3cbf7da91b75062dde64a6abc54bd10a 100644 (file)
@@ -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 */
index 32aa392f0758bded4e64ba0d2dc5232b49b04a87..5950cf794df2de8322d583bce8572e2bd22cb0c6 100644 (file)
@@ -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);
 }