]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/bscan.c
- Send all queued messages in SD and FD prior to closing down
[bacula/bacula] / bacula / src / stored / bscan.c
index add9076726e0191fea7f76872f3b1a9fede8a18c..45f53f5332e447bc80d1323f1d9625fef7ef8203 100644 (file)
@@ -90,6 +90,9 @@ static bool update_vol_info = false;
 static bool list_records = false;
 static int ignored_msgs = 0;
 
+static uint64_t currentVolumeSize;
+static int64_t last_pct = -1;
+static bool showProgress = false;
 static int num_jobs = 0;
 static int num_pools = 0;
 static int num_media = 0;
@@ -103,6 +106,7 @@ bool forge_on = false;
 static void usage()
 {
    fprintf(stderr, _(
+"Copyright (C) 2001-2004 Kern Sibbald and John Walker.\n"
 "\nVersion: " VERSION " (" BDATE ")\n\n"
 "Usage: bscan [ options ] <bacula-archive>\n"
 "       -b bootstrap      specify a bootstrap file\n"
@@ -133,8 +137,11 @@ int main (int argc, char *argv[])
    init_msg(NULL, NULL);
 
 
-   while ((ch = getopt(argc, argv, "b:c:d:h:mn:pP:rsu:vV:w:?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:c:d:h:mn:pP:rsSu:vV:w:?")) != -1) {
       switch (ch) {
+      case 'S' :
+        showProgress = true;
+        break;
       case 'b':
         bsr = parse_bsr(NULL, optarg);
         break;
@@ -248,6 +255,12 @@ int main (int argc, char *argv[])
    if (!dev) { 
       exit(1);
    }
+   if (showProgress) {
+      struct stat sb;
+      fstat(dev->fd, &sb);
+      currentVolumeSize = sb.st_size;
+      Pmsg1(000, _("Current Volume Size = %" llu "\n"), currentVolumeSize);
+   }
 
    if ((db=db_init_database(NULL, db_name, db_user, db_password, db_host, 0, NULL)) == NULL) {
       Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n"));
@@ -266,6 +279,7 @@ int main (int argc, char *argv[])
       num_media, num_pools, num_jobs, num_files);
 
    free_jcr(bjcr);
+   term_dev(dev);
    return 0;
 }
   
@@ -277,8 +291,12 @@ int main (int argc, char *argv[])
 static bool bscan_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
 {
    Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
-   for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
-      DCR *dcr = mjcr->dcr;
+   DCR *dcr;
+   foreach_dlist(dcr, dev->attached_dcrs) {
+      JCR *mjcr = dcr->jcr;
+      if (mjcr->JobId == 0) {
+        continue;
+      }
       if (verbose) {
          Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job);
       }
@@ -299,8 +317,13 @@ static bool bscan_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block
     * have the Volume list, but we get attached.
     */
    bool stat = mount_next_read_volume(jcr, dev, block);
-   /* we must once more detach ourselves (attached by mount_next ...) */
-   detach_jcr_from_device(dev, jcr); /* detach bscan jcr */
+
+   if (showProgress) {
+      struct stat sb;
+      fstat(dev->fd, &sb);
+      currentVolumeSize = sb.st_size;
+      Pmsg1(000, _("Current Volume Size = %" llu "\n"), currentVolumeSize);
+   }
    return stat;
 }
 
@@ -316,17 +339,15 @@ static void do_scan()
    memset(&fr, 0, sizeof(fr));
 
    /* Detach bscan's jcr as we are not a real Job on the tape */
-   detach_jcr_from_device(dev, bjcr);
 
    read_records(bjcr->dcr, record_cb, bscan_mount_next_read_volume);
-   release_device(bjcr);
+// release_device(bjcr);
 
    free_attr(attr);
-   term_dev(dev);
 }
 
 /*
- * Returns: true if OK
+ * Returns: true  if OK
  *         false if error
  */
 static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
@@ -337,7 +358,16 @@ static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
    if (rec->data_len > 0) {
       mr.VolBytes += rec->data_len + WRITE_RECHDR_LENGTH; /* Accumulate Volume bytes */
+      if (showProgress) {
+        int64_t pct = (mr.VolBytes * 100) / currentVolumeSize;
+        if (pct != last_pct) {
+            fprintf(stdout, "done: %" lld "\n", pct);
+           fflush(stdout);
+           last_pct = pct;
+        }
+      }
    }
+   
    if (list_records) {
       Pmsg5(000, _("Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n"),
            rec->VolSessionId, rec->VolSessionTime, rec->FileIndex, 
@@ -412,8 +442,7 @@ static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
             Pmsg1(000, _("Media type \"%s\" is OK.\n"), mr.MediaType);
         }
         /* Reset some JCR variables */
-        for (mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
-           dcr = mjcr->dcr;
+        foreach_dlist(dcr, dev->attached_dcrs) {
            dcr->VolFirstIndex = dcr->FileIndex = 0;
            dcr->StartBlock = dcr->EndBlock = 0;
            dcr->StartFile = dcr->EndFile = 0;
@@ -432,7 +461,7 @@ static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
         }
         unser_session_label(&label, rec);
         memset(&jr, 0, sizeof(jr));
-        jr.JobId = label.JobId;
+        bstrncpy(jr.Job, label.Job, sizeof(jr.Job));
         if (db_get_job_record(bjcr, db, &jr)) {
            /* Job record already exists in DB */
             update_db = false;  /* don't change db in create_job_record */
@@ -525,7 +554,7 @@ static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
         /* Create JobMedia record */
         create_jobmedia_record(db, mjcr);
-        detach_jcr_from_device(dev, mjcr);
+        dev->attached_dcrs->remove(mjcr->dcr);
         free_jcr(mjcr);
 
         break;
@@ -539,10 +568,14 @@ static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
          *   them.
          */
         if (update_db) {
-           mjcr=next_attached_jcr(dev, NULL);
-           for ( ; mjcr; ) {
-              JCR *njcr; 
+           DCR *mdcr;
+           foreach_dlist(mdcr, dev->attached_dcrs) {
+              JCR *mjcr = mdcr->jcr;
+              if (!mjcr || mjcr->JobId == 0) {
+                 continue;
+              }
               jr.JobId = mjcr->JobId;
+              /* Mark Job as Error Terimined */
               jr.JobStatus = JS_ErrorTerminated;
               jr.JobFiles = mjcr->JobFiles;
               jr.JobBytes = mjcr->JobBytes;
@@ -553,9 +586,8 @@ static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
               if (!db_update_job_end_record(bjcr, db, &jr)) {
                   Pmsg1(0, _("Could not update job record. ERR=%s\n"), db_strerror(db));
               }
-              njcr = mjcr->next_dev;
+              mjcr->dcr = NULL;
               free_jcr(mjcr);
-              mjcr = njcr;
            }
         }
         mr.VolFiles = rec->File;
@@ -617,14 +649,8 @@ static bool record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
                     edit_uint64_with_commas(rec->Block, ed3),
                     edit_uint64_with_commas(mr.VolBytes, ed4));
       } 
-      if (db_get_file_attributes_record(bjcr, db, attr->fname, NULL, &fr)) {
-        if (verbose > 1) {
-            Pmsg1(000, _("File record already exists for: %s\n"), attr->fname);
-        }
-      } else {
-        create_file_attributes_record(db, mjcr, attr->fname, attr->lname, 
+      create_file_attributes_record(db, mjcr, attr->fname, attr->lname, 
            attr->type, attr->attr, rec);
-      }
       free_jcr(mjcr);
       break;
 
@@ -997,7 +1023,8 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel,
       return 0;
    }
    if (verbose) {
-      Pmsg1(000, _("Updated Job termination record for new JobId=%u\n"), jr->JobId);
+      Pmsg2(000, _("Updated Job termination record for JobId=%u TermStat=%c\n"), jr->JobId,
+        jr->JobStatus);
    }
    if (verbose > 1) {
       const char *term_msg;
@@ -1113,7 +1140,7 @@ static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type)
       return 0;
    }
 
-   if (!update_db) {
+   if (!update_db || mjcr->FileId == 0) {
       free_jcr(mjcr);
       return 1;
    }
@@ -1152,7 +1179,7 @@ static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId)
    jobjcr->VolSessionId = rec->VolSessionId;
    jobjcr->VolSessionTime = rec->VolSessionTime;
    jobjcr->ClientId = jr->ClientId;
-   attach_jcr_to_device(dev, jobjcr);
+// attach_jcr_to_device(dev, jobjcr);
    new_dcr(jobjcr, dev);
    return jobjcr;
 }