]> git.sur5r.net Git - bacula/bacula/commitdiff
kes If doing a mount, look for a slot, and if specified pass it to
authorKern Sibbald <kern@sibbald.com>
Tue, 15 Aug 2006 20:43:54 +0000 (20:43 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 15 Aug 2006 20:43:54 +0000 (20:43 +0000)
     the SD so that it can load the autochanger.
kes  Return DVD=1 flag if a label command is done to a DVD. This
     permits setting VolParts to 1.
kes  Apply DVD patch from Richard Mortimer <richm@oldelvet.org.uk>, but
     rework ua_label code based on DVD media type to use DVD flag returned.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3286 91ce42f0-d328-0410-95d8-f526ca767f89

18 files changed:
bacula/kernstodo
bacula/scripts/dvd-handler.in
bacula/src/cats/bdb_find.c
bacula/src/dird/protos.h
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_label.c
bacula/src/dird/ua_select.c
bacula/src/lib/edit.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/dircmd.c
bacula/src/stored/dvd.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h
bacula/src/version.h
bacula/technotes-1.39

index 6258919c07cf9fddb45b6e2e5dcefadb746ebdf5..c8774d6921cf6b631002f8b91735ae6f374ecf25 100644 (file)
@@ -1,5 +1,5 @@
                     Kern's ToDo List
-                     30 July 2006
+                     16 August 2006
 
 Major development:      
 Project                     Developer
@@ -1647,3 +1647,5 @@ Block Position: 0
 - Fix auth compatibility with 1.38
 - Update dbcheck to include Log table
 - Update llist to include new fields.
+- Make unmount unload autochanger.  Make mount load slot.
+
index b90108156ead4f0a4626b69c8d61605e81b89f4f..1aa05e842d1b12fcb2d80aae23000e6892c522cf 100644 (file)
@@ -267,6 +267,9 @@ class disk:
       cmd = self.growcmd + self.growparams
       if newvol:
          cmd += " -Z "
+         // Ignore any existing iso9660 filesystem - used for truncate
+         if newvol == 2:
+             cmd += "-use-the-force-luke=tty "
       else:
          cmd += " -M "
       cmd += self.device + " " + str(partfile)
@@ -397,8 +400,9 @@ test      Scan the device and report the information found.
 free      Scan the device and report the available space.
 write     Write a part file to disk.
            This operation needs two additional arguments.
-           The first indicates to append (0) or restart the
-           disk (1). The second is the file to write.
+           The first indicates to append (0), restart the
+           disk (1) or restart existing disk (2). The second
+           is the file to write.
 prepare   Prepare a DVD+/-RW for being used by Bacula.
            Note: This is only useful if you already have some
            non-Bacula data on a medium, and you want to use
index f63a5354dc04f96f154b77ea1b8826b737ada460..a6cce18e9d041ee6a0f1cab867ec863d2708ec2c 100644 (file)
@@ -174,7 +174,7 @@ db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr
 
 bool
 db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr)
-{ return 0; }
+{ return false; }
 
 bool
 db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
index 16a361df71e7f81e78a439d983958fa03fa79406..d7c040fbb245993e35e1cdc0ea3fc177a56dd0e2 100644 (file)
@@ -208,6 +208,7 @@ int     do_prompt(UAContext *ua, const char *automsg, const char *msg, char *pro
 CAT    *get_catalog_resource(UAContext *ua);
 STORE  *get_storage_resource(UAContext *ua, bool use_default);
 int     get_storage_drive(UAContext *ua, STORE *store);
+int     get_storage_slot(UAContext *ua, STORE *store);
 int     get_media_type(UAContext *ua, char *MediaType, int max_media);
 bool    get_pool_dbr(UAContext *ua, POOL_DBR *pr);
 int     get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
index 9869bb281e92c78df6555c2f20cf81dd84f6258b..24828f4a25746b97ab3c8943506551d971677ed2 100644 (file)
@@ -1301,6 +1301,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    JCR *jcr = ua->jcr;
    char dev_name[MAX_NAME_LENGTH];
    int drive;
+   int slot = -1;
 
    if (!open_db(ua)) {
       return;
@@ -1313,6 +1314,9 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    }
    set_wstorage(jcr, store);
    drive = get_storage_drive(ua, store);
+   if (strcmp(command, "mount") == 0) {
+      slot = get_storage_slot(ua, store);
+   }
 
    Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n",
       store->media_type, store->dev_name(), drive);
