]> git.sur5r.net Git - bacula/bacula/commitdiff
Update tape tests for hardware certification
authorKern Sibbald <kern@maous.(none)>
Tue, 1 Sep 2009 16:46:00 +0000 (18:46 +0200)
committerKern Sibbald <kern@maous.(none)>
Tue, 1 Sep 2009 16:46:00 +0000 (18:46 +0200)
bacula/src/stored/btape.c
bacula/technotes
regress/tests/btape-test-tape

index 61c14e5aafa4e87a0350308fde4ece91afc2938c..66f1f846b1dec4545e52e002cbf6123004e04665 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -74,6 +74,7 @@ static uint32_t btape_state_level = 2;
 DEVICE *dev = NULL;
 DCR *dcr;
 DEVRES *device = NULL;
 DEVICE *dev = NULL;
 DCR *dcr;
 DEVRES *device = NULL;
+int exit_code = 0;
 
 
 /* Forward referenced subroutines */
 
 
 /* Forward referenced subroutines */
@@ -305,15 +306,14 @@ int main(int margc, char *margv[])
    }
    dcr = jcr->dcr;
    if (!open_the_device()) {
    }
    dcr = jcr->dcr;
    if (!open_the_device()) {
-      goto terminate;
+      exit(1);
    }
 
    Dmsg0(200, "Do tape commands\n");
    do_tape_cmds();
 
 terminate:
    }
 
    Dmsg0(200, "Do tape commands\n");
    do_tape_cmds();
 
 terminate:
-   terminate_btape(0);
-   return 0;
+   terminate_btape(exit_code);
 }
 
 static void terminate_btape(int stat)
 }
 
 static void terminate_btape(int stat)
@@ -685,16 +685,16 @@ static void rectestcmd()
  *   it to make sure it is valid.  Bacula can skip this validation
  *   if you set "Backward space record = no"
  */
  *   it to make sure it is valid.  Bacula can skip this validation
  *   if you set "Backward space record = no"
  */
-static int re_read_block_test()
+static bool re_read_block_test()
 {
    DEV_BLOCK *block = dcr->block;
    DEV_RECORD *rec;
 {
    DEV_BLOCK *block = dcr->block;
    DEV_RECORD *rec;
-   int stat = 0;
+   bool rc = false;
    int len;
 
    if (!(dev->capabilities & CAP_BSR)) {
       Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
    int len;
 
    if (!(dev->capabilities & CAP_BSR)) {
       Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
-      return 0;
+      return true;
    }
 
    Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
    }
 
    Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
@@ -781,11 +781,11 @@ static int re_read_block_test()
    Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
    Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
 
    Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
    Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
 
-   stat = 1;
+   rc = true;
 
 bail_out:
    free_record(rec);
 
 bail_out:
    free_record(rec);
-   if (stat == 0) {
+   if (!rc) {
       Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
                  "this function to verify the last block written to the\n"
                  "tape. Bacula will skip the last block verification\n"
       Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
                  "this function to verify the last block written to the\n"
                  "tape. Bacula will skip the last block verification\n"
@@ -793,38 +793,38 @@ bail_out:
                   "Backward Space Record = No\n\n"
                   "to your Storage daemon's Device resource definition.\n"));
    }
                   "Backward Space Record = No\n\n"
                   "to your Storage daemon's Device resource definition.\n"));
    }
-   return stat;
+   return rc;
 }
 
 }
 
+const int num_recs = 10000;
 
 
-/*
- * 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()
+static bool write_two_files()
 {
    DEV_BLOCK *block;
    DEV_RECORD *rec;
 {
    DEV_BLOCK *block;
    DEV_RECORD *rec;
-   int stat = 0;
    int len, i, j;
    int *p;
    int len, i, j;
    int *p;
+   bool rc = false;       /* bad return code */
 
 
-   Pmsg0(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
-      "I'm going to write 1000 records and an EOF\n"
-      "then write 1000 records and an EOF, then rewind,\n"
+   Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
+      "I'm going to write %d records and an EOF\n"
+      "then write %d records and an EOF, then rewind,\n"
       "and re-read the data to verify that it is correct.\n\n"
       "and re-read the data to verify that it is correct.\n\n"
-      "This is an *essential* feature ...\n\n"));
+      "This is an *essential* feature ...\n\n"), num_recs, num_recs);
+
    block = dcr->block;
    block = dcr->block;
+   empty_block(block);
    rec = new_record();
    rec = new_record();
