]> git.sur5r.net Git - bacula/bacula/commitdiff
Adapt to FreeBSD tape drives
authorKern Sibbald <kern@sibbald.com>
Thu, 27 Mar 2003 15:15:41 +0000 (15:15 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 27 Mar 2003 15:15:41 +0000 (15:15 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@399 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/stored_conf.c
bacula/src/version.h

index a045aab6d7a2e77d6e122a40d7c60e07cc082516..ecb16f2506375385f5dad5fd561fd5214b94d015 100644 (file)
@@ -57,8 +57,10 @@ static void scancmd();
 static void rewindcmd();
 static void clearcmd();
 static void wrcmd();
+static void rrcmd();
 static void eodcmd();
 static void fillcmd();
+static void statcmd();
 static void unfillcmd();
 static int flush_block(DEV_BLOCK *block, int dump);
 static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
@@ -499,6 +501,14 @@ static void capcmd()
    printf("%sSHORT ", dev->state & ST_SHORT ? "" : "!");
    printf("\n");
 
+   printf(_("Device parameters:\n"));
+   printf("Device name: %s\n", dev->dev_name);
+   printf("File=%u block=%u\n", dev->file, dev->block_num);
+   printf("Min block=%u Max block=%u\n", dev->min_block_size, dev->max_block_size);
+
+   printf("Status:\n");
+   statcmd();
+
 }
 
 /*
@@ -607,7 +617,7 @@ static int re_read_block_test()
       Pmsg0(0, _("Error writing block to device.\n")); 
       goto bail_out;
    } else {
-      Pmsg1(0, _("Wrote fourth record of %d bytes.\n"), rec->data_len);
+      Pmsg1(0, _("Wrote third record of %d bytes.\n"), rec->data_len);
    }
    weofcmd();
    weofcmd();
@@ -687,13 +697,7 @@ static int append_test()
       dev->file, dev->file == 3 ? "correct!" : "NOT correct!!!!");
 
    if (dev->file != 3) {
-      Pmsg0(-1, _("\nYou MUST correct this problem. Try adding:\n\n"
-            "Hardware End of Medium = No\n\n"
-            "to your Storage daemon's Device resource definition.\n"
-            "Then re-run this test. If it still fails, there is a\n"
-            "a problem with your tape driver that must be corrected\n"
-            "before continuing.\n"));
-      return 0;
+      return -1;
    }
 
    Pmsg0(-1, _("\nNow the important part, I am going to attempt to append to the tape.\n\n"));
@@ -703,8 +707,77 @@ static int append_test()
    Pmsg0(-1, _("Done appending, there should be no I/O errors\n\n"));
    Pmsg0(-1, "Doing Bacula scan of blocks:\n");
    scan_blocks();
-   Pmsg0(-1, _("End scanning the tape.\n\n"
-        "The above scan should have output identical to what follows:\n\n"
+   Pmsg0(-1, _("End scanning the tape.\n"));
+   Pmsg2(-1, _("We should be in file 4. I am at file %d. This is %s\n"), 
+      dev->file, dev->file == 4 ? "correct!" : "NOT correct!!!!");
+
+   if (dev->file != 4) {
+      return -2;
+   }
+
+   return 1;
+}
+
+/* 
+ * This is a general test of Bacula's functions
+ *   needed to read and write the tape.
+ */
+static void testcmd()
+{
+   int stat;
+   re_read_block_test();
+
+   stat = append_test();
+   if (stat == 1) {                  /* OK get out */
+      goto all_done;
+   }
+   if (stat == -1) {                 /* first test failed */
+      if (dev_cap(dev, CAP_EOM)) {
+         Pmsg0(-1, "\nAppend test failed. Attempting again.\n"
+                   "Setting \"Hardware End of Medium = no\" and retrying append test.\n\n");
+        dev->capabilities &= ~CAP_EOM; /* turn off eom */
+        stat = append_test();
+        if (stat == 1) {
+            Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
+                     "    Hardware End of Medium = No\n\n"
+                     "to your Device resource in the Storage conf file.\n");
+           goto all_done;
+        }
+        if (stat == -1) {
+            Pmsg0(-1, "\n\nThat appears not to have corrected the problem.\n");
+           goto all_done;
+        }
+        /* Wrong count after append */
+        if (stat == -2) {
+            Pmsg0(-1, "\n\nIt looks like the append failed. Attempting again.\n"
+                     "Setting \"BSF at EOM = yes\" and retrying append test.\n");
+           dev->capabilities |= CAP_BSFATEOM; /* backspace on eom */
+           stat = append_test();
+           if (stat == 1) {
+               Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
+                     "    Hardware End of Medium = No\n"
+                     "    BSR at EOM = yes\n\n"
+                     "to your Device resource in the Storage conf file.\n");
+              goto all_done;
+           }
+        }
+
+         Pmsg0(-1, "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
+               "Unable to correct the problem. You MUST fix this\n"
+                "problem before Bacula can use your tape drive correctly\n");
+         Pmsg0(-1, "\nPerhaps running Bacula in fixed block mode will work.\n"
+               "Do so by setting:\n\n"
+               "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");
+      }
+   }
+
+all_done:
+   Pmsg0(-1, _("\nThe above Bacula scan should have output identical to what follows.\n"
+        "Please double check it ...\n"
         "=== Sample correct output ===\n"
         "1 block of 64448 bytes in file 1\n"
         "End of File mark.\n"
@@ -720,30 +793,10 @@ static int append_test()
    Pmsg0(-1, _("If the above scan output is not identical to the\n"
                "sample output, you MUST correct the problem\n"
                "or Bacula will not be able to write multiple Jobs to \n"
-               "the tape.\n\n"
-               "If the output is incorrect, you might\n"
-               "be able to run in fixed block mode by setting:\n\n"
-               "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"));
+               "the tape.\n\n"));
 
    Pmsg0(-1, _("\n=== End Append files test ===\n"));
