]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Modify disk changer to simulate some of the error conditions
authorKern Sibbald <kern@sibbald.com>
Mon, 11 Sep 2006 21:11:03 +0000 (21:11 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 11 Sep 2006 21:11:03 +0000 (21:11 +0000)
     of mtx-changer.
kes  Make sure the close() call in the SD tools is just before the
     getchar() call.
kes  Implement dir_get_volume_info() in bls using the patch from
     Richard Mortimer but call find_num_dvd_parts().
kes  Implement find_num_dvd_parts() that mounts and scans a DVD
     and counts the parts.
kes  Move the omode code in open_dvd() up so that the cannot
     write on blank disk can check can be bypassed for read mode.
     Not yet implemented.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3457 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/scripts/disk-changer.in
bacula/src/stored/bextract.c
bacula/src/stored/bls.c
bacula/src/stored/bscan.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dvd.c
bacula/src/stored/protos.h
bacula/technotes-1.39

index 94c5682f4dc23239df8e253e7a3d97e73e7bfa2c..85de7bf1de9e15e9bf1c8da74b56f4fc0f75c3ed 100644 (file)
@@ -164,23 +164,39 @@ case $cmd in
    unload)
       debug "Doing disk -f $ctl unload $slot $device $drive"
       get_dir
-      echo "0" >$dir/loaded${drive}
-      unlink $device 2>/dev/null >/dev/null
-      rm -f $device
+      ld=`cat $dir/loaded${drive}`
+      if [ $slot -eq $ld ]; then
+        echo "0" >$dir/loaded${drive}
+        unlink $device 2>/dev/null >/dev/null
+        rm -f $device
+      else
+        echo "Storage Element $slot is Already Full"
+        exit 1
+      fi
       ;;
 
    load)
       debug "Doing disk $ctl load $slot $device $drive"
       get_dir
-      echo "0" >$dir/loaded${drive}
-      unlink $device 2>/dev/null >/dev/null
-      rm -f $device
-      ln -s $dir/slot${slot} $device
-      rtn=$?
-      if [ $rtn -eq 0 ]; then
-        echo $slot >$dir/loaded${drive}
+      if [ -f $dir/loaded${drive} ]; then
+        ld=`cat $dir/loaded${drive}`
+      else
+        ld=0
+      fi
+      if [ $ld -eq 0 ]; then
+        echo "0" >$dir/loaded${drive}
+        unlink $device 2>/dev/null >/dev/null
+        rm -f $device
+        ln -s $dir/slot${slot} $device
+        rtn=$?
+        if [ $rtn -eq 0 ]; then
+           echo $slot >$dir/loaded${drive}
+        fi
+        exit $rtn
+      else
+        echo "Drive ${drive} Full (Storage element ${ld} loaded)"
+        exit 1
       fi
-      exit $rtn
       ;;
 
    list) 
index 8251f90e61f73f32f48a79a3374abbda7d4a0aac..e64fe471362946cf814f15d7ff78286580fae83c 100644 (file)
@@ -472,6 +472,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
    DEVICE *dev = dcr->dev;
    fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
       dcr->VolumeName, dev->print_name());
+   dev->close();
    getchar();
    return true;
 }
index 5d671f232d0eabe8e4ad24e6fef85508964ba636..bdc20604dc7fd9d125f7500a173f86eb8f6e9e72 100644 (file)
@@ -421,7 +421,6 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess
 
 
 /* Dummies to replace askdir.c */
-bool    dir_get_volume_info(DCR *dcr, enum get_vol_info_rw  writing) { return 1;}
 bool    dir_find_next_appendable_volume(DCR *dcr) { return 1;}
 bool    dir_update_volume_info(DCR *dcr, bool relabel) { return 1; }
 bool    dir_create_jobmedia_record(DCR *dcr) { return 1; }
@@ -436,6 +435,16 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
    DEVICE *dev = dcr->dev;
    fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
       dcr->VolumeName, dev->print_name());
+   dev->close();
    getchar();
    return true;
 }
+
+bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw  writing)
+{
+   Dmsg0(100, "Fake dir_get_volume_info\n");
+   bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
+   dcr->VolCatInfo.VolCatParts = find_num_dvd_parts(dcr);
+   Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatParts);
+   return 1;
+}
index 735ddc11c9d7768d396ec679976973afa2683bc9..7b4061554a04d8bd728e6a0a1f4c7fbe158da6ab 100644 (file)
@@ -1263,9 +1263,9 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
    DEVICE *dev = dcr->dev;
    Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
    /* Close device so user can use autochanger if desired */
-   dev->close();
    fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
          dcr->VolumeName, dev->print_name());
+   dev->close();
    getchar();
    return true;
 }
index f3c4b4d55ee7a4882a40bb882e4a55e20e575592..10b64c4377af7c6523fee5d45ce4bcc21902923d 100644 (file)
@@ -2687,7 +2687,6 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
    if (dcr->VolumeName[0] == 0) {
       return dir_ask_sysop_to_create_appendable_volume(dcr);
    }
-   dev->close();
    Pmsg1(-1, "%s", dev->errmsg);           /* print reason */
    if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
       fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
@@ -2696,6 +2695,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
       fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
          dcr->VolumeName, dev->print_name());
    }
+   dev->close();
    getchar();
    return true;
 }
@@ -2716,9 +2716,9 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
    }
    autochanger = autoload_device(dcr, 1, NULL);
    if (!autochanger) {
-      dev->close();
       fprintf(stderr, _("Mount blank Volume on device %s and press return when ready: "),
          dev->print_name());
+      dev->close();
       getchar();
    }
    open_device(dcr);
