]> git.sur5r.net Git - bacula/bacula/commitdiff
Add write/read and positioning test to btape
authorKern Sibbald <kern@sibbald.com>
Thu, 12 Feb 2004 23:51:44 +0000 (23:51 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 12 Feb 2004 23:51:44 +0000 (23:51 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1050 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/stored/btape.c
bacula/src/stored/dev.c

index ca18e1d8026f75edfedefe07ba4e8a31196f70ca..fcece7f4c97a4b8370d67c7265d4b733c8ab358d 100644 (file)
@@ -505,6 +505,7 @@ static void capcmd()
    printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
    printf("%sFSR ", dev->capabilities & CAP_FSR ? "" : "!");
    printf("%sFSF ", dev->capabilities & CAP_FSF ? "" : "!");
+   printf("%sFASTFSF ", dev->capabilities & CAP_FASTFSF ? "" : "!");
    printf("%sEOM ", dev->capabilities & CAP_EOM ? "" : "!");
    printf("%sREM ", dev->capabilities & CAP_REM ? "" : "!");
    printf("%sRACCESS ", dev->capabilities & CAP_RACCESS ? "" : "!");
@@ -603,11 +604,11 @@ static int re_read_block_test()
    }
 
    Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
-      "I'm going to write three records and an eof\n"
-      "then backup over the eof and re-read the last record.\n"     
+      "I'm going to write three records and an EOF\n"
+      "then backup over the EOF and re-read the last record.\n"     
       "Bacula does this after writing the last block on the\n"
-      "tape to verify that the block was written correctly.\n"
-      "It is not an *essential* feature ...\n\n")); 
+      "tape to verify that the block was written correctly.\n\n"
+      "This is not an *essential* feature ...\n\n")); 
    rewindcmd();
    block = new_block(dev);
    rec = new_record();
@@ -700,6 +701,215 @@ bail_out:
    return stat;
 }
 