-   return 1;
-}
-
-/* 
- * This is a general test of Bacula's functions
- *   needed to read and write the tape.
- */
-static void testcmd()
-{
-   re_read_block_test();
-
-   if (!append_test()) {
-      return;
-   }
+   
 }
 
 /* Forward space a file */
@@ -808,6 +861,32 @@ bail_out:
    sm_check(__FILE__, __LINE__, False);
 }
 
+/* 
+ * Read a record from the tape
+ */
+static void rrcmd()
+{
+   char *buf;
+   int stat, len;
+
+   if (!get_cmd("Enter length to read: ")) {
+      return;
+   }
+   len = atoi(cmd);
+   if (len < 0 || len > 1000000) {
+      Pmsg0(0, _("Bad length entered, using default of 1024 bytes.\n"));
+      len = 1024;
+   }
+   buf = (char *)malloc(len);
+   stat = read(dev->fd, buf, len);
+   if (stat > 0 && stat <= len) {
+      errno = 0;
+   }
+   Pmsg3(0, _("Read of %d bytes gives stat=%d. ERR=%s\n"),
+      len, stat, strerror(errno));
+   free(buf);
+}
+
 
 /*
  * Scan tape by reading block by block. Report what is
@@ -1448,7 +1527,8 @@ static struct cmdstruct commands[] = {
  {"status",     statcmd,      "print tape status"},
  {"test",       testcmd,      "General test Bacula tape functions"},
  {"weof",       weofcmd,      "write an EOF on the tape"},
- {"wr",         wrcmd,        "write a single record of 2048 bytes"}, 
+ {"wr",         wrcmd,        "write a single Bacula block"}, 
+ {"rr",         rrcmd,        "read a single record"},
             };
 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
 
index ac112d5e7cc18afc9298f7eec50740ab4a05b593..11a9cd3fd3b8c512b71c754598a57c065b294bb7 100644 (file)
@@ -412,7 +412,7 @@ eod_dev(DEVICE *dev)
       }
       return 0;
    }
-   if (dev->capabilities & CAP_EOM) {
+   if (dev_cap(dev, CAP_EOM)) {
       mt_com.mt_op = MTEOM;
       mt_com.mt_count = 1;
       if ((stat=ioctl(dev->fd, MTIOCTOP, (char *)&mt_com)) < 0) {
@@ -447,9 +447,20 @@ eod_dev(DEVICE *dev)
         }
       }
    }
-   update_pos_dev(dev);                     /* update position */
+   /*
+    * Some drivers leave us after second EOF when doing
+    * MTEOM, so we must backup so that appending overwrites
+    * the second EOF.
+    */
+   if (dev_cap(dev, CAP_BSFATEOM)) {
+      stat =  (bsf_dev(dev, 1) == 0);
+      dev->file++;                   /* keep same file */
+   } else {
+      update_pos_dev(dev);                  /* update position */
+      stat = 1;
+   }
    Dmsg1(200, "EOD dev->file=%d\n", dev->file);