@@ -1324,7 +1328,11 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    sd = jcr->store_bsock;
    bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
    bash_spaces(dev_name);
-   bnet_fsend(sd, "%s %s drive=%d", command, dev_name, drive);
+   if (slot > 0) {
+      bnet_fsend(sd, "%s %s drive=%d slot=%d", command, dev_name, drive, slot);
+   } else {
+      bnet_fsend(sd, "%s %s drive=%d", command, dev_name, drive);
+   }
    while (bnet_recv(sd) >= 0) {
       bsendmsg(ua, "%s", sd->msg);
    }
@@ -1334,7 +1342,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
 }
 
 /*
- * mount [storage=<name>] [drive=nn]
+ * mount [storage=<name>] [drive=nn] [slot=mm]
  */
 static int mount_cmd(UAContext *ua, const char *cmd)
 {
index 86a5b02843a4a86135e929767a722867e47556e8..c7d546f4b56b771165b9f0cb470f513ab22732df 100644 (file)
@@ -629,6 +629,7 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
    BSOCK *sd;
    char dev_name[MAX_NAME_LENGTH];
    bool ok = false;
+   bool is_dvd = false;
 
    if (!(sd=open_sd_bsock(ua))) {
       return false;
@@ -662,12 +663,20 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr,
       if (strncmp(sd->msg, "3000 OK label.", 14) == 0) {
          ok = true;
       }
+      if (strncmp(sd->msg, "3000 OK label. DVD=1 ", 21) == 0) {
+         is_dvd = true;
+      }
    }
    unbash_spaces(mr->VolumeName);
    unbash_spaces(mr->MediaType);
    unbash_spaces(pr->Name);
    mr->LabelDate = time(NULL);
    mr->set_label_date = true;
+   if (is_dvd) {
+      /* We know that a freshly labelled DVD has 1 VolParts */
+      /* This does not apply to auto-labelled DVDs. */
+      mr->VolParts = 1;
+   }
    if (ok) {
       if (media_record_exists) {      /* we update it */
          mr->VolBytes = 1;
index 6fbfb84d033025fcb8e4c3d90ea2ea36ed4cad09..b12517f4f9baa9acccd09bdf559b4289d6e233cc 100644 (file)
@@ -907,6 +907,27 @@ int get_storage_drive(UAContext *ua, STORE *store)
    return drive;
 }
 
+/* Get slot that we are working with for this storage */
+int get_storage_slot(UAContext *ua, STORE *store)
+{
+   int i, slot = -1;
+   /* Get slot for autochanger if possible */
+   i = find_arg_with_value(ua, "slot");
+   if (i >=0) {
+      slot = atoi(ua->argv[i]);
+   } else if (store && store->autochanger) {
+      /* Ask user to enter slot number */
+      ua->cmd[0] = 0;
+      if (!get_cmd(ua, _("Enter autochanger slot: "))) {
+         slot = -1;  /* None */
+      } else {
+         slot = atoi(ua->cmd);
+      }
+   }
+   return slot;
+}
+
+
 
 /*
  * Scan looking for mediatype=
index c0e5d0523d5c2bd22ca9233d209a16ccec9b4a11..bc07ad74ee1e84da320df3692910aaa9e78f3f3e 100644 (file)
@@ -6,7 +6,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2002-2005 Kern Sibbald
+   Copyright (C) 2002-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
index 9eabe54198d3cdb946a509192cdf50a0f67b65ef..6fe9210bad5a81635c8974c9cb98a27caf72405d 100644 (file)
@@ -373,7 +373,7 @@ static void labelcmd()
       }
    }
    dev->rewind(dcr);
-   write_new_volume_label_to_dev(dcr, cmd, "Default");
+   write_new_volume_label_to_dev(dcr, cmd, "Default", true /* label dvd now */);
    Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
 }
 
index f394db043dae593505cc2f9a38bfe1a7f3980d7c..9dfaa307d0214efe691d028af1c22e9cf492af6d 100644 (file)
@@ -504,6 +504,8 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
       file_size = 0;
    }
    part_size = 0;
+   // Clear any previous truncated_dvd status - we will recalculate it here
+   truncated_dvd = false;
 
    Dmsg2(99, "open_dvd_device: num_parts=%d, VolCatInfo.VolCatParts=%d\n",
       dcr->dev->num_parts, dcr->VolCatInfo.VolCatParts);
@@ -525,6 +527,7 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
             clear_opened();
             return;
          }
