]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dev.c
Correct dvd code that breaks tape labeling
[bacula/bacula] / bacula / src / stored / dev.c
index 4dc9352d14538f639ffdc0c2eb3a0f33e0b51e45..2ba6fa455f48a577a46c29c7f47166cfd7898246 100644 (file)
@@ -526,7 +526,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
      
    if (mount_dvd(this, 1)) {
       Dmsg0(99, "DVD device mounted.\n");
-      if ((num_dvd_parts == 0) && (!truncating)) {
+      if (num_dvd_parts == 0 && !truncating) {
          /*
           * If we can mount the device, and we are not truncating the DVD, 
           * we usually want to abort. There is one exception, if there is 
@@ -583,6 +583,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
       omode = OPEN_READ_ONLY;
       make_mounted_dvd_filename(this, archive_name);
    } else {
+      omode = OPEN_READ_WRITE;
       make_spooled_dvd_filename(this, archive_name);
    }
    set_mode(omode);
@@ -599,27 +600,26 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
       dev_errno = EIO; /* Interpreted as no device present by acquire.c:acquire_device_for_read(). */
       Dmsg1(29, "open failed: %s", errmsg);
       
+      /* Previous open failed. See if we can recover */
       if ((omode == OPEN_READ_ONLY || omode == OPEN_READ_WRITE) &&
           (part > num_dvd_parts)) {
-         /* If the last part (on spool), doesn't exists when accessing,
+         /* If the last part (on spool), doesn't exist when accessing,
           * create it. In read/write mode a write will be allowed (higher
           * level software thinks that we are extending a pre-existing
           * media. Reads for READ_ONLY will report immediately an EOF 
           * Sometimes it is better to finish with an EOF than with an error. */
          Dmsg1(29, "Creating last part on spool: %s\n", archive_name.c_str());
+         omode = CREATE_READ_WRITE;
          set_mode(CREATE_READ_WRITE);
          fd = ::open(archive_name.c_str(), mode, 0640);
          set_mode(omode);
       }
-      
-      /* We don't need it. Only the last part is on spool */
-      /*if (omode == OPEN_READ_ONLY) {
-         make_spooled_dvd_filename(this, archive_name);
-         fd = ::open(archive_name.c_str(), mode, 0640);  // try on spool
-      }*/
    }
    Dmsg1(100, "after open fd=%d\n", fd);
    if (fd >= 0) {
+      if (omode == OPEN_READ_WRITE || omode == CREATE_READ_WRITE) {
+         set_append();
+      }
       /* Get size of file */
       if (fstat(fd, &filestat) < 0) {
          berrno be;
@@ -634,22 +634,6 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
          part_size = filestat.st_size;
          dev_errno = 0;
          update_pos_dev(this);                /* update position */
-         
-         /* NB: It seems this code is wrong... part number is incremented in open_next_part, not here */
-         
-         /* Check if just created Volume  part */
-/*
- *         if (omode == OPEN_READ_WRITE && (part == 0 || part_size == 0)) {
- *          part++;
- *          num_dvd_parts = part;
- *          VolCatInfo.VolCatParts = num_dvd_parts;
- *       } else {
- *          if (part == 0) {             // we must have opened the first part
- *             part++;
- *          }
- *       }
- */
-
       }
    }
 }
@@ -667,6 +651,10 @@ bool DEVICE::rewind(DCR *dcr)
    bool first = true;
 
    Dmsg3(400, "rewind res=%d fd=%d %s\n", reserved_device, fd, print_name());
+   state &= ~(ST_EOT|ST_EOF|ST_WEOT);  /* remove EOF/EOT flags */
+   block_num = file = 0;
+   file_size = 0;
+   file_addr = 0;
    if (fd < 0) {
       if (!is_dvd()) { /* In case of major error, the fd is not open on DVD, so we don't want to abort. */
          dev_errno = EBADF;
@@ -676,10 +664,6 @@ bool DEVICE::rewind(DCR *dcr)
       }
       return false;
    }
-   state &= ~(ST_EOT|ST_EOF|ST_WEOT);  /* remove EOF/EOT flags */
-   block_num = file = 0;
-   file_size = 0;
-   file_addr = 0;
    if (is_tape()) {
       mt_com.mt_op = MTREW;
       mt_com.mt_count = 1;
@@ -1796,16 +1780,21 @@ void DEVICE::close()
       struct stat statp;
       int part_save = part;
       POOL_MEM archive_name(PM_FNAME);
+      int status;
 
       part = num_dvd_parts;
-      Dmsg3(100, "Remove empty part in close call make_dvd_filename. part=%d num=%d vol=%s\n", 
-         part, num_dvd_parts, VolCatInfo.VolCatName);
       make_spooled_dvd_filename(this, archive_name);
       /* Check that the part file is empty */
-      if ((stat(archive_name.c_str(), &statp) == 0) && (statp.st_size == 0)) {
+      status = stat(archive_name.c_str(), &statp);
+      if (status == 0 && statp.st_size == 0) {
+         Dmsg3(100, "Unlink empty part in close call make_dvd_filename. part=%d num=%d vol=%s\n", 
+                part, num_dvd_parts, VolCatInfo.VolCatName);
          Dmsg1(100, "unlink(%s)\n", archive_name.c_str());
          unlink(archive_name.c_str());
-      }
+         set_part_spooled(false);        /* no spooled part left */
+      } else if (status < 0) {                         
+         set_part_spooled(false);        /* spool doesn't exit */
+      }       
       part = part_save;               /* restore part number */
    }
    
@@ -1914,7 +1903,9 @@ bool DEVICE::do_mount(int mount, int dotimeout)
    }
    results = get_memory(2000);
    results[0] = 0;
+
    /* If busy retry each second */
+   Dmsg1(20, "do_mount run_prog=%s\n", ocmd.c_str());
    while ((status = run_program_full_output(ocmd.c_str(), 
                        max_open_wait/2, results)) != 0) {
       /* Doesn't work with internationalisation (This is not a problem) */