-   return 1;
+   return stat;
 }
 
 /*
@@ -663,7 +674,6 @@ fsf_dev(DEVICE *dev, int num)
 { 
    struct mtop mt_com;
    int stat = 0;
-   char rbuf[1024];
 
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
@@ -680,26 +690,37 @@ fsf_dev(DEVICE *dev, int num)
       Mmsg1(&dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
       return 0;
    }
-   if (dev->state & ST_EOF)
+   if (dev->state & ST_EOF) {
       Dmsg0(200, "ST_EOF set on entry to FSF\n");
-   if (dev->state & ST_EOT)
+   }
+   if (dev->state & ST_EOT) {
       Dmsg0(200, "ST_EOT set on entry to FSF\n");
+   }
       
    Dmsg0(29, "fsf_dev\n");
    dev->block_num = 0;
-   if (dev->capabilities & CAP_FSF) {
+   if (dev_cap(dev, CAP_FSF)) {
+      POOLMEM *rbuf;
+      int rbuf_len;
       Dmsg0(200, "FSF has cap_fsf\n");
+      if (dev->max_block_size == 0) {
+        rbuf_len = DEFAULT_BLOCK_SIZE;
+      } else {
+        rbuf_len = dev->max_block_size;
+      }
+      rbuf = get_memory(rbuf_len);
       mt_com.mt_op = MTFSF;
       mt_com.mt_count = 1;
       while (num-- && !(dev->state & ST_EOT)) {
-         Dmsg0(200, "Doing read for fsf\n");
-        if ((stat = read(dev->fd, rbuf, sizeof(rbuf))) < 0) {
+         Dmsg0(200, "Doing read before fsf\n");
+        if ((stat = read(dev->fd, (char *)rbuf, rbuf_len)) < 0) {
            if (errno == ENOMEM) {     /* tape record exceeds buf len */
-              stat = sizeof(rbuf);   /* This is OK */
+              stat = rbuf_len;        /* This is OK */
            } else {
               dev->state |= ST_EOT;
               clrerror_dev(dev, -1);
-               Dmsg1(200, "Set ST_EOT read error %d\n", dev->dev_errno);
+               Dmsg2(200, "Set ST_EOT read errno=%d. ERR=%s\n", dev->dev_errno,
+                 strerror(dev->dev_errno));
                Mmsg2(&dev->errmsg, _("read error on %s. ERR=%s.\n"),
                  dev->dev_name, strerror(dev->dev_errno));
                Dmsg1(200, "%s", dev->errmsg);
@@ -740,6 +761,7 @@ fsf_dev(DEVICE *dev, int num)
            dev->file_addr = 0;
         }   
       }
+      free_memory(rbuf);
    
    /*
     * No FSF, so use FSR to simulate it
index d2fd63c935af445667a13f37f42b4d0a3f94761d..2d558d93b73b05fbba353950ef316376067f6f8b 100644 (file)
@@ -81,6 +81,7 @@
 #define CAP_AUTOCHANGER    0x1000     /* AutoChanger */
 #define CAP_OFFLINEUNMOUNT 0x2000     /* Offline before unmount */
 #define CAP_STREAM         0x4000     /* Stream device */
+#define CAP_BSFATEOM       0x8000     /* Backspace file at EOM */
 
 /* Test state */
 #define dev_state(dev, state) ((dev)->state & (state))
index 864b0534ad6bb20d33cf8e765d5aacf0f674fefd..4fdb2870204ebc19ef3d345477d92dfe81da5db4 100644 (file)
@@ -86,6 +86,7 @@ static struct res_items dev_items[] = {
    {"hardwareendofmedium",   store_yesno,  ITEM(res_dev.cap_bits), CAP_EOM,  ITEM_DEFAULT, 1},
    {"backwardspacerecord",   store_yesno,  ITEM(res_dev.cap_bits), CAP_BSR,  ITEM_DEFAULT, 1},
    {"backwardspacefile",     store_yesno,  ITEM(res_dev.cap_bits), CAP_BSF,  ITEM_DEFAULT, 1},
+   {"bsfateom",              store_yesno,  ITEM(res_dev.cap_bits), CAP_BSFATEOM, ITEM_DEFAULT, 0},
    {"forwardspacerecord",    store_yesno,  ITEM(res_dev.cap_bits), CAP_FSR,  ITEM_DEFAULT, 1},
    {"forwardspacefile",      store_yesno,  ITEM(res_dev.cap_bits), CAP_FSF,  ITEM_DEFAULT, 1},
    {"removablemedia",        store_yesno,  ITEM(res_dev.cap_bits), CAP_REM,  ITEM_DEFAULT, 1},
index 3198dc40d2284a7a0eaeaa627eb0377ea0e98b1b..ccad32fa8c4487ea00e3114a7502a80e31c0e18d 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.30"
 #define VSTRING "1"
-#define BDATE   "25 March 2003"
-#define LSMDATE "25Mar03"
+#define BDATE   "27 March 2003"
+#define LSMDATE "27Mar03"
 
 /* Debug flags */
 #define DEBUG 1