+         truncated_dvd = true;
       }
    } else {
       /* We cannot mount the device */
@@ -576,16 +579,21 @@ void DEVICE::open_dvd_device(DCR *dcr, int omode)
       berrno be;
       Mmsg2(errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(), 
             be.strerror());
+      // Should this be set if we try the create/open below
       dev_errno = EIO; /* Interpreted as no device present by acquire.c:acquire_device_for_read(). */
       Dmsg1(29, "open failed: %s", errmsg);
       
-      if ((omode == OPEN_READ_ONLY) && (part == num_parts)) {
-         /* If the last part (on spool), doesn't exists when reading, create it and read from it
-          * (it will report immediately an EOF):
+      if ((omode == OPEN_READ_ONLY || omode == OPEN_READ_WRITE) &&
+          (part == num_parts)) {
+         /* If the last part (on spool), doesn't exists 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. */
-         set_mode(OPEN_READ_WRITE);
+         Dmsg0(29, "Creating last part on spool to make our caller happy\n");
+         set_mode(CREATE_READ_WRITE);
          fd = ::open(archive_name.c_str(), mode, 0640);
-         set_mode(OPEN_READ_ONLY);
+         set_mode(omode);
       }
       
       /* We don't need it. Only the last part is on spool */
@@ -2002,7 +2010,11 @@ void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg)
             break;
          case 'e':
             if (num_parts == 0) {
-               str = "1";
+               if (truncating || truncated_dvd) {
+                  str = "2";
+               } else {
+                  str = "1";
+               }
             } else {
                str = "0";
             }
index 929726b7b8e1fb67244341d1992e2e8b29d8317d..4f2068ee159fffa5bb938126de225372fce084f7 100644 (file)
@@ -246,6 +246,7 @@ public:
    uint64_t free_space;               /* current free space on medium (without the current part) */
    int free_space_errno;              /* indicates errno getting freespace */
    bool truncating;                   /* if set, we are currently truncating the DVD */
+   bool truncated_dvd;                /* if set, we have a truncated DVD in the drive */
    
    
    utime_t  vol_poll_interval;        /* interval between polling Vol mount */
index 1243e24eea104b5dc2c3b4f7be2dd76d56e0041d..7a22f56521a2b83a946c47a13e7f0366c4692280 100644 (file)
@@ -209,7 +209,7 @@ void *handle_connection_request(void *arg)
            Dmsg1(200, "Do command: %s\n", cmds[i].cmd);
            if (!cmds[i].func(jcr)) { /* do command */
               quit = true; /* error, get out */
-              Dmsg1(190, "Command %s requsts quit\n", cmds[i].cmd);
+              Dmsg1(190, "Command %s reqeusts quit\n", cmds[i].cmd);
            }
            found = true;             /* indicate command found */
            break;
@@ -396,7 +396,12 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
    Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
 
-   if (!try_autoload_device(dcr->jcr, slot, newname)) {
+   Dmsg0(90, "try_autoload_device - looking for volume_info\n");
+   if (relabel && dev->is_dvd()) {
+      dcr->VolCatInfo.VolCatParts=1;
+   }
+
+   if (!try_autoload_device(dcr->jcr, slot, (relabel == 0) ? newname : oldname)) {
       goto bail_out;                  /* error */
    }
 
@@ -409,7 +414,7 @@ static void label_volume_if_ok(DCR *dcr, char *oldname,
    if (dev->open(dcr, mode) < 0) {
       bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
          dev->print_name(), dev->strerror());
-      return;      
+      goto bail_out;      
    }
 
    /* See what we have for a Volume */
@@ -436,18 +441,26 @@ 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()) {
+         /* Change the partition file name */
+         bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
+         if (!dev->truncate(dcr)) {
+            bnet_fsend(dir, _("3912 Failed to truncate previous DVD volume.\n"));
+            break;
+         }
+      }
       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)) {
+      if (!write_new_volume_label_to_dev(dcr, newname, poolname, true /* write dvd now */)) {
          bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
          break;
       }
       bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
       /* The following 3000 OK label. string is scanned in ua_label.c */
-      bnet_fsend(dir, "3000 OK label. Volume=%s Device=%s\n",
-         newname, dev->print_name());
+      bnet_fsend(dir, "3000 OK label. DVD=%d Volume=\"%s\" Device=\"%s\"\n",
+         dev->is_dvd()?1:0, newname, dev->print_name());
       break;
    case VOL_NO_MEDIA:
       bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror());
@@ -582,8 +595,15 @@ static bool mount_cmd(JCR *jcr)
    DEVICE *dev;
    DCR *dcr;
    int drive;
