]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dev.c
kes Fix logic error in handling error return from mtx-changer
[bacula/bacula] / bacula / src / stored / dev.c
index c053980bb33fd0731d734f5e6da3df342497c379..a4dc8477339001af4280534e89e1f5f05008078f 100644 (file)
@@ -432,7 +432,7 @@ void DEVICE::open_file_device(DCR *dcr, int omode)
    pm_strcpy(archive_name, dev_name);
    /*  
     * If this is a virtual autochanger (i.e. changer_res != NULL)
-    *  we simply use the deviced name, assuming it has been
+    *  we simply use the device name, assuming it has been
     *  appropriately setup by the "autochanger".
     */
    if (!device->changer_res) {
@@ -526,8 +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)) {
-#ifdef needed
+      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 
@@ -541,7 +540,6 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
             clear_opened();
             return;
          }
-#endif
          truncated_dvd = true;
       }
    } else {
@@ -584,9 +582,11 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
    if (part <= num_dvd_parts) {
       omode = OPEN_READ_ONLY;
       make_mounted_dvd_filename(this, archive_name);
+      set_part_spooled(false);
    } else {
       omode = OPEN_READ_WRITE;
       make_spooled_dvd_filename(this, archive_name);
+      set_part_spooled(true);
    }
    set_mode(omode);
 
@@ -1780,18 +1780,27 @@ void DEVICE::close()
    /* Remove the last part file if it is empty */
    if (num_dvd_parts > 0) {
       struct stat statp;
-      int part_save = part;
+      uint32_t 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());
-      }
+         if (part_save == part) {
+           set_part_spooled(false);        /* no spooled part left */
+         }
+      } else if (status < 0) {                         
+         if (part_save == part) {
+           set_part_spooled(false);        /* spool doesn't exit */
+         }
+      }       
       part = part_save;               /* restore part number */
    }
    
@@ -1814,6 +1823,30 @@ void DEVICE::close()
    openmode = 0;
 }
 
+/*
+ * This call closes the device, but it is used in DVD handling
+ *  where we close one part and then open the next part. The
+ *  difference between close_part() and close() is that close_part()
+ *  saves the state information of the device (e.g. the Volume lable,
+ *  the Volume Catalog record, ...  This permits opening and closing
+ *  the Volume parts multiple times without losing track of what the    
+ *  main Volume parameters are.
+ */
+void DEVICE::close_part(DCR *dcr)
+{
+   VOLUME_LABEL saveVolHdr;
+   VOLUME_CAT_INFO saveVolCatInfo;     /* Volume Catalog Information */
+
+
+   memcpy(&saveVolHdr, &VolHdr, sizeof(saveVolHdr));
+   memcpy(&saveVolCatInfo, &VolCatInfo, sizeof(saveVolCatInfo));
+   close();                           /* close current part */
+   memcpy(&VolHdr, &saveVolHdr, sizeof(VolHdr));
+   memcpy(&VolCatInfo, &saveVolCatInfo, sizeof(VolCatInfo));
+   memcpy(&dcr->VolCatInfo, &saveVolCatInfo, sizeof(dcr->VolCatInfo));
+}
+
+
 
 
 bool DEVICE::truncate(DCR *dcr) /* We need the DCR for DVD-writing */
@@ -1900,10 +1933,12 @@ 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) */
+      /* Doesn't work with internationalization (This is not a problem) */
       if (fnmatch("*is already mounted on", results, 0) == 0) {
          break;
       }