]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/btape.c
Merge master with SF
[bacula/bacula] / bacula / src / stored / btape.c
index b285c72e39d97d70134ae86cda6ed96b38f3a814..74e117e5898c5d54e8d31c443a5b4eaf300fbbde 100644 (file)
@@ -20,7 +20,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula® is a registered trademark of Kern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 #include "bacula.h"
 #include "stored.h"
 
+#ifdef USE_VTAPE
+#include "vtape.h"
+#endif
+
 /* Dummy functions */
 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
+extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
 
 /* External subroutines */
 extern void free_config_resources();
@@ -98,6 +103,7 @@ static void do_unfill();
 
 
 /* Static variables */
+static CONFIG *config;
 #define CONFIG_FILE "bacula-sd.conf"
 char *configfile = NULL;
 
@@ -265,8 +271,8 @@ int main(int margc, char *margv[])
 
    daemon_start_time = time(NULL);
 
-   parse_config(configfile);
-
+   config = new_config_parser();
+   parse_sd_config(config, configfile, M_ERROR_TERM);
 
    /* See if we can open a device */
    if (margc == 0) {
@@ -317,7 +323,11 @@ static void terminate_btape(int stat)
    if (configfile) {
       free(configfile);
    }
-   free_config_resources();
+   if (config) {
+      config->free_resources();
+      free(config);
+      config = NULL;
+   }
    if (args) {
       free_pool_memory(args);
       args = NULL;
@@ -334,12 +344,12 @@ static void terminate_btape(int stat)
    free_jcr(jcr);
    jcr = NULL;
 
+   free_volume_lists();
+
    if (dev) {
       dev->term();
    }
 
-   free_volume_list();
-
    if (debug_level > 10)
       print_memory_pool_stats();
 
@@ -349,8 +359,9 @@ static void terminate_btape(int stat)
 
    stop_watchdog();
    term_msg();
-   close_memory_pool();               /* free memory in pool */
    term_last_jobs_list();
+   close_memory_pool();               /* free memory in pool */
+   lmgr_cleanup_main();
 
    sm_dump(false);
    exit(stat);
@@ -403,7 +414,6 @@ static void labelcmd()
       }
    }
    dev->rewind(dcr);
-   dev->weof(1);
    write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
    Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
 }
@@ -624,7 +634,7 @@ static void capcmd()
 }
 
 /*
- * Test writting larger and larger records.
+ * Test writing larger and larger records.
  * This is a torture test for records.
  */
 static void rectestcmd()
@@ -633,7 +643,7 @@ static void rectestcmd()
    DEV_RECORD *rec;
    int i, blkno = 0;
 
-   Pmsg0(0, _("Test writting larger and larger records.\n"
+   Pmsg0(0, _("Test writing larger and larger records.\n"
 "This is a torture test for records.\nI am going to write\n"
 "larger and larger records. It will stop when the record size\n"
 "plus the header exceeds the block size (by default about 64K)\n"));
@@ -786,35 +796,35 @@ bail_out:
    return stat;
 }
 
+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;
-   int stat = 0;
    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"
-      "This is an *essential* feature ...\n\n"));
+      "This is an *essential* feature ...\n\n"), num_recs, num_recs);
+
    block = dcr->block;
+   empty_block(block);
    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;
    }
-   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;
@@ -828,9 +838,9 @@ static int write_read_test()
          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();
-   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;
@@ -844,18 +854,54 @@ static int write_read_test()
          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();
    }
+   rc = true;
+
+bail_out:
+   free_record(rec);
+   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 int write_read_test()
+{
+   DEV_BLOCK *block;
+   DEV_RECORD *rec;
+   int stat = 0;
+   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"));
    }
-   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;
@@ -883,8 +929,8 @@ read_again:
          }
          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"));
@@ -905,62 +951,20 @@ static int position_test()
    DEV_BLOCK *block = dcr->block;
    DEV_RECORD *rec;
    int stat = 0;
-   int len, i, j;
+   int len, j;
    bool ok = true;
    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"));
+   block = dcr->block;
    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;
-   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;
@@ -2014,7 +2018,7 @@ static void fillcmd()
          set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
       if (!write_session_label(dcr, EOS_LABEL)) {
-         Pmsg1(000, _("Error writting end session label. ERR=%s\n"), dev->bstrerror());
+         Pmsg1(000, _("Error writing end session label. ERR=%s\n"), dev->bstrerror());
          ok = false;
       }
       /* Write out final block of this session */
@@ -2500,11 +2504,7 @@ static void rawfill_cmd()
    Pmsg1(0, _("Begin writing raw blocks of %u bytes.\n"), block->buf_len);
    for ( ;; ) {
       *p = block_num;
-      if (dev->is_tape()) {
-         stat = tape_write(dev->fd(), block->buf, block->buf_len);
-      } else {
-         stat = write(dev->fd(), block->buf, block->buf_len);
-      }
+      stat = dev->d_write(dev->fd(), block->buf, block->buf_len);
       if (stat == (int)block->buf_len) {
          if ((block_num++ % 100) == 0) {
             printf("+");
@@ -2577,7 +2577,7 @@ do_tape_cmds()
             found = true;
             break;
          }
-      if (!found) {
+      if (*cmd && !found) {
          Pmsg1(0, _("\"%s\" is an invalid command\n"), cmd);
       }
    }
@@ -2622,7 +2622,8 @@ get_cmd(const char *prompt)
 {
    int i = 0;
    int ch;
-   fprintf(stdout, prompt);
+
+   fprintf(stdout, "%s", prompt);
 
    /* We really should turn off echoing and pretty this
     * up a bit.
@@ -2633,8 +2634,9 @@ get_cmd(const char *prompt)
          strip_trailing_junk(cmd);
          return 1;
       } else if (ch == 4 || ch == 0xd3 || ch == 0x8) {
-         if (i > 0)
+         if (i > 0) {
             cmd[--i] = 0;
+         }
          continue;
       }
 
@@ -2662,7 +2664,7 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw  writing)
    return 1;
 }
 
-bool dir_create_jobmedia_record(DCR *dcr)
+bool dir_create_jobmedia_record(DCR *dcr, bool zero)
 {
    dcr->WroteVol = false;
    return 1;
@@ -2675,7 +2677,7 @@ bool dir_find_next_appendable_volume(DCR *dcr)
    return dcr->VolumeName[0] != 0;
 }
 
-bool dir_ask_sysop_to_mount_volume(DCR *dcr)
+bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /* mode */)
 {
    DEVICE *dev = dcr->dev;
    Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");