]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/read_record.c
!!! I didn't run the regression tests.!!!
[bacula/bacula] / bacula / src / stored / read_record.c
index ea8b513f99093dae63549ab3bdb5893e125e2613..5ecfdf7c4e8ecd15363dd820be5cb86c9f77e9e1 100644 (file)
@@ -11,7 +11,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+   Copyright (C) 2000-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -41,36 +41,38 @@ static int try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev);
 static char *rec_state_to_str(DEV_RECORD *rec);
 #endif
 
-int read_records(JCR *jcr,  DEVICE *dev, 
-       int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec),
-       int mount_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block))
+bool read_records(DCR *dcr,
+       bool record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec),
+       bool mount_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block))
 {
+   JCR *jcr = dcr->jcr;
+   DEVICE *dev = dcr->dev;
    DEV_BLOCK *block;
    DEV_RECORD *rec = NULL;
    uint32_t record;
-   int ok = TRUE;
+   bool ok = true;
    bool done = false;
    SESSION_LABEL sessrec;
    dlist *recs;                        /* linked list of rec packets open */
 
    block = new_block(dev);
-   recs = new dlist(rec, &rec->link);
+   recs = New(dlist(rec, &rec->link));
    position_to_first_file(jcr, dev);
 
    for ( ; ok && !done; ) {
       if (job_canceled(jcr)) {
-        ok = FALSE;
+        ok = false;
         break;
       }
-      if (!read_block_from_device(jcr, dev, block, CHECK_BLOCK_NUMBERS)) {
+      if (!read_block_from_device(dcr, block, CHECK_BLOCK_NUMBERS)) {
         if (dev_state(dev, ST_EOT)) {
            DEV_RECORD *trec = new_record();
 
-            Jmsg(jcr, M_INFO, 0, "End of Volume at file %u  on device %s, Volume \"%s\"\n", 
+            Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n", 
                 dev->file, dev_name(dev), jcr->VolumeName);
            if (!mount_cb(jcr, dev, block)) {
                Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
-              ok = FALSE;
+              ok = false;
               /*
                * Create EOT Label so that Media record may
                *  be properly updated because this is the last
@@ -87,7 +89,7 @@ int read_records(JCR *jcr,  DEVICE *dev,
             *  and pass it off to the callback routine, then continue
             *  most likely reading the previous record.
             */
-           read_block_from_device(jcr, dev, block, NO_BLOCK_NUMBER_CHECK);
+           read_block_from_device(dcr, block, NO_BLOCK_NUMBER_CHECK);
            read_record_from_block(block, trec);
            handle_session_record(dev, trec, &sessrec);
            ok = record_cb(jcr, dev, block, trec);
@@ -105,18 +107,22 @@ int read_records(JCR *jcr,  DEVICE *dev,
                  dev->file, dev_name(dev), jcr->VolumeName);
            continue;
         } else if (dev_state(dev, ST_SHORT)) {
-            Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
+            Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg);
            continue;
         } else {
            /* I/O error or strange end of tape */
            display_tape_error_status(jcr, dev);
-           ok = FALSE;
+           if (forge_on || jcr->ignore_label_errors) {
+              fsr_dev(dev, 1);       /* try skipping bad record */
+               Dmsg0(000, "Did fsr\n");
+              continue;              /* try to continue */
+           }
+           ok = false;
            break;
         }
       }
       Dmsg2(100, "New block at position=(file:block) %d:%d\n", dev->file, dev->block_num);
-#define FAST_BLOCK_REJECTION
-#ifdef FAST_BLOCK_REJECTION
+#ifdef if_and_when_FAST_BLOCK_REJECTION_is_working
       /* this does not stop when file/block are too big */
       if (!match_bsr_block(jcr->bsr, block)) {
         if (try_repositioning(jcr, rec, dev)) {
@@ -131,7 +137,7 @@ int read_records(JCR *jcr,  DEVICE *dev,
        *   VolSessionId and VolSessionTime 
        */
       bool found = false;
-      for (rec=(DEV_RECORD *)recs->first(); rec; rec=(DEV_RECORD *)recs->next(rec)) {
+      foreach_dlist(rec, recs) {
         if (rec->VolSessionId == block->VolSessionId &&
             rec->VolSessionTime == block->VolSessionTime) {
            found = true;
@@ -237,11 +243,10 @@ int read_records(JCR *jcr,  DEVICE *dev,
 // Dmsg2(100, "Position=(file:block) %d:%d\n", dev->file, dev->block_num);
 
    /* Walk down list and free all remaining allocated recs */
-   for (rec=(DEV_RECORD *)recs->first(); rec; ) {
-      DEV_RECORD *nrec = (DEV_RECORD *)recs->next(rec);
+   while (!recs->empty()) {
+      rec = (DEV_RECORD *)recs->first();
       recs->remove(rec);
       free_record(rec);
-      rec = nrec;
    }
    delete recs;
    print_block_read_errors(jcr, block);
@@ -268,7 +273,7 @@ static int try_repositioning(JCR *jcr, DEV_RECORD *rec, DEVICE *dev)
       return 1;
    }    
    if (bsr) {
-      if (verbose > 1) {
+      if (verbose) {
          Jmsg(jcr, M_INFO, 0, "Reposition from (file:block) %d:%d to %d:%d\n",
            dev->file, dev->block_num, bsr->volfile->sfile,
            bsr->volblock->sblock);
@@ -309,8 +314,9 @@ static BSR *position_to_first_file(JCR *jcr, DEVICE *dev)
 
 static void handle_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
 {
-   char *rtype;
+   const char *rtype;
    char buf[100];
+   
    memset(sessrec, 0, sizeof(sessrec));
    switch (rec->FileIndex) {
    case PRE_LABEL:
@@ -345,19 +351,19 @@ static char *rec_state_to_str(DEV_RECORD *rec)
    static char buf[200]; 
    buf[0] = 0;
    if (rec->state & REC_NO_HEADER) {
-      strcat(buf, "Nohdr,");
+      bstrncat(buf, "Nohdr,", sizeof(buf));
    }
    if (is_partial_record(rec)) {
-      strcat(buf, "partial,");
+      bstrncat(buf, "partial,", sizeof(buf));
    }
    if (rec->state & REC_BLOCK_EMPTY) {
-      strcat(buf, "empty,");
+      bstrncat(buf, "empty,", sizeof(buf));
    }
    if (rec->state & REC_NO_MATCH) {
-      strcat(buf, "Nomatch,");
+      bstrncat(buf, "Nomatch,", sizeof(buf));
    }
    if (rec->state & REC_CONTINUATION) {
-      strcat(buf, "cont,");
+      bstrncat(buf, "cont,", sizeof(buf));
    }
    if (buf[0]) {
       buf[strlen(buf)-1] = 0;