+   int slot = 0;
+   bool ok;
 
-   if (sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2) {
+   ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(), 
+               &drive, &slot) == 3;
+   if (!ok) {
+      ok = sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2;
+   }
+   if (ok) {
       dcr = find_device(jcr, devname, drive);
       if (dcr) {
          dev = dcr->dev;
@@ -603,6 +623,9 @@ static bool mount_cmd(JCR *jcr)
          /* In both of these two cases, we (the user) unmounted the Volume */
          case BST_UNMOUNTED_WAITING_FOR_SYSOP:
          case BST_UNMOUNTED:
+            if (dev->is_autochanger() && slot > 0) {
+               try_autoload_device(jcr, slot, "");
+            }
             /* We freed the device, so reopen it and wake any waiting threads */
             if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
                bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
@@ -647,6 +670,9 @@ static bool mount_cmd(JCR *jcr)
             break;
 
          case BST_NOT_BLOCKED:
+            if (dev->is_autochanger() && slot > 0) {
+               try_autoload_device(jcr, slot, "");
+            }
             if (dev->is_open()) {
                if (dev->is_labeled()) {
                   bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
@@ -722,19 +748,31 @@ static bool unmount_cmd(JCR *jcr)
             if (!dev->is_busy()) {
                unload_autochanger(jcr->dcr, -1);          
             }
-            Dmsg0(90, "Device already unmounted\n");
-            bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
-               dev->print_name());
-
+            if (dev->is_dvd()) {
+               if (unmount_dvd(dev, 0)) {
+                  bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
+                     dev->print_name());
+               } else {
+                  bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
+               } 
+            } else {
+               Dmsg0(90, "Device already unmounted\n");
+               bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), 
+                  dev->print_name());
+            }
          } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) {
             Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting,
                dev->dev_blocked);
             if (!unload_autochanger(jcr->dcr, -1)) {
                dev->close();
             }
-            dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
-            bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
-               dev->print_name());
+            if (dev->is_dvd() && !unmount_dvd(dev, 0)) {
+               bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
+            } else {
+               dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP;
+               bnet_fsend(dir, _("3001 Device %s unmounted.\n"), 
+                  dev->print_name());
+            }
 
          } else if (dev->dev_blocked == BST_DOING_ACQUIRE) {
             bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), 
@@ -759,8 +797,12 @@ static bool unmount_cmd(JCR *jcr)
             if (!unload_autochanger(jcr->dcr, -1)) {
                dev->close();
             }
-            bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
-               dev->print_name());
+            if (dev->is_dvd() && !unmount_dvd(dev, 0)) {
+               bnet_fsend(dir, _("3907 %s"), dev->bstrerror());
+            } else {
+               bnet_fsend(dir, _("3002 Device %s unmounted.\n"), 
+                  dev->print_name());
+            }
          }
          V(dev->mutex);
          free_dcr(dcr);
index 828425691106fb5cf6cb87db20df1e0287a9bdf2..bc50a59a2442275e1bc6ee13ca19f5bfe2bac132 100644 (file)
@@ -138,7 +138,10 @@ static bool do_mount_dvd(DEVICE* dev, int mount, int dotimeout)
    while ((status = run_program_full_output(ocmd.c_str(), 
                        dev->max_open_wait/2, results)) != 0) {
       /* Doesn't work with internationalisation (This is not a problem) */
-      if (fnmatch("*is already mounted on", results, 0) == 0) {
+      if (mount && fnmatch("*is already mounted on*", results, 0) == 0) {
+         break;
+      }
+      if (!mount && fnmatch("* not mounted*", results, 0) == 0) {
          break;
       }
       if (timeout-- > 0) {
@@ -151,9 +154,10 @@ static bool do_mount_dvd(DEVICE* dev, int mount, int dotimeout)
          bmicrosleep(1, 0);
          continue;
       }
-      Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->print_name(), results);
-      Mmsg(dev->errmsg, _("Device %s cannot be mounted. ERR=%s\n"), 
-           dev->print_name(), results);
+      Dmsg3(40, "Device %s cannot be %smounted. ERR=%s\n", dev->print_name(),
+           (mount ? "" : "un"), results);
+      Mmsg(dev->errmsg, _("Device %s cannot be %smounted. ERR=%s\n"), 
+           dev->print_name(), (mount ? "" : "un"), results);
       /*
        * Now, just to be sure it is not mounted, try to read the
        *  filesystem.
@@ -201,8 +205,17 @@ static bool do_mount_dvd(DEVICE* dev, int mount, int dotimeout)
       Dmsg1(29, "do_mount_dvd: got %d files in the mount point (not counting ., .. and .keep)\n", count);
       
       if (count > 0) {
-         mount = 1;                      /* If we got more than ., .. and .keep */
-         break;                          /*   there must be something mounted */
+         /* If we got more than ., .. and .keep */
+         /*   there must be something mounted */
+         if (mount) {
+            break;
+         } else {
+            /* An unmount request. We failed to unmount - report an error */
+            dev->set_mounted(true);
+            free_pool_memory(results);
+            Dmsg0(200, "============ DVD mount=1\n");
+            return false;
+         }
       }
 get_out:
       dev->set_mounted(false);