+   rec->data = check_pool_memory_size(rec->data, block->buf_len);
+   rec->data_len = block->buf_len-100;
+   len = rec->data_len/sizeof(i);
+
    if (!dev->rewind(dcr)) {
       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
    if (!dev->rewind(dcr)) {
       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    }
-   rec->data = check_pool_memory_size(rec->data, block->buf_len);
-   rec->data_len = block->buf_len-100;
-   len = rec->data_len/sizeof(i);
-   for (i=1; i<=1000; i++) {
+
+   for (i=1; i<=num_recs; i++) {
       p = (int *)rec->data;
       for (j=0; j<len; j++) {
          *p++ = i;
       p = (int *)rec->data;
       for (j=0; j<len; j++) {
          *p++ = i;
@@ -838,9 +838,9 @@ static int write_read_test()
          goto bail_out;
       }
    }
          goto bail_out;
       }
    }
-   Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
+   Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
    weofcmd();
    weofcmd();
-   for (i=1001; i<=2000; i++) {
+   for (i=num_recs+1; i<=2*num_recs; i++) {
       p = (int *)rec->data;
       for (j=0; j<len; j++) {
          *p++ = i;
       p = (int *)rec->data;
       for (j=0; j<len; j++) {
          *p++ = i;
@@ -854,24 +854,63 @@ static int write_read_test()
          goto bail_out;
       }
    }
          goto bail_out;
       }
    }
-   Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
+   Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
    weofcmd();
    if (dev->has_cap(CAP_TWOEOF)) {
       weofcmd();
    }
    weofcmd();
    if (dev->has_cap(CAP_TWOEOF)) {
       weofcmd();
    }
+   rc = true;
+
+bail_out:
+   free_record(rec);
+   if (!rc) {
+      exit_code = 1;
+   }
+   return rc;
+
+}
+
+/*
+ * 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 bool write_read_test()
+{
+   DEV_BLOCK *block;
+   DEV_RECORD *rec;
+   bool rc = false;
+   int len, i, j;
+   int *p;
+
+   rec = new_record();
+
+   if (!write_two_files()) {
+      goto bail_out;
+   }
+
+   block = dcr->block;
+   empty_block(block);
+
    if (!dev->rewind(dcr)) {
       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    } else {
       Pmsg0(0, _("Rewind OK.\n"));
    }
    if (!dev->rewind(dcr)) {
       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    } else {
       Pmsg0(0, _("Rewind OK.\n"));
    }
-   for (i=1; i<=2000; i++) {
+
+   rec->data = check_pool_memory_size(rec->data, block->buf_len);
+   rec->data_len = block->buf_len-100;
+   len = rec->data_len/sizeof(i);
+
+   /* Now read it back */
+   for (i=1; i<=2*num_recs; i++) {
 read_again:
       if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
          berrno be;
          if (dev_state(dev, ST_EOF)) {
             Pmsg0(-1, _("Got EOF on tape.\n"));
 read_again:
       if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
          berrno be;
          if (dev_state(dev, ST_EOF)) {
             Pmsg0(-1, _("Got EOF on tape.\n"));
-            if (i == 1001) {
+            if (i == num_recs+1) {
                goto read_again;
             }
          }
                goto read_again;
             }
          }
@@ -893,16 +932,19 @@ read_again:
          }
          p++;
       }
          }
          p++;
       }
-      if (i == 1000 || i == 2000) {
-         Pmsg0(-1, _("1000 blocks re-read correctly.\n"));
+      if (i == num_recs || i == 2*num_recs) {
+         Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
       }
    }
    Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
       }
    }
    Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
-   stat = 1;
+   rc = true;
 
 bail_out:
    free_record(rec);
 
 bail_out:
    free_record(rec);
-   return stat;
+   if (!rc) {
+      exit_code = 1;   
+   }
+   return rc;
 }
 
 /*
 }
 
 /*
@@ -910,67 +952,26 @@ bail_out:
  *   several files. It then rewinds the tape and attepts
  *   to read these blocks back checking the data.
  */
  *   several files. It then rewinds the tape and attepts
  *   to read these blocks back checking the data.
  */
