From f38b0d104d80ef9567a902d609b3cf9d0564f365 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 16 Sep 2006 16:59:25 +0000 Subject: [PATCH 1/1] kes Correct a test in block.c that prevented restore of a DVD from looking at the last part in the spool directory. kes Make some error messages clearer mostly by using the word DVD in the message. Improve infor message in read_record for DVDs. kes Remove DVD kludges in dircmd.c label/relabel. kes Move the dvd relabel code from dircmd.c into write_new_volume_label_to_dvd() adding a relabel argument. kes Rewrite the truncate_dvd() code to be much simpler and more logical. First blow away any spool part, then create a new empty part and write to the DVD. kes Rewrite the can_write_on_non_blank_dvd() code making it only ensure that no valid data is on the DVD -- i.e. it can be overwritten. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3477 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/block.c | 30 +++++----- bacula/src/stored/btape.c | 2 +- bacula/src/stored/dev.c | 11 ++-- bacula/src/stored/dircmd.c | 36 ++++-------- bacula/src/stored/dvd.c | 100 ++++++++++++++------------------ bacula/src/stored/label.c | 16 ++++- bacula/src/stored/mount.c | 2 +- bacula/src/stored/protos.h | 3 +- bacula/src/stored/read_record.c | 13 +++-- bacula/src/version.h | 4 +- bacula/technotes-1.39 | 14 +++++ 11 files changed, 122 insertions(+), 109 deletions(-) diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 728c5343bd..2b62215673 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -570,7 +570,7 @@ bool write_block_to_dev(DCR *dcr) } /* We successfully wrote the block, now do housekeeping */ - Dmsg2(400, "VolCatBytes=%d newVolCatBytes=%d\n", (int)dev->VolCatInfo.VolCatBytes, + Dmsg2(1300, "VolCatBytes=%d newVolCatBytes=%d\n", (int)dev->VolCatInfo.VolCatBytes, (int)(dev->VolCatInfo.VolCatBytes+wlen)); dev->VolCatInfo.VolCatBytes += wlen; dev->VolCatInfo.VolCatBlocks++; @@ -919,23 +919,25 @@ reread: return false; } - /*Dmsg1(100, "dev->file_size=%u\n",(unsigned int)dev->file_size); - Dmsg1(100, "dev->file_addr=%u\n",(unsigned int)dev->file_addr); - Dmsg1(100, "lseek=%u\n",(unsigned int)lseek(dev->fd, 0, SEEK_CUR)); - Dmsg1(100, "dev->part_start=%u\n",(unsigned int)dev->part_start); - Dmsg1(100, "dev->file_addr-dev->part_start=%u\n",(unsigned int)dev->file_addr-dev->part_start); - Dmsg1(100, "dev->file_size-dev->part_start=%u\n",(unsigned int)dev->file_size-dev->part_start); - Dmsg1(100, "dev->part_size=%u\n", (unsigned int)dev->part_size); - Dmsg1(100, "dev->part=%u\n", (unsigned int)dev->part); - Dmsg1(100, "dev->num_dvd_parts=%u\n", (unsigned int)dev->num_dvd_parts); - Dmsg1(100, "dev->VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts); - Dmsg3(100, "Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0), +#define lots_of_debug +#ifdef lots_of_debug + if (dev->at_eof() && dev->is_dvd()) { + Dmsg1(100, "file_size=%u\n",(unsigned int)dev->file_size); + Dmsg1(100, "file_addr=%u\n",(unsigned int)dev->file_addr); + Dmsg1(100, "lseek=%u\n",(unsigned int)lseek(dev->fd, 0, SEEK_CUR)); + Dmsg1(100, "part_start=%u\n",(unsigned int)dev->part_start); + Dmsg1(100, "part_size=%u\n", (unsigned int)dev->part_size); + Dmsg2(100, "part=%u num_dvd_parts=%u\n", dev->part, dev->num_dvd_parts); + Dmsg1(100, "VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts); + Dmsg3(100, "Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0), ((dev->file_addr-dev->part_start) == dev->part_size), - (dev->part <= dev->VolCatInfo.VolCatParts));*/ + (dev->part <= dev->VolCatInfo.VolCatParts)); + } +#endif /* Check for DVD part file end */ if (dev->at_eof() && dev->is_dvd() && dev->num_dvd_parts > 0 && - dev->part < dev->num_dvd_parts) { + dev->part <= dev->num_dvd_parts) { Dmsg0(400, "Call dvd_open_next_part\n"); if (dvd_open_next_part(dcr) < 0) { Jmsg3(dcr->jcr, M_FATAL, 0, _("Unable to open device part=%d %s: ERR=%s\n"), diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index fb561309c8..8184f53204 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -384,7 +384,7 @@ static void labelcmd() } } dev->rewind(dcr); - write_new_volume_label_to_dev(dcr, cmd, "Default", true /* label dvd now */); + 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); } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index cc599b5657..17d5aff193 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -490,7 +490,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) archive_name.c_str(), mode_to_str(omode)); /* - * For a DVD we must alway pull the state info from dcr->VolCatInfo + * For a DVD we must always pull the state info from dcr->VolCatInfo * This is a bit ugly, but is necessary because we need to open/close/re-open * the dvd file in order to properly mount/unmount and access the * DVD. So we store the state of the DVD as far as is known in the @@ -551,7 +551,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) * we continue (it's the method used by truncate_dvd to truncate a volume). */ if (!check_can_write_on_non_blank_dvd(dcr)) { - Mmsg(errmsg, _("The media in the device %s is not empty, please blank it before writing anything to it.\n"), print_name()); + Mmsg(errmsg, _("The DVD in device %s contains data, please blank it before writing.\n"), print_name()); Emsg0(M_FATAL, 0, errmsg); unmount_dvd(this, 1); /* Unmount the device, so the operator can change it. */ clear_opened(); @@ -572,13 +572,13 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) if (have_media()) { Dmsg1(29, "Could not mount device %s, this is not a problem (num_dvd_parts == 0), and have media.\n", print_name()); } else { - Mmsg(errmsg, _("There is no valid media in the device %s.\n"), print_name()); + Mmsg(errmsg, _("There is no valid DVD in device %s.\n"), print_name()); Emsg0(M_FATAL, 0, errmsg); clear_opened(); return; } } else { - Mmsg(errmsg, _("Could not mount device %s.\n"), print_name()); + Mmsg(errmsg, _("Could not mount DVD device %s.\n"), print_name()); Emsg0(M_FATAL, 0, errmsg); clear_opened(); return; @@ -1842,6 +1842,9 @@ bool DEVICE::truncate(DCR *dcr) /* We need the DCR for DVD-writing */ return truncate_dvd(dcr); } + /* ***FIXME*** we really need to unlink() the file so that + * its name can be changed for a relabel. + */ if (ftruncate(fd, 0) != 0) { berrno be; Mmsg2(errmsg, _("Unable to truncate device %s. ERR=%s\n"), diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 8889efaa81..f3ce023113 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -390,18 +390,14 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, DEVICE *dev = dcr->dev; int label_status; int mode; - const char *volname = (relabel == 0) ? newname : oldname; + const char *volname = (relabel == 1) ? oldname : newname; char ed1[50]; steal_device_lock(dev, &hold, BST_WRITING_LABEL); Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name()); - Dmsg0(90, "try_autoload_device - looking for volume_info\n"); - if (relabel && dev->is_dvd()) { - /* Fake at least one partition to ensure that we look for the old volume */ - dcr->VolCatInfo.VolCatParts = 1; - } + Dmsg0(90, "try_autoload_device - looking for volume_info\n"); if (!try_autoload_device(dcr->jcr, slot, volname)) { goto bail_out; /* error */ } @@ -412,10 +408,12 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, } else { mode = CREATE_READ_WRITE; } - if (dev->is_dvd()) { - bstrncpy(dcr->VolCatInfo.VolCatName, volname, sizeof(dcr->VolCatInfo.VolCatName)); - } + if (relabel) { + dev->truncating = true; /* let open() know we will truncate it */ + } + /* Set old volume name for open if relabeling */ + bstrncpy(dcr->VolCatInfo.VolCatName, volname, sizeof(dcr->VolCatInfo.VolCatName)); if (dev->open(dcr, mode) < 0) { bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"), dev->print_name(), dev->strerror()); @@ -425,6 +423,8 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, /* See what we have for a Volume */ label_status = read_dev_volume_label(dcr); + /* Set new volume name */ + bstrncpy(dcr->VolCatInfo.VolCatName, newname, sizeof(dcr->VolCatInfo.VolCatName)); switch(label_status) { case VOL_NAME_ERROR: case VOL_VERSION_ERROR: @@ -446,25 +446,11 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n")); break; } - if (relabel && dev->is_dvd()) { - /* Save dev VolumeName */ - bstrncpy(dcr->VolumeName, dev->VolCatInfo.VolCatName, sizeof(dcr->VolumeName)); - /* Use new name for DVD truncation */ - bstrncpy(dev->VolCatInfo.VolCatName, newname, sizeof(dev->VolCatInfo.VolCatName)); - if (!dev->truncate(dcr)) { - bnet_fsend(dir, _("3912 Failed to truncate previous DVD volume.\n")); - /* Restore device VolName */ - bstrncpy(dev->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dev->VolCatInfo.VolCatName)); - break; - } - /* Restore device VolName */ - bstrncpy(dev->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dev->VolCatInfo.VolCatName)); - } - free_volume(dev); /* release old volume name */ /* Fall through wanted! */ case VOL_IO_ERROR: case VOL_NO_LABEL: - if (!write_new_volume_label_to_dev(dcr, newname, poolname, true /* write dvd now */)) { + if (!write_new_volume_label_to_dev(dcr, newname, poolname, + relabel, true /* write dvd now */)) { bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror()); break; } diff --git a/bacula/src/stored/dvd.c b/bacula/src/stored/dvd.c index 74642dff7e..e958c3fbbb 100644 --- a/bacula/src/stored/dvd.c +++ b/bacula/src/stored/dvd.c @@ -122,6 +122,7 @@ static bool do_mount_dvd(DEVICE* dev, int mount, int dotimeout) icmd = dev->device->unmount_command; } + dev->clear_freespace_ok(); dev->edit_mount_codes(ocmd, icmd); Dmsg2(200, "do_mount_dvd: cmd=%s mounted=%d\n", ocmd.c_str(), !!dev->is_mounted()); @@ -296,7 +297,7 @@ bool update_free_space_dev(DEVICE* dev) berrno be; Dmsg1(20, "Run freespace prog=%s\n", ocmd.c_str()); status = run_program_full_output(ocmd.c_str(), dev->max_open_wait/2, results); - Dmsg2(20, "Freespace status=%d result=%s\n", status, results); + Dmsg2(500, "Freespace status=%d result=%s\n", status, results); if (status == 0) { free = str_to_int64(results); Dmsg1(400, "Free space program run: Freespace=%s\n", results); @@ -357,7 +358,8 @@ bool dvd_write_part(DCR *dcr) DEVICE *dev = dcr->dev; POOL_MEM archive_name(PM_FNAME); - /* Don't write empty part files. + /* + * Don't write empty part files. * This is only useful when growisofs does not support write beyond * the 4GB boundary. * Example : @@ -369,7 +371,6 @@ bool dvd_write_part(DCR *dcr) * - Bacula thinks he must finish to write to the device, so it * tries to write the last part (0-byte), but dvd-writepart fails... * - * ***FIXME**** we cannot write a blank part!!!!!!! * There is one exception: when recycling a volume, we write a blank part * file, so, then, we need to accept to write it. */ @@ -379,7 +380,7 @@ bool dvd_write_part(DCR *dcr) make_spooled_dvd_filename(dev, archive_name); unlink(archive_name.c_str()); dev->set_part_spooled(false); - Dmsg1(29, "unlink(%s)\n", archive_name.c_str()); + Dmsg1(29, "========= unlink(%s)\n", archive_name.c_str()); sm_check(__FILE__, __LINE__, false); return true; } @@ -454,7 +455,7 @@ bool dvd_write_part(DCR *dcr) make_spooled_dvd_filename(dev, archive_name); unlink(archive_name.c_str()); dev->set_part_spooled(false); - Dmsg1(29, "unlink(%s)\n", archive_name.c_str()); + Dmsg1(29, "========= unlink(%s)\n", archive_name.c_str()); sm_check(__FILE__, __LINE__, false); /* growisofs umounted the device, so remount it (it will update the free space) */ @@ -570,7 +571,7 @@ int dvd_open_next_part(DCR *dcr) * - Close the fd * - Reopen the device */ -int dvd_open_first_part(DCR *dcr, int mode) +static bool dvd_open_first_part(DCR *dcr, int mode) { DEVICE *dev = dcr->dev; @@ -588,11 +589,11 @@ int dvd_open_first_part(DCR *dcr, int mode) if (dev->open(dcr, mode) < 0) { Dmsg0(400, "open dev() failed\n"); - return -1; + return false; } Dmsg2(400, "Leave open_first_part state=%s append=%d\n", dev->is_open()?"open":"not open", dev->can_append()); - return dev->fd; + return true; } @@ -640,7 +641,7 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) * until the right one is loaded */ Dmsg0(100, "lseek open first part\n"); - if (dvd_open_first_part(dcr, dev->openmode) < 0) { + if (!dvd_open_first_part(dcr, dev->openmode)) { Dmsg0(400, "lseek_dvd failed while trying to open the first part\n"); return -1; } @@ -699,7 +700,7 @@ off_t lseek_dvd(DCR *dcr, off_t offset, int whence) * (useful for DVDs) */ int modesave = dev->openmode; - if (dvd_open_first_part(dcr, OPEN_READ_ONLY) < 0) { + if (!dvd_open_first_part(dcr, OPEN_READ_ONLY)) { Dmsg0(400, "lseek_dvd failed while trying to open the first part\n"); return -1; } @@ -801,7 +802,17 @@ bool truncate_dvd(DCR *dcr) return false; } + /* If necessary, delete its spool file. */ + if (dev->is_part_spooled()) { + POOL_MEM archive_name(PM_FNAME); + /* Delete spool file */ + make_spooled_dvd_filename(dev, archive_name); + unlink(archive_name.c_str()); + dev->set_part_spooled(false); + } + /* Set num_dvd_parts to zero (on disk) */ + dev->part = 0; dev->num_dvd_parts = 0; dcr->VolCatInfo.VolCatParts = 0; dev->VolCatInfo.VolCatParts = 0; @@ -809,31 +820,20 @@ bool truncate_dvd(DCR *dcr) Dmsg0(400, "truncate_dvd: Opening first part (1)...\n"); dev->truncating = true; - if (dvd_open_first_part(dcr, CREATE_READ_WRITE) < 0) { + /* This creates a zero length spool file and sets part=1 */ + if (!dvd_open_first_part(dcr, CREATE_READ_WRITE)) { Dmsg0(400, "truncate_dvd: Error while opening first part (1).\n"); dev->truncating = false; return false; } - Dmsg0(400, "truncate_dvd: Truncating...\n"); - - /* If necessary, truncate it spool file. */ - if (ftruncate(dev->fd, 0) != 0) { - berrno be; - Mmsg2(dev->errmsg, _("Unable to truncate device %s. ERR=%s\n"), - dev->print_name(), be.strerror()); - dev->truncating = false; - return false; - } - dev->close_part(dcr); Dmsg0(400, "truncate_dvd: Opening first part (2)...\n"); /* - * Now actually truncate the DVD - * This is really kludgy, why not an argument or a separate - * subroutine? KES + * Now actually truncate the DVD which is done by writing + * a zero length part to the DVD/ */ if (!dvd_write_part(dcr)) { Dmsg0(400, "truncate_dvd: Error while writing to DVD.\n"); @@ -843,6 +843,7 @@ bool truncate_dvd(DCR *dcr) dev->truncating = false; /* Set num_dvd_parts to zero (on disk) */ + dev->part = 0; dev->num_dvd_parts = 0; dcr->VolCatInfo.VolCatParts = 0; dev->VolCatInfo.VolCatParts = 0; @@ -850,30 +851,22 @@ bool truncate_dvd(DCR *dcr) dev->VolCatInfo.VolCatBytes = 0; dcr->VolCatInfo.VolCatBytes = 0; -#ifdef xxx /* Update catalog */ if (!dir_update_volume_info(dcr, false)) { return false; } -#endif - if (dvd_open_first_part(dcr, OPEN_READ_WRITE) < 0) { - Dmsg0(400, "truncate_dvd: Error while opening first part (2).\n"); - return false; - } - return true; } -/* Checks if we can write on a non-blank DVD: meaning that it just have been - * truncated (there is only one zero-sized file on the DVD, with the right - * volume name). +/* + * Checks if we can write on a non-blank DVD: meaning that it just have been + * truncated (there is only one zero-sized file on the DVD). * * Note! Normally if we can mount the device, which should be the case * when we get here, it is not a blank DVD. Hence we check if - * there is a zero length file with the right name, in which case - * we allow it. - * This seems terribly kludgie to me. KES + * if all files are of zero length (i.e. no data), in which case we allow it. + * */ bool check_can_write_on_non_blank_dvd(DCR *dcr) { @@ -881,9 +874,8 @@ bool check_can_write_on_non_blank_dvd(DCR *dcr) DIR* dp; struct dirent *entry, *result; int name_max; - int count = 0; - bool matched = true; struct stat filestat; + bool ok = true; name_max = pathconf(".", _PC_NAME_MAX); if (name_max < 1024) { @@ -899,7 +891,7 @@ bool check_can_write_on_non_blank_dvd(DCR *dcr) } entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 1000); - while (1) { + for ( ;; ) { if ((readdir_r(dp, entry, &result) != 0) || (result == NULL)) { dev->dev_errno = EIO; Dmsg2(129, "check_can_write_on_non_blank_dvd: no more files in dir %s (dev=%s)\n", @@ -908,39 +900,37 @@ bool check_can_write_on_non_blank_dvd(DCR *dcr) } else { Dmsg2(99, "check_can_write_on_non_blank_dvd: found %s (versus %s)\n", result->d_name, dev->VolCatInfo.VolCatName); - if (strcmp(result->d_name, dev->VolCatInfo.VolCatName) == 0) { - /* Found the file, checking it is empty */ + if (strcmp(result->d_name, ".") && strcmp(result->d_name, "..") && + strcmp(result->d_name, ".keep")) { + /* Found a file, checking it is empty */ POOL_MEM filename(PM_FNAME); pm_strcpy(filename, dev->device->mount_point); if (filename.c_str()[strlen(filename.c_str())-1] != '/') { pm_strcat(filename, "/"); } - pm_strcat(filename, dev->VolCatInfo.VolCatName); + pm_strcat(filename, result->d_name); if (stat(filename.c_str(), &filestat) < 0) { berrno be; dev->dev_errno = errno; Dmsg2(29, "check_can_write_on_non_blank_dvd: cannot stat file (file=%s), ERR=%s\n", filename.c_str(), be.strerror()); - return false; + ok = false; + break; } Dmsg2(99, "check_can_write_on_non_blank_dvd: size of %s is %lld\n", filename.c_str(), filestat.st_size); - matched = filestat.st_size == 0; + if (filestat.st_size != 0) { + ok = false; + break; + } } } - count++; } free(entry); closedir(dp); - if (count > 3) { - /* There are more than 3 files (., .., and the volume file) */ - Dmsg1(29, "Cannot write on blank DVD too many files %d greater than 3\n", count); - return false; - } - - Dmsg2(29, "OK can_write_on_non_blank_dvd: got %d files in the mount point (matched=%d)\n", count, matched); - return matched; + Dmsg1(29, "OK can_write_on_non_blank_dvd: OK=%d\n", ok); + return ok; } /* diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 32a65297bf..12b25388d5 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -290,7 +290,7 @@ bool write_volume_label_to_block(DCR *dcr) * This routine should be used only when labeling a blank tape. */ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, - const char *PoolName, bool dvdnow) + const char *PoolName, bool relabel, bool dvdnow) { DEVICE *dev = dcr->dev; @@ -298,6 +298,19 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, Dmsg0(99, "write_volume_label()\n"); empty_block(dcr->block); + /* If relabeling, truncate the device */ + if (relabel && !dev->truncate(dcr)) { + goto bail_out; + } + + if (relabel) { + dev->close_part(dcr); /* make sure closed for rename */ + } + + /* Set the new filename for open, ... */ + bstrncpy(dev->VolCatInfo.VolCatName, VolName, sizeof(dev->VolCatInfo.VolCatName)); + bstrncpy(dcr->VolCatInfo.VolCatName, VolName, sizeof(dcr->VolCatInfo.VolCatName)); + Dmsg1(150, "New VolName=%s\n", VolName); if (dev->open(dcr, OPEN_READ_WRITE) < 0) { /* If device is not tape, attempt to create it */ if (dev->is_tape() || dev->open(dcr, CREATE_READ_WRITE) < 0) { @@ -351,6 +364,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, /* Now commit block to DVD if we should write now */ if (dev->is_dvd() && dvdnow) { + Dmsg1(150, "New VolName=%s\n", dev->VolCatInfo.VolCatName); if (!dvd_write_part(dcr)) { Dmsg2(30, "Bad DVD write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror()); goto bail_out; diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 4ca03652d3..ddc2b5d58f 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -445,7 +445,7 @@ static int try_autolabel(DCR *dcr) Dmsg0(150, "Create volume label\n"); /* Create a new Volume label and write it to the device */ if (!write_new_volume_label_to_dev(dcr, dcr->VolumeName, - dcr->pool_name, false /* defer DVD label */)) { + dcr->pool_name, false, /* no relabel */ false /* defer DVD label */)) { Dmsg0(150, "!write_vol_label\n"); mark_volume_in_error(dcr); return try_next_vol; diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 84ef598d07..e9c8b1cca9 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -146,7 +146,8 @@ int read_dev_volume_label(DCR *dcr); int read_dvd_volume_label(DCR *dcr, bool write); void create_session_label(DCR *dcr, DEV_RECORD *rec, int label); void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName, bool dvdnow); -bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName, bool dvdnow); +bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, + const char *PoolName, bool relabel, bool dvdnow); #define ANSI_VOL_LABEL 0 #define ANSI_EOF_LABEL 1 #define ANSI_EOV_LABEL 2 diff --git a/bacula/src/stored/read_record.c b/bacula/src/stored/read_record.c index 5d1069e8c0..655c9950f8 100644 --- a/bacula/src/stored/read_record.c +++ b/bacula/src/stored/read_record.c @@ -109,14 +109,17 @@ bool read_records(DCR *dcr, } else if (dev->at_eof()) { if (verbose) { - char dvdpart[100]; + char *fp; + uint32_t fp_num; if (dev->is_dvd()) { - bsnprintf(dvdpart, sizeof(dvdpart), _("part %d "), dev->part); + fp = _("part"); + fp_num = dev->part; } else { - dvdpart[0] = 0; + fp = _("file"); + fp_num = dev->file; } - Jmsg(jcr, M_INFO, 0, _("End of file %u %son device %s, Volume \"%s\"\n"), - dev->file, dvdpart, dev->print_name(), dcr->VolumeName); + Jmsg(jcr, M_INFO, 0, _("End of %s %u on device %s, Volume \"%s\"\n"), + fp, fp_num, dev->print_name(), dcr->VolumeName); } Dmsg3(200, "End of file %u on device %s, Volume \"%s\"\n", dev->file, dev->print_name(), dcr->VolumeName); diff --git a/bacula/src/version.h b/bacula/src/version.h index 39ea8444ba..8146603819 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "1.39.23" -#define BDATE "15 September 2006" -#define LSMDATE "15Sep06" +#define BDATE "16 September 2006" +#define LSMDATE "16Sep06" #define BYEAR "2006" /* year for copyright messages in progs */ /* Debug flags */ diff --git a/bacula/technotes-1.39 b/bacula/technotes-1.39 index 2d49c311fc..ea919b57b2 100644 --- a/bacula/technotes-1.39 +++ b/bacula/technotes-1.39 @@ -1,6 +1,20 @@ Technical notes on version 1.39 General: +16Sep06 +kes Correct a test in block.c that prevented restore of a DVD from + looking at the last part in the spool directory. +kes Make some error messages clearer mostly by using the word DVD + in the message. Improve infor message in read_record for DVDs. +kes Remove DVD kludges in dircmd.c label/relabel. +kes Move the dvd relabel code from dircmd.c into + write_new_volume_label_to_dvd() adding a relabel argument. +kes Rewrite the truncate_dvd() code to be much simpler and + more logical. First blow away any spool part, then create a + new empty part and write to the DVD. +kes Rewrite the can_write_on_non_blank_dvd() code making it + only ensure that no valid data is on the DVD -- i.e. it + can be overwritten. 15Sep06 kes Minor Makefile fixes. kes Put attach_dcr_to_dev in a subroutine. -- 2.39.2