]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Apply dvd-handler patch from Richard Mortimer.
authorKern Sibbald <kern@sibbald.com>
Wed, 30 Aug 2006 16:19:32 +0000 (16:19 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 30 Aug 2006 16:19:32 +0000 (16:19 +0000)
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

bacula/ReleaseNotes
bacula/scripts/dvd-handler.in
bacula/src/lib/bpipe.c
bacula/src/stored/autochanger.c
bacula/src/stored/block.c
bacula/src/stored/dev.c
bacula/src/stored/dvd.c
bacula/src/stored/label.c
bacula/src/stored/reserve.c
bacula/technotes-1.39

index 8873284c340572444fae93174465fff239806a05..8442a90b363aefefefa7e37024d0d404e839590b 100644 (file)
@@ -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:
index 66e258c5f3641a8dac5dc618550df41fea317e39..14bce276ab471d69e2a598059ac24fdca1af4a49 100644 (file)
@@ -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))
 
index 3f142bb8cbe77691cb345a7756dc6370449c36d3..7b1535e4b0b5e8ac49598806a438ce1c78cc56f1 100644 (file)
@@ -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);
index f2bd9fd1fc69fa0638ea25d7f64873240949fe69..65549cfe70e2ffe17537996e4f334c8cc2c1b467 100644 (file)
@@ -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;
index 136175601a1c40a5e6865eafda430992b734691e..0cf0ea40f2d1b5f0b29f8136cb31f740adc4e530 100644 (file)
@@ -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;
    }
index 4dc9352d14538f639ffdc0c2eb3a0f33e0b51e45..5ecbe103ca900e97553c76754ec5e41807f783ee 100644 (file)
@@ -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++;
- *          }
- *       }
- */
-
       }
    }
 }
index 9201a4844de3097ad714f2849044efc32a2c6680..bb890056fa3f90c5be59dcaf27f141c0ec833be2 100644 (file)
@@ -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;
index 4959d55268e1b87d168f5929d83069c29981332e..5734f4369082aff3a21fbdd39fb69f7f3375562c 100644 (file)
@@ -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 {
index dad24e65def7aef85a39ac156e387709101a3b31..250bd4f7c9e68d401d970ed906bb7671dfe5a51e 100644 (file)
@@ -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;
index 70830cf93b987465c835dff360d84d62589ee651..bc9f422490b7f45fdc04395162bfd2e7392eb467 100644 (file)
@@ -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