-static int position_test()
+static bool position_test()
 {
    DEV_BLOCK *block = dcr->block;
    DEV_RECORD *rec;
 {
    DEV_BLOCK *block = dcr->block;
    DEV_RECORD *rec;
-   int stat = 0;
-   int len, i, j;
-   bool ok = true;
+   bool rc = false;
+   int len, j;
+   bool more = true;
    int recno = 0;
    int file = 0, blk = 0;
    int *p;
    bool got_eof = false;
 
    int recno = 0;
    int file = 0, blk = 0;
    int *p;
    bool got_eof = false;
 
-   Pmsg0(-1, _("\n=== Write, rewind, and position test ===\n\n"
-      "I'm going to write 1000 records and an EOF\n"
-      "then write 1000 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"));
+   Pmsg0(0, _("Block position test\n"));
+   block = dcr->block;
    empty_block(block);
    rec = new_record();
    empty_block(block);
    rec = new_record();
-   if (!dev->rewind(dcr)) {
-      Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
-      goto bail_out;
-   }
    rec->data = check_pool_memory_size(rec->data, block->buf_len);
    rec->data_len = block->buf_len-100;
    rec->data = check_pool_memory_size(rec->data, block->buf_len);
    rec->data_len = block->buf_len-100;
-   len = rec->data_len/sizeof(i);
-   for (i=1; i<=1000; i++) {
-      p = (int *)rec->data;
-      for (j=0; j<len; j++) {
-         *p++ = i;
-      }
-      if (!write_record_to_block(block, rec)) {
-         Pmsg0(0, _("Error writing record to block.\n"));
-         goto bail_out;
-      }
-      if (!write_block_to_dev(dcr)) {
-         Pmsg0(0, _("Error writing block to device.\n"));
-         goto bail_out;
-      }
-   }
-   Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
-   weofcmd();
-   for (i=1001; i<=2000; i++) {
-      p = (int *)rec->data;
-      for (j=0; j<len; j++) {
-         *p++ = i;
-      }
-      if (!write_record_to_block(block, rec)) {
-         Pmsg0(0, _("Error writing record to block.\n"));
-         goto bail_out;
-      }
-      if (!write_block_to_dev(dcr)) {
-         Pmsg0(0, _("Error writing block to device.\n"));
-         goto bail_out;
-      }
-   }
-   Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
-   weofcmd();
-   if (dev->has_cap(CAP_TWOEOF)) {
-      weofcmd();
-   }
+   len = rec->data_len/sizeof(j);
+
    if (!dev->rewind(dcr)) {
       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
    if (!dev->rewind(dcr)) {
       Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
       goto bail_out;
@@ -978,8 +979,11 @@ static int position_test()
       Pmsg0(0, _("Rewind OK.\n"));
    }
 
       Pmsg0(0, _("Rewind OK.\n"));
    }
 
-   while(ok) {
+   while (more) {
       /* Set up next item to read based on where we are */
       /* Set up next item to read based on where we are */
+      /* At each step, recno is what we print for the "block number"
+       *  and file, blk are the real positions to go to.
+       */
       switch (recno) {
       case 0:
          recno = 5;
       switch (recno) {
       case 0:
          recno = 5;
@@ -992,27 +996,27 @@ static int position_test()
          blk = 200;
          break;
       case 201:
          blk = 200;
          break;
       case 201:
-         recno = 1000;
+         recno = num_recs;
          file = 0;
          file = 0;
-         blk = 999;
+         blk = num_recs-1;
          break;
          break;
-      case 1000:
-         recno = 1001;
+      case num_recs:
+         recno = num_recs+1;
          file = 1;
          blk = 0;
          break;
          file = 1;
          blk = 0;
          break;
-      case 1001:
-         recno = 1601;
+      case num_recs+1:
+         recno = num_recs+601;
          file = 1;
          blk = 600;
          break;
          file = 1;
          blk = 600;
          break;
-      case 1601:
-         recno = 2000;
+      case num_recs+601:
+         recno = 2*num_recs;
          file = 1;
          file = 1;
-         blk = 999;
+         blk = num_recs-1;
          break;
          break;
-      case 2000:
-         ok = false;
+      case 2*num_recs:
+         more = false;
          continue;
       }
       Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
          continue;
       }
       Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
@@ -1062,11 +1066,11 @@ read_again:
       Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
    }
    Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
       Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
    }
    Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
-   stat = 1;
+   rc = true;
 
 bail_out:
    free_record(rec);
 
 bail_out:
    free_record(rec);
-   return stat;
+   return rc;
 }
 
 
 }
 
 
@@ -1289,7 +1293,7 @@ static void autochangercmd()
  * This test assumes that the append test has been done,
  *   then it tests the fsf function.
  */
  * This test assumes that the append test has been done,
  *   then it tests the fsf function.
  */