+
+/*
+ * This test writes Bacula blocks to the tape in
+ *   several files. It then rewinds the tape and attepts
+ *   to read these blocks back checking the data.
+ */
+static int write_read_test()
+{
+   DEV_BLOCK *block;
+   DEV_RECORD *rec;
+   int stat = 0;
+   int len, i, j;
+
+   Pmsg0(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
+      "I'm going to write 10 records and an EOF\n"
+      "then write 10 records and an EOF, then rewind,\n"     
+      "and re-read the data to verify that it is correct.\n\n"
+      "This is an *essential* feature ...\n\n")); 
+   block = new_block(dev);
+   rec = new_record();
+   if (!rewind_dev(dev)) {
+      Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
+      goto bail_out;
+   }
+   rec->data = check_pool_memory_size(rec->data, block->buf_len);
+   len = rec->data_len = block->buf_len-100;
+   for (i=1; i<=10; i++) {
+      memset(rec->data, i, rec->data_len);
+      if (!write_record_to_block(block, rec)) {
+         Pmsg0(0, _("Error writing record to block.\n")); 
+        goto bail_out;
+      }
+      if (!write_block_to_dev(jcr, dev, block)) {
+         Pmsg0(0, _("Error writing block to device.\n")); 
+        goto bail_out;
+      }
+   }
+   Pmsg1(0, _("Wrote 10 blocks of %d bytes.\n"), rec->data_len);
+   weofcmd();
+   for (i=11; i<=20; i++) {
+      memset(rec->data, i, rec->data_len);
+      if (!write_record_to_block(block, rec)) {
+         Pmsg0(0, _("Error writing record to block.\n")); 
+        goto bail_out;
+      }
+      if (!write_block_to_dev(jcr, dev, block)) {
+         Pmsg0(0, _("Error writing block to device.\n")); 
+        goto bail_out;
+      }
+   }
+   Pmsg1(0, _("Wrote 10 blocks of %d bytes.\n"), rec->data_len);
+   weofcmd();
+   if (dev_cap(dev, CAP_TWOEOF)) {
+      weofcmd();
+   }
+   if (!rewind_dev(dev)) {
+      Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
+      goto bail_out;
+   } else {
+      Pmsg0(0, "Rewind OK.\n");
+   }
+   for (i=1; i<=20; i++) {
+read_again:
+      if (!read_block_from_dev(jcr, dev, block, NO_BLOCK_NUMBER_CHECK)) {
+        if (dev_state(dev, ST_EOF)) {
+            Pmsg0(-1, _("Got EOF on tape.\n"));
+           goto read_again;
+        }
+         Pmsg1(0, _("Read block failed! ERR=%s\n"), strerror(dev->dev_errno));
+        goto bail_out;
+      }
+      memset(rec->data, 0, rec->data_len);
+      if (!read_record_from_block(block, rec)) {
+         Pmsg1(0, _("Read record failed! ERR=%s\n"), strerror(dev->dev_errno));
+        goto bail_out;
+      }
+      for (j=0; j<len; j++) {
+        if (rec->data[j] != i) {
+            Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
+              i, rec->data[j], j);
+           goto bail_out;
+        }
+      }
+      if (i == 10 || i == 20) {
+         Pmsg0(-1, _("10 blocks re-read correctly.\n"));
+      }
+   }
+   Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
+   stat = 1;
+
+bail_out:
+   free_block(block);
+   free_record(rec);
+   return stat;
+}
+
+/*
+ * This test writes Bacula blocks to the tape in
+ *   several files. It then rewinds the tape and attepts
+ *   to read these blocks back checking the data.
+ */
+static int position_test()
+{
+   DEV_BLOCK *block;
+   DEV_RECORD *rec;
+   int stat = 0;
+   int len, i, j;
+
+   Pmsg0(-1, _("\n=== Write, rewind, and position test ===\n\n"
+      "I'm going to write 10 records and an EOF\n"
+      "then write 10 records and an EOF, then rewind,\n"     
+      "and position to a few blocks and verify that it is correct.\n\n"
+      "This is an *essential* feature ...\n\n")); 
+   block = new_block(dev);
+   rec = new_record();
+   if (!rewind_dev(dev)) {
+      Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
+      goto bail_out;
+   }
+   rec->data = check_pool_memory_size(rec->data, block->buf_len);
+   len = rec->data_len = block->buf_len-100;
+   for (i=1; i<=10; i++) {
+      memset(rec->data, i, rec->data_len);
+      if (!write_record_to_block(block, rec)) {
+         Pmsg0(0, _("Error writing record to block.\n")); 
+        goto bail_out;
+      }
+      if (!write_block_to_dev(jcr, dev, block)) {
+         Pmsg0(0, _("Error writing block to device.\n")); 
+        goto bail_out;
+      }
+   }
+   Pmsg1(0, _("Wrote 10 blocks of %d bytes.\n"), rec->data_len);
+   weofcmd();
+   for (i=11; i<=20; i++) {
+      memset(rec->data, i, rec->data_len);
+      if (!write_record_to_block(block, rec)) {
+         Pmsg0(0, _("Error writing record to block.\n")); 
+        goto bail_out;
+      }
+      if (!write_block_to_dev(jcr, dev, block)) {
+         Pmsg0(0, _("Error writing block to device.\n")); 
+        goto bail_out;
+      }
+   }
+   Pmsg1(0, _("Wrote 10 blocks of %d bytes.\n"), rec->data_len);
+   weofcmd();
+   if (dev_cap(dev, CAP_TWOEOF)) {
+      weofcmd();
+   }
+   if (!rewind_dev(dev)) {
+      Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
+      goto bail_out;
+   } else {
+      Pmsg0(0, "Rewind OK.\n");
+   }
+
+   for (i=1; i<=20; i++) {
+      if (i != 5 && i != 17) {
+        continue;
+      }
+      if (i == 5) {
+         Pmsg0(-1, "Reposition to file:block 0:4\n");
+        if (!reposition_dev(dev, 0, 4)) {
+            Pmsg0(0, "Reposition error.\n");
+           goto bail_out;
+        }
+      } else {
+         Pmsg0(-1, "Reposition to file:block 1:6\n");
+        if (!reposition_dev(dev, 1, 6)) {
+            Pmsg0(0, "Reposition error.\n");
+           goto bail_out;
+        }
+      }
+read_again:
+      if (!read_block_from_dev(jcr, dev, block, NO_BLOCK_NUMBER_CHECK)) {
+        if (dev_state(dev, ST_EOF)) {
+            Pmsg0(-1, _("Got EOF on tape.\n"));
+           goto read_again;
+        }
+         Pmsg1(0, _("Read block failed! ERR=%s\n"), strerror(dev->dev_errno));
+        goto bail_out;
+      }
+      memset(rec->data, 0, rec->data_len);
+      if (!read_record_from_block(block, rec)) {
+         Pmsg1(0, _("Read record failed! ERR=%s\n"), strerror(dev->dev_errno));
+        goto bail_out;
+      }
+      for (j=0; j<len; j++) {
+        if (rec->data[j] != i) {
+            Pmsg3(0, _("Bad data in record. Expected %d, got %d at byte %d. Test failed!\n"),
+              i, rec->data[j], j);
+           goto bail_out;
+        }
+      }
+      Pmsg0(-1, _("Block re-read correctly.\n"));
+   }
+   Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
+   stat = 1;
+
+bail_out:
+   free_block(block);
+   free_record(rec);
+   return stat;
+}
+
+
+
+
 /*
  * This test writes some records, then writes an end of file,
  *   rewinds the tape, moves to the end of the data and attepts
@@ -754,7 +964,6 @@ static int append_test()
    if (dev->file != 4) {
       return -2;
    }
-
    return 1;
 }
 
@@ -964,10 +1173,9 @@ test_again:
    }
 
    Pmsg0(-1, "\n");
-   Pmsg0(0, _("Now forward spacing 4 more files.\n"));
-   if (!fsf_dev(dev, 4)) {
+   Pmsg0(0, _("Now forward spacing 1 more file.\n"));
+   if (!fsf_dev(dev, 1)) {
       Pmsg1(0, "Bad status from fsr. ERR=%s\n", strerror_dev(dev));
-      goto bail_out;
    }
    Pmsg2(-1, _("We should be in file 5. I am at file %d. This is %s\n"), 
       dev->file, dev->file == 5 ? "correct!" : "NOT correct!!!!");
@@ -1002,6 +1210,13 @@ static void testcmd()
 {
    int stat;
 
+   if (!write_read_test()) {
+      return;
+   }
+   if (!position_test()) {
+      return;
+   }
+
    stat = append_test();
    if (stat == 1) {                  /* OK get out */
       goto all_done;