@@ -375,10 +388,11 @@ bool dvd_write_part(DCR *dcr)
    Dmsg2(29, "dvd_write_part: cmd=%s timeout=%d\n", ocmd.c_str(), timeout);
       
    status = run_program_full_output(ocmd.c_str(), timeout, results.c_str());
+   dev->truncated_dvd = false; // Clear this status now write has finished
    if (status != 0) {
       Mmsg1(dev->errmsg, _("Error while writing current part to the DVD: %s"), 
             results.c_str());
-      Dmsg1(000, "%s", dev->errmsg);
+      Dmsg1(000, "%s\n", dev->errmsg);
       dev->dev_errno = EIO;
       mark_volume_in_error(dcr);
       sm_check(__FILE__, __LINE__, false);
@@ -716,6 +730,17 @@ bool dvd_close_job(DCR *dcr)
 bool truncate_dvd(DCR *dcr) {
    DEVICE* dev = dcr->dev;
 
+   if (dev->fd >= 0) {
+      close(dev->fd);
+   }
+   dev->fd = -1;
+   dev->clear_opened();
+
+   if (!unmount_dvd(dev, 1)) {
+      Dmsg0(400, "truncate_dvd: Failed to unmount DVD\n");
+      return false;
+   }
+
    /* Set num_parts to zero (on disk) */
    dev->num_parts = 0;
    dcr->VolCatInfo.VolCatParts = 0;
@@ -724,12 +749,11 @@ bool truncate_dvd(DCR *dcr) {
    Dmsg0(400, "truncate_dvd: Opening first part (1)...\n");
    
    dev->truncating = true;
-   if (dvd_open_first_part(dcr, OPEN_READ_WRITE) < 0) {
+   if (dvd_open_first_part(dcr, CREATE_READ_WRITE) < 0) {
       Dmsg0(400, "truncate_dvd: Error while opening first part (1).\n");
       dev->truncating = false;
       return false;
    }
-   dev->truncating = false;
 
    Dmsg0(400, "truncate_dvd: Truncating...\n");
 
@@ -738,6 +762,7 @@ bool truncate_dvd(DCR *dcr) {
       berrno be;
       Mmsg2(dev->errmsg, _("Unable to truncate device %s. ERR=%s\n"), 
          dev->print_name(), be.strerror());
+      dev->truncating = false;
       return false;
    }
    
@@ -749,8 +774,10 @@ bool truncate_dvd(DCR *dcr) {
    
    if (!dvd_write_part(dcr)) {
       Dmsg0(400, "truncate_dvd: Error while writing to DVD.\n");
+      dev->truncating = false;
       return false;
    }
+   dev->truncating = false;
    
    /* Set num_parts to zero (on disk) */
    dev->num_parts = 0;
index 030a7ca2c2af62900b0000eee23d12e06033bc01..4959d55268e1b87d168f5929d83069c29981332e 100644 (file)
@@ -163,6 +163,7 @@ int read_dev_volume_label(DCR *dcr)
          empty_block(block);
          return VOL_OK;
       }
+      Dmsg0(100, "No volume label - bailing out\n");
       stat = VOL_NO_LABEL;
       goto bail_out;
    }
@@ -288,7 +289,8 @@ 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 write_new_volume_label_to_dev(DCR *dcr, const char *VolName, 
+                                   const char *PoolName, bool dvdnow)
 {
    DEVICE *dev = dcr->dev;
 
@@ -312,8 +314,8 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
       }
    }
 
-   /* Create PRE_LABEL */
-   create_volume_label(dev, VolName, PoolName);
+   /* Create PRE_LABEL or VOL_LABEL if DVD */
+   create_volume_label(dev, VolName, PoolName, dvdnow);
 
    /*
     * If we have already detected an ANSI label, re-read it
@@ -346,6 +348,15 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
       Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror());
       goto bail_out;
    }
+
+   /* Now commit block to DVD if we should write now */
+   if (dev->is_dvd() && dvdnow) {
+      if (!dvd_write_part(dcr)) {
+         Dmsg2(30, "Bad DVD write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror());
+         goto bail_out;
+      }
+   }
+
    Dmsg0(99, " Wrote block to device\n");
 
    if (dev->weof(1)) {
@@ -541,7 +552,8 @@ static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec)
 /*
  * Create a volume label in memory
  */
-void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName)
+void create_volume_label(DEVICE *dev, const char *VolName, 
+                         const char *PoolName, bool dvdnow)
 {
    DEVRES *device = (DEVRES *)dev->device;
 
@@ -554,7 +566,12 @@ void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName)
 
    bstrncpy(dev->VolHdr.Id, BaculaId, sizeof(dev->VolHdr.Id));
    dev->VolHdr.VerNum = BaculaTapeVersion;
-   dev->VolHdr.LabelType = PRE_LABEL;  /* Mark tape as unused */
+   if (dev->is_dvd() && dvdnow) {
+      /* We do not want to re-label a DVD so write VOL_LABEL now */
+      dev->VolHdr.LabelType = VOL_LABEL;
+   } else {
+      dev->VolHdr.LabelType = PRE_LABEL;  /* Mark tape as unused */
+   }
    bstrncpy(dev->VolHdr.VolumeName, VolName, sizeof(dev->VolHdr.VolumeName));
    bstrncpy(dev->VolHdr.PoolName, PoolName, sizeof(dev->VolHdr.PoolName));
    bstrncpy(dev->VolHdr.MediaType, device->media_type, sizeof(dev->VolHdr.MediaType));
index 8b86db484be6ff9e20f644f6155960e68700a10a..83494eb715fd0748a3a3066f6e0218856e810342 100644 (file)
@@ -194,7 +194,7 @@ read_volume:
     */
    if (dev->has_cap(CAP_STREAM)) {
       vol_label_status = VOL_OK;
-      create_volume_label(dev, dcr->VolumeName, "Default");
+      create_volume_label(dev, dcr->VolumeName, "Default", false /* not DVD */);
       dev->VolHdr.LabelType = PRE_LABEL;
    } else {
       vol_label_status = read_dev_volume_label(dcr);
@@ -421,7 +421,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)) {
+             dcr->pool_name, false /* defer DVD label */)) {
          Dmsg0(150, "!write_vol_label\n");
          mark_volume_in_error(dcr);
          return try_next_vol;
index 1b92dc0e945592ae652fbf33200c3df9566158dc..269ba46011c9454dbe603ab49f74048a70e21c39 100644 (file)
@@ -153,8 +153,8 @@ void     handle_filed_connection(BSOCK *fd, char *job_name);
 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     write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
+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);
 #define ANSI_VOL_LABEL 0
 #define ANSI_EOF_LABEL 1
 #define ANSI_EOV_LABEL 2