-static int fsf_test()
+static bool fsf_test()
 {
    bool set_off = false;
 
 {
    bool set_off = false;
 
@@ -1371,7 +1375,7 @@ test_again:
       goto bail_out;
    }
    Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
       goto bail_out;
    }
    Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
-   return 1;
+   return true;
 
 bail_out:
    Pmsg0(-1, _("\nThe forward space file test failed.\n"));
 
 bail_out:
    Pmsg0(-1, _("\nThe forward space file test failed.\n"));
@@ -1386,7 +1390,7 @@ bail_out:
             "Some systems, e.g. OpenBSD, require you to set\n"
             "   Use MTIOCGET= no\n"
             "in your device resource. Use with caution.\n"));
             "Some systems, e.g. OpenBSD, require you to set\n"
             "   Use MTIOCGET= no\n"
             "in your device resource. Use with caution.\n"));
-   return -2;
+   return false;
 }
 
 
 }
 
 
@@ -1402,9 +1406,11 @@ static void testcmd()
    int stat;
 
    if (!write_read_test()) {
    int stat;
 
    if (!write_read_test()) {
+      exit_code = 1;
       return;
    }
    if (!position_test()) {
       return;
    }
    if (!position_test()) {
+      exit_code = 1;
       return;
    }
 
       return;
    }
 
@@ -1467,6 +1473,7 @@ failed:
             "Some systems, e.g. OpenBSD, require you to set\n"
             "   Use MTIOCGET= no\n"
             "in your device resource. Use with caution.\n"));
             "Some systems, e.g. OpenBSD, require you to set\n"
             "   Use MTIOCGET= no\n"
             "in your device resource. Use with caution.\n"));
+       exit_code = 1;
        return;
    }
 
        return;
    }
 
@@ -1490,10 +1497,14 @@ all_done:
         "the tape.\n\n"));
 
    if (stat == 1) {
         "the tape.\n\n"));
 
    if (stat == 1) {
-      re_read_block_test();
+      if (!re_read_block_test()) {
+         exit_code = 1;
+      }
    }
 
    }
 
-   fsf_test();                        /* do fast forward space file test */
+   if (!fsf_test()) {                  /* do fast forward space file test */
+      exit_code = 1;
+   }
 
    autochanger_test();                /* do autochanger test */
 
 
    autochanger_test();                /* do autochanger test */
 
index 25ff578a775a48b2ece48aa76056c0177099a891..58a64f8a78d6eec6f7dd9f4fb6b9e4b97acaf28c 100644 (file)
@@ -3,6 +3,9 @@
 General:
 
 01Sep09
 General:
 
 01Sep09
+kes  Update tape tests for hardware certification
+     Add script for doing btape test command 
+     Make btape return error status if test command fails 
 kes  Eliminate xattr.c compiler warning
 31Aug09
 ebl  Prohibit copy and assignment in db_list_ctx.
 kes  Eliminate xattr.c compiler warning
 31Aug09
 ebl  Prohibit copy and assignment in db_list_ctx.
index 860f013d353f0ef95e2637b7541f87a8f917be2a..9faa43b80c5dfcb4dd0ad4987898d2e0dc3a4b0f 100755 (executable)
@@ -26,6 +26,33 @@ quit
 END_OF_DATA
 fi
 
 END_OF_DATA
 fi
 
+if [ $? != 0 ] ; then
+   echo " "
+   echo " "
+   echo "  !!!!! btape fill test failed!!! !!!!! "
+   echo "  !!!!! btape fill test failed!!! !!!!! " >>test.out
+   echo " "
+   exit 1
+fi
+
+#
+#  Increase block size to 262144
+#
+cp ${cwd}/bin/bacula-sd.conf ${cwd}/tmp/1
+sed -e 's%64512%262144%' ${cwd}/tmp/1 >${cwd}/bin/bacula-sd.conf
+
+if test "$debug" -eq 1 ; then
+  $bin/btape -c bin/bacula-sd.conf tape <<END_OF_DATA
+test
+quit
+END_OF_DATA
+else
+  $bin/btape -c bin/bacula-sd.conf tape <<END_OF_DATA >${cwd}/tmp/log1.out 2>&1
+test
+quit
+END_OF_DATA
+fi
+
 if [ $? != 0 ] ; then
    echo " "
    echo " "
 if [ $? != 0 ] ; then
    echo " "
    echo " "