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)
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;
}
/* 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; }
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;
+}
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;
}
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: "),
fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
dcr->VolumeName, dev->print_name());
}
+ dev->close();
getchar();
return true;
}
}
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);
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;
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),
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;
+}
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);
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.