index e29b19d39e7a6c9ce871177b3bda9ac6359142e4..e92980678555886eb70f291a9a6ef2929039fa37 100644 (file)
@@ -3,9 +3,9 @@
  */
 
 #undef  VERSION
-#define VERSION "1.39.19"
-#define BDATE   "15 August 2006"
-#define LSMDATE "15Aug06"
+#define VERSION "1.39.20"
+#define BDATE   "16 August 2006"
+#define LSMDATE "16Aug06"
 #define BYEAR "2006"       /* year for copyright messages in progs */
 
 /* Debug flags */
index a81bb4f30b0a3b4bbfdaa414a80bec09e533f789..117310cf7f7687d413d3b38707abb407e1c125f7 100644 (file)
@@ -1,6 +1,13 @@
               Technical notes on version 1.39  
 
 General:
+16Aug06
+kes  If doing a mount, look for a slot, and if specified pass it to
+     the SD so that it can load the autochanger.
+kes  Return DVD=1 flag if a label command is done to a DVD. This
+     permits setting VolParts to 1.
+kes  Apply DVD patch from Richard Mortimer <richm@oldelvet.org.uk>, but
+     rework ua_label code based on DVD media type to use DVD flag returned.
 15Aug06
 kes  Eliminate some compile warnings in dird_conf.c
 kes  Format the bytes field in the terminated jobs part of the status