@@ -1023,8 +1238,8 @@ static void testcmd()
            goto all_done;
         }
         if (stat == -1) {
-            Pmsg0(-1, "\n\nThat appears not to have corrected the problem.\n");
-           goto all_done;
+            Pmsg0(-1, "\n\nThat appears *NOT* to have corrected the problem.\n");
+           goto failed;
         }
         /* Wrong count after append */
         if (stat == -2) {
@@ -1043,6 +1258,7 @@ static void testcmd()
         }
 
       }
+failed:
       Pmsg0(-1, "\nAppend test failed.\n\n");
       Pmsg0(-1, "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
             "Unable to correct the problem. You MUST fix this\n"
@@ -1052,8 +1268,11 @@ static void testcmd()
             "Minimum Block Size = nnn\n"
             "Maximum Block Size = nnn\n\n"
             "in your Storage daemon's Device definition.\n"
-            "nnn must match your tape driver's block size.\n"
-            "This, however, is not really an ideal solution.\n");
+            "nnn must match your tape driver's block size, which\n"
+            "can be determined by reading your tape manufacturers\n"
+            "information, and the information on your kernel dirver.\n"
+            "Fixed block sizes, however, are not normally an ideal solution.\n");
+       return;
    }
 
 all_done:
index 5ef4ae83accec9e9a7ffe5392038107a3463ca35..8be58acc9451a832c66a32b43949917715c265e3 100644 (file)
@@ -432,7 +432,7 @@ eod_dev(DEVICE *dev)
 
    if (dev_cap(dev, CAP_FASTFSF) && !dev_cap(dev, CAP_EOM)) {
       struct mtget mt_stat;
-      Dmsg0(200,"PAPED using FAST FSF for EOM\n");
+      Dmsg0(000,"Using FAST FSF for EOM\n");
       if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) == 0 && mt_stat.mt_fileno <= 0) {
        if (!rewind_dev(dev)) {
          return 0;
@@ -450,11 +450,11 @@ eod_dev(DEVICE *dev)
    }
 
    if (dev_cap(dev, CAP_EOM)) {
-      Dmsg0(200,"PAPED using EOM for EOM\n");
+      Dmsg0(000,"Using EOM for EOM\n");
       mt_com.mt_op = MTEOM;
       mt_com.mt_count = 1;
    }
-   if(dev_cap(dev, CAP_FASTFSF) || dev_cap(dev, CAP_EOM)) {
+   if (dev_cap(dev, CAP_FASTFSF) || dev_cap(dev, CAP_EOM)) {
       if ((stat=ioctl(dev->fd, MTIOCTOP, (char *)&mt_com)) < 0) {
          Dmsg1(50, "ioctl error: %s\n", strerror(dev->dev_errno));
         clrerror_dev(dev, mt_com.mt_op);
@@ -470,7 +470,7 @@ eod_dev(DEVICE *dev)
            dev->dev_name, strerror(dev->dev_errno));
         return 0;
       }
-      Dmsg2(200, "EOD file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno);
+      Dmsg2(000, "EOD file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno);
       dev->file = mt_stat.mt_fileno;
 
    /*