index a4dc8477339001af4280534e89e1f5f05008078f..331e7a5faa3947f6d2aa6abc19b6c79472f2d8f9 100644 (file)
@@ -518,6 +518,23 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
    if (num_dvd_parts != VolCatInfo.VolCatParts) {
       num_dvd_parts = VolCatInfo.VolCatParts;
    }
+
+   /*
+    * If we are not trying to access the last part, set mode to 
+    *   OPEN_READ_ONLY as writing would be an error.
+    */
+   Dmsg2(29, "open DVD part=%d num_dvd_parts=%d\n", part, num_dvd_parts);
+   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);
+
    // Clear any previous truncated_dvd status - we will recalculate it here
    truncated_dvd = false;
 
@@ -574,21 +591,6 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
    openmode = omode;
    Dmsg2(100, "openmode=%d %s\n", openmode, mode_to_str(openmode));
    
-   /*
-    * If we are not trying to access the last part, set mode to 
-    *   OPEN_READ_ONLY as writing would be an error.
-    */
-   Dmsg2(29, "open DVD part=%d num_dvd_parts=%d\n", part, num_dvd_parts);
-   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);
 
    /* If creating file, give 0640 permissions */
    Dmsg3(29, "mode=%s open(%s, 0x%x, 0640)\n", mode_to_str(omode), 
index 96eca5b32daf636fd0b54257b927724b698a9c9e..beb9c7de71223932d3f12962704213adff68747e 100644 (file)
@@ -904,3 +904,76 @@ bool check_can_write_on_non_blank_dvd(DCR *dcr)
    Dmsg2(29, "OK  can_write_on_non_blank_dvd: got %d files in the mount point (matched=%d)\n", count, matched);
    return matched;
 }
+
+/* 
+ * Mount a DVD device, then scan to find out how many parts
+ *  there are.
+ */
+int find_num_dvd_parts(DCR *dcr)
+{
+   DEVICE *dev = dcr->dev;
+   int num_parts = 0;
+
+   if (!dev->is_dvd()) {
+      return 0;
+   }
+   
+   if (dev->mount(1)) {
+      DIR* dp;
+      struct dirent *entry, *result;
+      int name_max;
+      int len = strlen(dcr->VolCatInfo.VolCatName);
+
+      /* Now count the number of parts */
+      name_max = pathconf(".", _PC_NAME_MAX);
+      if (name_max < 1024) {
+         name_max = 1024;
+      }
+         
+      if (!(dp = opendir(dev->device->mount_point))) {
+         berrno be;
+         dev->dev_errno = errno;
+         Dmsg3(29, "find_num_dvd_parts: failed to open dir %s (dev=%s), ERR=%s\n", 
+               dev->device->mount_point, dev->print_name(), be.strerror());
+         goto get_out;
+      }
+      
+      entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000);
+
+      Dmsg1(100, "Looking for Vol=%s\n", dcr->VolCatInfo.VolCatName);
+      for ( ;; ) {
+         int flen;
+         bool ignore;
+         if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) {
+            dev->dev_errno = EIO;
+            Dmsg2(129, "find_num_dvd_parts: failed to find suitable file in dir %s (dev=%s)\n", 
+                  dev->device->mount_point, dev->print_name());
+            break;
+         }
+         flen = strlen(result->d_name);
+         ignore = true;
+         if (flen >= len) {
+            result->d_name[len] = 0;
+            if (strcmp(dcr->VolCatInfo.VolCatName, result->d_name) == 0) {
+               num_parts++;
+               Dmsg1(100, "find_num_dvd_parts: found part: %s\n", result->d_name);
+               ignore = false;
+            }
+         }
+         if (ignore) {
+            Dmsg2(129, "find_num_dvd_parts: ignoring %s in %s\n", 
+                  result->d_name, dev->device->mount_point);
+         }
+      }
+      free(entry);
+      closedir(dp);
+      Dmsg1(29, "find_num_dvd_parts = %d\n", num_parts);
+   }
+   
+get_out:
+   dev->set_freespace_ok();
+   if (dev->is_mounted()) {
+      dev->unmount(0);
+   }
+   return num_parts;
+}
index 1b9cf9d078db3f3f3533db02c2f2ad971e5ef4a0..10b82cf1d8eeb5c4e08e97dd782dfa48370a45c0 100644 (file)
@@ -119,6 +119,7 @@ void make_mounted_dvd_filename(DEVICE *dev, POOL_MEM &archive_name);
 void make_spooled_dvd_filename(DEVICE *dev, POOL_MEM &archive_name);
 bool truncate_dvd(DCR *dcr);
 bool check_can_write_on_non_blank_dvd(DCR *dcr);
+int find_num_dvd_parts(DCR *dcr);
 
 /* From device.c */
 bool     open_device(DCR *dcr);
index 2a0712a7a82c7cff6a9453e6019d36256a1f6473..811d2e2bdd3b49dbe59f4dbddd8bcea3b06d8ebd 100644 (file)
@@ -1,6 +1,18 @@
               Technical notes on version 1.39  
 
 General:
+11Sep06
+kes  Modify disk changer to simulate some of the error conditions
+     of mtx-changer.
+kes  Make sure the close() call in the SD tools is just before the
+     getchar() call.
+kes  Implement dir_get_volume_info() in bls using the patch from
+     Richard Mortimer but call find_num_dvd_parts().
+kes  Implement find_num_dvd_parts() that mounts and scans a DVD
+     and counts the parts. 
+kes  Move the omode code in open_dvd() up so that the cannot
+     write on blank disk can check can be bypassed for read mode.
+     Not yet implemented.
 10Sep06
 kes  Disable normal data spooling for DVD writing which uses  
      a different spooling mechanism.