From: Kern Sibbald Date: Wed, 30 Aug 2006 16:19:32 +0000 (+0000) Subject: kes Apply dvd-handler patch from Richard Mortimer. X-Git-Tag: Release-2.0.0~528 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=e7e9bb6646aaa795d3bb8a036cffa498a9a17b4e;p=bacula%2Fbacula kes Apply dvd-handler patch from Richard Mortimer. kes Apply dvd error check patch from Richard Mortimer. kes Apply bpipe race patch from Richard Mortimer. kes Rework how DVD labels are handled and set append only when part > num_dvd_parts. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3388 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index 8873284c34..8442a90b36 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -32,6 +32,37 @@ Fixes for 1.39.20: - Eric fixed RunScripts, which I (Kern) had broken in the last beta. - Correct Client migration SQL as pointed out by Marc. +New Features in 1.40.0 (beginning of release info) +- There is a new cross-compiled Win32 File daemon that now has all the features + that were previously only in the Unix versions. + + To install the 1.39.18 Win32 FD, you *must* first stop any + previous version that is running in a DOS shell with: + + net stop bacula + + or select the 'Close Bacula' menu item from the Bacula tray icon, + you should then save your bacula-fd.conf file, and either + uninstall (using Uninstall.bat in the c:\bacula directory) or + remove the old installation by manually in a DOS shell in the + Bacula directory enter: + + bacula-fd /remove + + after that you can proceed with the installation. My experience + is that it does not properly create the new bacula-fd.conf file, so + copy the one saved to the directory you chose to install Bacula, + or to the directory chosen by the Installer to put the bacula-fd.conf + file. Then you can start Bacula in a DOS shell with: + + net start baculafd + + or use the Windows Control Panel->Administrative Tools->Component + Services menu item. The document has been updated (not completely). + For installation details, please see: + http://www.bacula.org/dev-manual/Windows_Version_Bacula.html + + ========================================== Warning for version 1.39.18 and greater: @@ -62,29 +93,6 @@ Warning for version 1.39.18 and greater: - The "Accept Any Volume" directive has been removed. It was never implemented. Bacula will always accept any valid tape that is in the drive for appending. -- To install the 1.39.18 Win32 FD, you *must* first stop any - previous version that is running in a DOS shell with: - - net stop bacula - - or select the 'Close Bacula' menu item from the Bacula tray icon, - you should then save your bacula-fd.conf file, and either - uninstall (using Uninstall.bat in the c:\bacula directory) or - remove the old installation by manually in a DOS shell in the - Bacula directory enter: - - bacula-fd /remove - - after that you can proceed with the installation. My experience - is that it does not properly create the new bacula-fd.conf file, so - copy the one saved to the directory you chose to install Bacula, - or to the directory chosen by the Installer to put the bacula-fd.conf - file. Then you can start Bacula in a DOS shell with: - - net start baculafd - - or use the Windows Control Panel->Administrative Tools->Component - Services menu item. A Lot of New features for 1.39.18: diff --git a/bacula/scripts/dvd-handler.in b/bacula/scripts/dvd-handler.in index 66e258c5f3..14bce276ab 100644 --- a/bacula/scripts/dvd-handler.in +++ b/bacula/scripts/dvd-handler.in @@ -288,6 +288,8 @@ class disk: self.pid = 0 print signal.signal(signal.SIGTERM, oldsig) + if not os.WIFEXITED(status): + raise DVDError(0, cmd + " process did not exit correctly, signal/status " + str(status)) if os.WEXITSTATUS(status) != 0: raise DVDError(os.WEXITSTATUS(status), cmd + " exited with status " + str(os.WEXITSTATUS(status)) + ", signal/status " + str(status)) diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index 3f142bb8cb..7b1535e4b0 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -247,7 +247,7 @@ int close_bpipe(BPIPE *bpipe) stop_child_timer(bpipe->timer_id); } free(bpipe); - Dmsg2(800, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat); + Dmsg2(200, "returning stat=%d,%d\n", stat & ~(b_errno_exit|b_errno_signal), stat); return stat; } @@ -420,16 +420,23 @@ int run_program_full_output(char *prog, int wait, POOLMEM *results) break; } else if (stat1 != 0) { Dmsg1(900, "Run program fgets stat=%d\n", stat1); - if (bpipe->timer_id) { - Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed); - if (bpipe->timer_id->killed) { - pm_strcat(tmp, _("Program killed by Bacula watchdog (timeout)\n")); - stat1 = ETIME; - break; - } + if (bpipe->timer_id && bpipe->timer_id->killed) { + Dmsg1(250, "Run program saw fgets killed=%d\n", bpipe->timer_id->killed); + break; } } } + /* + * We always check whether the timer killed the program. We would see + * an eof even when it does so we just have to trust the killed flag + * and set the timer values to avoid edge cases where the program ends + * just as the timer kills it. + */ + if (bpipe->timer_id && bpipe->timer_id->killed) { + Dmsg1(150, "Run program fgets killed=%d\n", bpipe->timer_id->killed); + pm_strcat(tmp, _("Program killed by Bacula watchdog (timeout)\n")); + stat1 = ETIME; + } int len = sizeof_pool_memory(results) - 1; bstrncpy(results, tmp, len); Dmsg3(1900, "resadr=0x%x reslen=%d res=%s\n", results, strlen(results), results); diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index f2bd9fd1fc..65549cfe70 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -105,7 +105,7 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) POOLMEM *changer; if (!dev->is_autochanger()) { - Dmsg0(200, "======== NOT AUTOCHANGER ======\n"); + Dmsg0(200, "== NOT AUTOCHANGER ==\n"); return 0; } slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0; diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 136175601a..0cf0ea40f2 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -711,7 +711,12 @@ static bool terminate_writing_volume(DCR *dcr) if (dev->is_dvd()) { if (!dvd_write_part(dcr)) { /* write last part */ + dev->VolCatInfo.VolCatErrors++; + Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing final part to DVD. " + "This Volume may not be readable.\n%s"), + dev->errmsg); ok = false; + Dmsg0(100, "dvd_write_part error.\n"); } dev->VolCatInfo.VolCatParts = dev->num_dvd_parts; } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 4dc9352d14..5ecbe103ca 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -527,6 +527,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 we can mount the device, and we are not truncating the DVD, * we usually want to abort. There is one exception, if there is @@ -540,6 +541,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode) clear_opened(); return; } +#endif truncated_dvd = true; } } else { @@ -583,6 +585,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 +602,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 +636,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++; - * } - * } - */ - } } } diff --git a/bacula/src/stored/dvd.c b/bacula/src/stored/dvd.c index 9201a4844d..bb890056fa 100644 --- a/bacula/src/stored/dvd.c +++ b/bacula/src/stored/dvd.c @@ -553,9 +553,6 @@ int dvd_open_next_part(DCR *dcr) /* Restore Volume header record */ memcpy(&dev->VolHdr, &VolHdr, sizeof(dev->VolHdr)); dev->set_labeled(); /* all next parts are "labeled" */ - if (dev->part > dev->num_dvd_parts) { /* set append if new part created */ - dev->set_append(); - } return dev->fd; } @@ -596,9 +593,6 @@ int dvd_open_first_part(DCR *dcr, int mode) Dmsg0(400, "open dev() failed\n"); return -1; } - if (dev->part > dev->num_dvd_parts) { /* created new part */ - dev->set_append(); - } Dmsg2(400, "Leave open_first_part state=%s append=%d\n", dev->is_open()?"open":"not open", dev->can_append()); return dev->fd; diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 4959d55268..5734f43690 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -388,26 +388,16 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) { DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; - bool can_write = true; if (dev->open(dcr, OPEN_READ_WRITE) < 0) { - /* If device is DVD, attempt to create it */ - if (!dev->is_dvd()) { - return false; - } - if (dev->open(dcr, CREATE_READ_WRITE) < 0) { - /* We forge on for a DVD but don't do any writing */ - can_write = false; - } + return false; } Dmsg2(190, "set append found freshly labeled volume. fd=%d dev=%x\n", dev->fd, dev); dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */ dev->set_append(); - if (can_write) { - if (!write_volume_label_to_block(dcr)) { - Dmsg0(200, "Error from write volume label.\n"); - return false; - } + if (!write_volume_label_to_block(dcr)) { + Dmsg0(200, "Error from write volume label.\n"); + return false; } /* * If we are not dealing with a streaming device, @@ -416,15 +406,17 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) * We do not write the block now if this is an ANSI label. This * avoids re-writing the ANSI label, which we do not want to do. */ - if (can_write && !dev_cap(dev, CAP_STREAM)) { + if (!dev_cap(dev, CAP_STREAM)) { if (!dev->rewind(dcr)) { - Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s: ERR=%s\n"), + Jmsg2(jcr, M_FATAL, 0, _("Rewind error on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); + return false; } if (recycle) { if (!dev->truncate(dcr)) { - Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device %s: ERR=%s\n"), + Jmsg2(jcr, M_FATAL, 0, _("Truncate error on device %s: ERR=%s\n"), dev->print_name(), dev->bstrerror()); + return false; } } @@ -483,7 +475,7 @@ bool rewrite_volume_label(DCR *dcr, bool recycle) * End writing real Volume label (from pre-labeled tape), or recycling * the volume. */ - Dmsg0(200, "OK from rewite vol label.\n"); + Dmsg0(200, "OK from rewrite vol label.\n"); return true; } @@ -566,7 +558,7 @@ void create_volume_label(DEVICE *dev, const char *VolName, bstrncpy(dev->VolHdr.Id, BaculaId, sizeof(dev->VolHdr.Id)); dev->VolHdr.VerNum = BaculaTapeVersion; - if (dev->is_dvd() && dvdnow) { + if (dev->is_dvd()) { /* We do not want to re-label a DVD so write VOL_LABEL now */ dev->VolHdr.LabelType = VOL_LABEL; } else { diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index dad24e65de..250bd4f7c9 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -242,7 +242,7 @@ void free_unused_volume(DCR *dcr) if (vol->dcr == dcr && (vol->dev == NULL || strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) { vol_list->remove(vol); - Dmsg1(100, "free_unused_olume %s\n", vol->vol_name); + Dmsg1(100, "free_unused_volume %s\n", vol->vol_name); free(vol->vol_name); free(vol); break; diff --git a/bacula/technotes-1.39 b/bacula/technotes-1.39 index 70830cf93b..bc9f422490 100644 --- a/bacula/technotes-1.39 +++ b/bacula/technotes-1.39 @@ -1,6 +1,12 @@ Technical notes on version 1.39 General: +30Aug06 +kes Apply dvd-handler patch from Richard Mortimer. +kes Apply dvd error check patch from Richard Mortimer. +kes Apply bpipe race patch from Richard Mortimer. +kes Rework how DVD labels are handled and set append only + when part > num_dvd_parts. 27Aug06 kes Rework many features of DVD writing and reading. Added many error messages. Most importantly changed part to represent the current