]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dvd.c
kes Apply patch supplied in bug #656 to pass priority field
[bacula/bacula] / bacula / src / stored / dvd.c
index 9201a4844de3097ad714f2849044efc32a2c6680..bcd360c6c95d1339d081b58b1a6e07a1273ce1f7 100644 (file)
@@ -135,11 +135,11 @@ static bool do_mount_dvd(DEVICE* dev, int mount, int dotimeout)
    results = get_memory(2000);
    results[0] = 0;
    /* If busy retry each second */
-   Dmsg1(100, "Run prog=%s\n", ocmd.c_str());
+   Dmsg1(20, "Run mount prog=%s\n", ocmd.c_str());
    while ((status = run_program_full_output(ocmd.c_str(), 
                        dev->max_open_wait/2, results)) != 0) {
-      Dmsg2(99, "Mount status=%d result=%s\n", status, results);
-      /* Doesn't work with internationalisation (This is not a problem) */
+      Dmsg2(20, "Mount status=%d result=%s\n", status, results);
+      /* Doesn't work with internationalization (This is not a problem) */
       if (mount && fnmatch("*is already mounted on*", results, 0) == 0) {
          break;
       }
@@ -261,6 +261,10 @@ bool update_free_space_dev(DEVICE* dev)
    char ed1[50];
    bool ok = false;
    int status;
+
+   if (!dev->is_dvd() || dev->is_freespace_ok()) {
+      return true;
+   }
    
    /* The device must be mounted in order to dvd-freespace to work */
    mount_dvd(dev, 1);
@@ -271,7 +275,7 @@ bool update_free_space_dev(DEVICE* dev)
    if (!icmd) {
       dev->free_space = 0;
       dev->free_space_errno = 0;
-      dev->clear_freespace_ok();   /* No valid freespace */
+      dev->clear_freespace_ok();              /* No valid freespace */
       dev->clear_media();
       Dmsg2(29, "ERROR: update_free_space_dev: free_space=%s, free_space_errno=%d (!icmd)\n", 
             edit_uint64(dev->free_space, ed1), dev->free_space_errno);
@@ -290,8 +294,9 @@ bool update_free_space_dev(DEVICE* dev)
    
    while (1) {
       berrno be;
-      Dmsg1(100, "Run prog=%s\n", ocmd.c_str());
+      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);
       if (status == 0) {
          free = str_to_int64(results);
          Dmsg1(400, "Free space program run: Freespace=%s\n", results);
@@ -352,6 +357,8 @@ bool dvd_write_part(DCR *dcr)
    DEVICE *dev = dcr->dev;
    POOL_MEM archive_name(PM_FNAME);
    
+   dev->clear_freespace_ok();             /* need to update freespace */
+
    /* Don't write empty part files.
     * This is only useful when growisofs does not support write beyond
     * the 4GB boundary.
@@ -409,15 +416,17 @@ bool dvd_write_part(DCR *dcr)
     * in case of a serious emergency.
     */
 
-   if (dev->part == 1)
+   if (dev->part == 1) {
       timeout = 16000;
-   else
+   } else {
       timeout = dev->max_open_wait + (dev->part_size/(1350*1024/4));
+   }
 
-   Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
-      
+   Dmsg2(20, "Write part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
    status = run_program_full_output(ocmd.c_str(), timeout, results.c_str());
+   Dmsg2(20, "Write part status=%d result=%s\n", status, results.c_str());
 
+   dev->truncated_dvd = false;
    if (status != 0) {
       Jmsg2(dcr->jcr, M_FATAL, 0, _("Error writing part %d to the DVD: ERR=%s\n"),
          dev->part, results.c_str());
@@ -427,16 +436,15 @@ bool dvd_write_part(DCR *dcr)
       dev->dev_errno = EIO;
       mark_volume_in_error(dcr);
       sm_check(__FILE__, __LINE__, false);
-      dev->truncated_dvd = false;
       return false;
    }
    Jmsg(dcr->jcr, M_INFO, 0, _("Part %d written to DVD.\n"), dev->part);
-   if (dev->truncated_dvd) {
-      dev->truncated_dvd = false;   /* turn off flag */
-   } else {                         /* DVD part written */
-      dev->num_dvd_parts++;            /* there is now one more part on DVD */
-      dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
-   }
+   Dmsg2(400, "dvd_write_part: Part %d written to DVD\nResults: %s\n",
+            dev->part, results.c_str());
+    
+   dev->num_dvd_parts++;            /* there is now one more part on DVD */
+   dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
+   Dmsg1(000, "Update num_parts=%d\n", dev->num_dvd_parts);
 
    /* Delete spool file */
    make_spooled_dvd_filename(dev, archive_name);
@@ -462,7 +470,6 @@ bool dvd_write_part(DCR *dcr)
 int dvd_open_next_part(DCR *dcr)
 {
    DEVICE *dev = dcr->dev;
-   VOLUME_LABEL VolHdr;
 
    Dmsg6(29, "Enter: == open_next_part part=%d npart=%d dev=%s vol=%s mode=%d file_addr=%d\n", 
       dev->part, dev->num_dvd_parts, dev->print_name(),
@@ -479,20 +486,13 @@ int dvd_open_next_part(DCR *dcr)
       return dev->fd;
    }
 
-   /*              
-    * Note, when we close, the Volume header is zeroed. Since
-    *  we reopen, but are in fact opening the same volume without
-    *  re-reading the Volume header, we simply save and restore it.
-    */
-   memcpy(&VolHdr, &dev->VolHdr, sizeof(VolHdr));
-   dev->close();                      /* close current part */
-   memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+   dev->close_part(dcr);               /* close current part */
    
    /*
-    * If we have a part open for write, then write it to
+    * If we have a spooled part open, write it to the
     *  DVD before opening the next part.
     */
-   if (dev->part > dev->num_dvd_parts && dev->can_append()) {
+   if (dev->is_part_spooled()) {
       Dmsg2(100, "Before open next write previous. part=%d num_parts=%d\n",
          dev->part, dev->num_dvd_parts);
       if (!dvd_write_part(dcr)) {
@@ -505,6 +505,7 @@ int dvd_open_next_part(DCR *dcr)
    dev->part++;
    Dmsg2(29, "Inc part=%d num_dvd_parts=%d\n", dev->part, dev->num_dvd_parts);
 
+   /* Are we working on a part past what is written in the DVD? */
    if (dev->num_dvd_parts < dev->part) {
       POOL_MEM archive_name(PM_FNAME);
       struct stat buf;
@@ -512,7 +513,7 @@ int dvd_open_next_part(DCR *dcr)
        * First check what is on DVD.  If our part is there, we
        *   are in trouble, so bail out.
        * NB: This is however not a problem if we are writing the first part.
-       * It simply means that we are overriding an existing volume...
+       * It simply means that we are over writing an existing volume...
        */
       if (dev->num_dvd_parts > 0) {
          make_mounted_dvd_filename(dev, archive_name);   /* makes dvd name */
@@ -525,13 +526,14 @@ int dvd_open_next_part(DCR *dcr)
          }
       }
 
+#ifdef neeeded
       Dmsg2(400, "num_dvd_parts=%d part=%d\n", dev->num_dvd_parts, dev->part);
       make_spooled_dvd_filename(dev, archive_name);   /* makes spool name */
       
       /* Check if the next part exists in spool directory . */
-      Dmsg1(100, "Check if part on spool: $s\n", archive_name.c_str());
+      Dmsg1(100, "Check if part on spool: %s\n", archive_name.c_str());
       if ((stat(archive_name.c_str(), &buf) == 0) || (errno != ENOENT)) {
-         Dmsg1(29, "open_next_part %s is in the way, deleting it...\n", archive_name.c_str());
+         Dmsg1(29, "======= Part %s is in the way, deleting it...\n", archive_name.c_str());
          /* Then try to unlink it */
          if (unlink(archive_name.c_str()) < 0) {
             berrno be;
@@ -541,6 +543,7 @@ int dvd_open_next_part(DCR *dcr)
             return -1;
          }
       }
+#endif
    }
 
    Dmsg2(400, "Call dev->open(vol=%s, mode=%d)\n", dcr->VolCatInfo.VolCatName, 
@@ -550,12 +553,7 @@ int dvd_open_next_part(DCR *dcr)
    if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
       return -1;
    } 
-   /* 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;
 }
@@ -568,20 +566,12 @@ int dvd_open_next_part(DCR *dcr)
 int dvd_open_first_part(DCR *dcr, int mode)
 {
    DEVICE *dev = dcr->dev;
-   VOLUME_LABEL VolHdr;
 
    Dmsg5(29, "Enter: ==== open_first_part dev=%s Vol=%s mode=%d num_dvd_parts=%d append=%d\n", dev->print_name(), 
          dev->VolCatInfo.VolCatName, dev->openmode, dev->num_dvd_parts, dev->can_append());
 
 
-   /*              
-    * Note, when we close, the Volume header is zeroed. Since
-    *  we reopen, but are in fact opening the same volume without
-    *  re-reading the Volume header, we simply save and restore it.
-    */
-   memcpy(&VolHdr, &dev->VolHdr, sizeof(VolHdr));
-   dev->close();
-   memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+   dev->close_part(dcr);
 
    Dmsg2(400, "Call dev->open(vol=%s, mode=%d)\n", dcr->VolCatInfo.VolCatName, 
          mode);
@@ -589,16 +579,10 @@ int dvd_open_first_part(DCR *dcr, int mode)
    dev->part = 1;
    dev->part_start = 0;
 
-
-   /* Restore Volume header record */
-   memcpy(&dev->VolHdr, &VolHdr, sizeof(dev->VolHdr));
    if (dev->open(dcr, mode) < 0) {
       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;
@@ -612,25 +596,21 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
    off_t pos;
    char ed1[50], ed2[50];
    
-   Dmsg3(400, "Enter lseek_dev fd=%d part=%d nparts=%d\n", dev->fd,
-      dev->part, dev->num_dvd_parts);
+   Dmsg5(400, "Enter lseek_dev fd=%d off=%s w=%d part=%d nparts=%d\n", dev->fd,
+      edit_int64(offset, ed1), whence, dev->part, dev->num_dvd_parts);
    if (!dev->is_dvd()) { 
       Dmsg0(400, "Using sys lseek\n");
       return lseek(dev->fd, offset, whence);
    }
 
-   /* Return I/O error ... no part */  
-   if (dev->part > dev->num_dvd_parts) {
-      return 0;
-   }
-      
    dcr = (DCR *)dev->attached_dcrs->first();  /* any dcr will do */
    switch(whence) {
    case SEEK_SET:
       Dmsg2(400, "lseek_dev SEEK_SET to %s (part_start=%s)\n",
-         edit_uint64(offset, ed1), edit_uint64(dev->part_start, ed2));
+         edit_int64(offset, ed1), edit_uint64(dev->part_start, ed2));
       if ((uint64_t)offset >= dev->part_start) {
-         if ((uint64_t)offset < dev->part_start+dev->part_size) {
+         if ((uint64_t)offset == dev->part_start || 
+             (uint64_t)offset < dev->part_start+dev->part_size) {
             /* We are staying in the current part, just seek */
             if ((pos = lseek(dev->fd, offset-dev->part_start, SEEK_SET)) < 0) {
                return pos;
@@ -666,20 +646,22 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
       }
       break;
    case SEEK_CUR:
-      Dmsg1(400, "lseek_dev SEEK_CUR to %s\n", edit_uint64(offset, ed1));
+      Dmsg1(400, "lseek_dev SEEK_CUR to %s\n", edit_int64(offset, ed1));
       if ((pos = lseek(dev->fd, (off_t)0, SEEK_CUR)) < 0) {
-         return pos;   
+         Dmsg0(400, "Seek error.\n");
+         return pos;                  
       }
       pos += dev->part_start;
       if (offset == 0) {
          Dmsg1(400, "lseek_dev SEEK_CUR returns %s\n", edit_uint64(pos, ed1));
          return pos;
-      } else { /* Not used in Bacula, but should work */
+      } else { 
+         Dmsg1(400, "do lseek_dev SEEK_SET %s\n", edit_uint64(pos, ed1));
          return lseek_dev(dev, pos, SEEK_SET);
       }
       break;
    case SEEK_END:
-      Dmsg1(400, "lseek_dev SEEK_END to %s\n", edit_uint64(offset, ed1));
+      Dmsg1(400, "lseek_dev SEEK_END to %s\n", edit_int64(offset, ed1));
       /*
        * Bacula does not use offsets for SEEK_END
        *  Also, Bacula uses seek_end only when it wants to
@@ -734,6 +716,7 @@ off_t lseek_dev(DEVICE *dev, off_t offset, int whence)
       }
       break;
    default:
+      Dmsg0(400, "Seek call error.\n");
       errno = EINVAL;
       return -1;
    }
@@ -745,7 +728,8 @@ bool dvd_close_job(DCR *dcr)
    JCR *jcr = dcr->jcr;
    bool ok = true;
 
-   /* If the device is a dvd and WritePartAfterJob
+   /*
+    * If the device is a dvd and WritePartAfterJob
     * is set to yes, open the next part, so, in case of a device
     * that requires mount, it will be written to the device.
     */
@@ -773,8 +757,7 @@ bool truncate_dvd(DCR *dcr)
 {
    DEVICE* dev = dcr->dev;
 
-   dev->close();
-   memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+   dev->close_part(dcr);
 
    if (!unmount_dvd(dev, 1)) {
       Dmsg0(400, "truncate_dvd: Failed to unmount DVD\n");
@@ -806,8 +789,7 @@ bool truncate_dvd(DCR *dcr)
       return false;
    }
    
-   dev->close();
-   memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
+   dev->close_part(dcr);
    
    Dmsg0(400, "truncate_dvd: Opening first part (2)...\n");
    
@@ -858,7 +840,7 @@ bool check_can_write_on_non_blank_dvd(DCR *dcr)
    struct dirent *entry, *result;
    int name_max;
    int count = 0;
-   bool matched = false;
+   bool matched = true;
    struct stat filestat;
       
    name_max = pathconf(".", _PC_NAME_MAX);
@@ -899,7 +881,7 @@ bool check_can_write_on_non_blank_dvd(DCR *dcr)
                   filename.c_str(), be.strerror());
                return false;
             }
-            Dmsg2(99, "check_can_write_on_non_blank_dvd: size of %s is %d\n", 
+            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;
          }