]> git.sur5r.net Git - bacula/bacula/commitdiff
- Add code to ensure that reserved but unused volumes
authorKern Sibbald <kern@sibbald.com>
Tue, 5 Jul 2005 19:02:19 +0000 (19:02 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 5 Jul 2005 19:02:19 +0000 (19:02 +0000)
  are freed.
- Correct how Volumes are mounted and handled so that the SD
  does not get stuck if multiple volumes are used (recycling,
  relabling, ...)
- Correct bug where you could relabel a volume while it
  was being acquired -- created chaos.

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

23 files changed:
bacula/kernstodo
bacula/kes-1.37
bacula/src/lib/bnet.c
bacula/src/lib/btimers.c
bacula/src/stored/acquire.c
bacula/src/stored/ansi_label.c
bacula/src/stored/askdir.c
bacula/src/stored/bcopy.c
bacula/src/stored/bextract.c
bacula/src/stored/block.c
bacula/src/stored/bls.c
bacula/src/stored/bscan.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/dircmd.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h
bacula/src/stored/reserve.c
bacula/src/stored/wait.c
bacula/src/version.h

index 0987d224dd26ccaea41020825c6982e30d2b3b41..4b44aa49317dddb95bf3bb7af4618e4b763fc723 100644 (file)
@@ -23,6 +23,7 @@ Autochangers:
      all Volumes from other drives.  "update slots all-drives"?
 
 For 1.37:
+- update volume=xxx --- add status=Full
 - After rename
   04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume 
      "DLT-13Feb04".
index 0a2d597748516b10f8b5692743ba26411f90d7d0..dd12b3177c8f194da591b1b14fac5c258e9cdd0c 100644 (file)
@@ -4,6 +4,14 @@
 General:
 
 Changes to 1.37.28:
+05Jul05
+- Add code to ensure that reserved but unused volumes
+  are freed. 
+- Correct how Volumes are mounted and handled so that the SD
+  does not get stuck if multiple volumes are used (recycling,
+  relabling, ...)
+- Correct bug where you could relabel a volume while it
+  was being acquired -- created chaos.
 04Jul05
 - Correct seg fault caused by open() calling sequence change.
 03Jul05
index 79c337692f4a65d8e27b9cf4bd121af95ee75aaa..7af71868f183305b274d240b845c60a8bd64477a 100644 (file)
@@ -956,7 +956,7 @@ bool bnet_set_buffer_size(BSOCK * bs, uint32_t size, int rw)
          Qmsg1(bs->jcr, M_ERROR, 0, _("sockopt error: %s\n"), be.strerror());
          dbuf_size -= TAPE_BSIZE;
       }
-      Dmsg1(200, "set network buffer size=%d\n", dbuf_size);
+      Dmsg1(900, "set network buffer size=%d\n", dbuf_size);
       if (dbuf_size != start_size) {
          Qmsg1(bs->jcr, M_WARNING, 0,
                _("Warning network buffer = %d bytes not max size.\n"), dbuf_size);
index 6578f7efc143fd6e93662ed8e13b57732f2a6e18..fcb0b3540c8d4be8ecae87a3682dab765d9abb97 100644 (file)
@@ -160,7 +160,7 @@ btimer_t *start_bsock_timer(BSOCK *bsock, uint32_t wait)
    wid->wd->interval = wait;
    register_watchdog(wid->wd);
 
-   Dmsg4(50, "Start bsock timer %p tid=%p for %d secs at %d\n", wid,
+   Dmsg4(950, "Start bsock timer %p tid=%p for %d secs at %d\n", wid,
          wid->tid, wait, time(NULL));
 
    return wid;
@@ -175,7 +175,7 @@ void stop_bsock_timer(btimer_t *wid)
       Dmsg0(900, "stop_bsock_timer called with NULL btimer_id\n");
       return;
    }
-   Dmsg3(50, "Stop bsock timer %p tid=%p at %d.\n", wid, wid->tid, time(NULL));
+   Dmsg3(950, "Stop bsock timer %p tid=%p at %d.\n", wid, wid->tid, time(NULL));
    stop_btimer(wid);
 }
 
index d5d753debd8fa5e8c86391b5683ccf8fb18bedc8..9b205b97418b1ae784b93b035773200dd0230215 100644 (file)
@@ -115,6 +115,7 @@ void free_dcr(DCR *dcr)
    if (dcr->jcr) {
       dcr->jcr->dcr = NULL;
    }
+   free_unused_volume(dcr);           /* free unused vols attached to this dcr */
    free(dcr);
 }
 
@@ -336,12 +337,20 @@ DCR *acquire_device_for_append(DCR *dcr)
        *   OK if next volume matches current volume
        *   otherwise mount desired volume obtained from
        *    dir_find_next_appendable_volume
+       *  dev->VolHdr.VolumeName is what is in the drive
+       *  dcr->VolumeName is what we pass into the routines, or
+       *    get back from the subroutines.
        */
       bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
           !(dir_find_next_appendable_volume(dcr) &&
             strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
-         Dmsg0(190, "Wrong tape mounted.\n");
+         Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
+            dcr->VolumeName);
+         /* Release volume reserved by dir_find_next_appendable_volume() */
+         if (dcr->VolumeName[0]) {
+            free_unused_volume(dcr);
+         }
          if (dev->num_writers != 0 || dev->reserved_device) {
             Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
             goto get_out;
@@ -367,7 +376,7 @@ DCR *acquire_device_for_append(DCR *dcr)
           if (dev->num_writers == 0) {
              memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
           }
-       }
+      }
    } else {
       /* Not already in append mode, so mount the device */
       Dmsg0(190, "Not in append mode, try mount.\n");
index c87f2d484fe064272fcfef845bfe505dbbdd09dd..f0eed69f51f451dcd46ad7609b1ad6218f6b3a61 100644 (file)
@@ -127,7 +127,7 @@ int read_ansi_ibm_label(DCR *dcr)
                   *q++ = *p++;
                }
                *q = 0;
-               new_volume(dev->VolHdr.VolumeName, dev);
+               new_volume(dcr, dev->VolHdr.VolumeName);
                Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
                Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolumeName);
                return VOL_NAME_ERROR;
index 0fa4699c764a9d5649b41d960186d247fd7519a9..8578711d7d00f011138defe328df660863002cb8 100644 (file)
@@ -258,9 +258,10 @@ bool dir_find_next_appendable_volume(DCR *dcr)
     }
     if (found) {
        Dmsg0(400, "dir_find_next_appendable_volume return true\n");
-       new_volume(dcr->VolumeName, NULL);   /* reserve volume */
+       new_volume(dcr, dcr->VolumeName);   /* reserve volume */
        return true;
     }
+    dcr->VolumeName[0] = 0;
     return false;
 }
 
@@ -427,8 +428,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
       }
       /* First pass, we *know* there are no appendable volumes, so no need to call */
       if (!first && dir_find_next_appendable_volume(dcr)) { /* get suggested volume */
-         unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                     (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+         unmounted = is_device_unmounted(dev);
          /*
           * If we have a valid volume name and we are not
           *   removable media, return now, or if we have a
@@ -510,8 +510,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
          init_device_wait_timers(dcr);
          continue;
       }
-      unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                  (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+      unmounted = is_device_unmounted(dev);
       if (unmounted) {
          continue;                    /* continue to wait */
       }
@@ -573,7 +572,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr)
       stat = wait_for_sysop(dcr);    ;     /* wait on device */
       if (dev->poll) {
          Dmsg1(400, "Poll timeout in mount vol on device %s\n", dev->print_name());
-         Dmsg1(400, "Blocked=%s\n", edit_blocked_reason(dev));
+         Dmsg1(400, "Blocked=%s\n", dev->print_blocked());
          return true;
       }
 
index 1897cf6dc609874083eeb141ae740fb6481b8f96..e508a48f9a43e8bc3dfef50863973ffb2149c442 100644 (file)
@@ -275,8 +275,9 @@ bool    dir_create_jobmedia_record(DCR *dcr) { return 1; }
 bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
-VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; }
+VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
 bool    free_volume(DEVICE *dev) { return true; }
+void    free_unused_volume(DCR *dcr) { }
 
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
index 6e6c9d881704c85f182d831d7462c29977c1ad1d..bcc3f2401255248d583090499593f8a88f159f1b 100644 (file)
@@ -458,8 +458,9 @@ bool    dir_create_jobmedia_record(DCR *dcr) { return 1; }
 bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
-VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; }
+VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
 bool    free_volume(DEVICE *dev) { return true; }
+void    free_unused_volume(DCR *dcr) { }
 
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
index 56b7bd54f64a423a61e5f3caa71c7b4e1ca8a220..976f5a54a401a34d3ef059ef37a1b501eb2bb4d4 100644 (file)
@@ -117,7 +117,7 @@ DEV_BLOCK *new_block(DEVICE *dev)
    block->buf = get_memory(block->buf_len);
    empty_block(block);
    block->BlockVer = BLOCK_VER;       /* default write version */
-   Dmsg1(350, "Returning new block=%x\n", block);
+   Dmsg1(650, "Returning new block=%x\n", block);
    return block;
 }
 
index 58a9cefd616295357976d6f1964a31857980709f..d6009b3aaa542152bd3814026bd91a376126e3ec 100644 (file)
@@ -429,8 +429,9 @@ bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
 int     generate_job_event(JCR *jcr, const char *event) { return 1; }
-VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; }
+VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
 bool    free_volume(DEVICE *dev) { return true; }
+void    free_unused_volume(DCR *dcr) { }
        
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
index 92a1fd0bf00bbc9ad3cd63498e3a91f71b904960..8de282c633b7392e41a9e6a305f30f3e94ee620a 100644 (file)
@@ -1200,8 +1200,9 @@ bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
 int     generate_job_event(JCR *jcr, const char *event) { return 1; }
-VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; }
+VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
 bool    free_volume(DEVICE *dev) { return true; }
+void    free_unused_volume(DCR *dcr) { }
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
 {
index 94ecfb312e7cd640bf1e13b554571cf4bac22b8c..92582eafee45090bea208792b7b37e745fa8de41 100644 (file)
@@ -2717,5 +2717,6 @@ static void set_volume_name(const char *VolName, int volnum)
    dcr->VolCatInfo.Slot = volnum;
 }
 
-VOLRES *new_volume(const char *VolumeName, DEVICE *dev) { return NULL; }
+VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
 bool    free_volume(DEVICE *dev) { return true; }
+void    free_unused_volume(DCR *dcr) { }
index 1484edcf66ff2b736a1999573fba12d7f94193b8..ebdd6779bd7be97913d28b06837f2ac1b03eca8e 100644 (file)
@@ -633,6 +633,28 @@ void DEVICE::unblock()
    V(mutex);
 }
 
+const char *DEVICE::print_blocked() const 
+{
+   switch (dev_blocked) {
+   case BST_NOT_BLOCKED:
+      return "BST_NOT_BLOCKED";
+   case BST_UNMOUNTED:
+      return "BST_UNMOUNTED";
+   case BST_WAITING_FOR_SYSOP:
+      return "BST_WAITING_FOR_SYSOP";
+   case BST_DOING_ACQUIRE:
+      return "BST_DOING_ACQUIRE";
+   case BST_WRITING_LABEL:
+      return "BST_WRITING_LABEL";
+   case BST_UNMOUNTED_WAITING_FOR_SYSOP:
+      return "BST_UNMOUNTED_WAITING_FOR_SYSOP";
+   case BST_MOUNT:
+      return "BST_MOUNT";
+   default:
+      return "unknown blocked code";
+   }
+}
+
 /*
  * Called to indicate that we have just read an
  *  EOF from the device.
index 9f1114842b6508002378200540454e5c7eb68cab..19a9599a99dc07420ed2b5ad2411c1aac762379e 100644 (file)
@@ -262,7 +262,7 @@ public:
    int is_mounted() const { return state & ST_MOUNTED; }
    int have_media() const { return state & ST_MEDIA; }
    int is_short_block() const { return state & ST_SHORT; }
-   int is_busy() const { return state & ST_READ || num_writers || reserved_device; }
+   int is_busy() const { return (state & ST_READ) || num_writers || reserved_device; }
    int at_eof() const { return state & ST_EOF; }
    int at_eot() const { return state & ST_EOT; }
    int at_weot() const { return state & ST_WEOT; }
@@ -323,6 +323,8 @@ public:
 
    void set_blocked(int block) { dev_blocked = block; };
    int  get_blocked() const { return dev_blocked; };
+   const char *print_blocked() const; /* in dev.c */
+   bool is_blocked() const { return dev_blocked != BST_NOT_BLOCKED; };
 };
 
 /* Note, these return int not bool! */
@@ -380,6 +382,7 @@ public:
    dlink link;
    char *vol_name;
    DEVICE *dev;
+   DCR *dcr;
 };
 
 
index f5d53743c50b81c69a54cb4a342a574077778800..7a66f618f407cac09373f926cd7621958cc78e7d 100644 (file)
@@ -379,7 +379,7 @@ void _lock_device(const char *file, int line, DEVICE *dev)
 /*
  * Check if the device is blocked or not
  */
-bool device_is_unmounted(DEVICE *dev)
+bool is_device_unmounted(DEVICE *dev)
 {
    bool stat;
    int blocked = dev->dev_blocked;
@@ -388,28 +388,6 @@ bool device_is_unmounted(DEVICE *dev)
    return stat;
 }
 
-const char *edit_blocked_reason(DEVICE *dev)
-{
-   switch (dev->dev_blocked) {
-   case BST_NOT_BLOCKED:
-      return "not blocked";
-   case BST_UNMOUNTED:
-      return "user unmounted device";
-   case BST_WAITING_FOR_SYSOP:
-      return "waiting for operator action";
-   case BST_DOING_ACQUIRE:
-      return "opening, validating, or positioning tape";
-   case BST_WRITING_LABEL:
-      return "labeling tape";
-   case BST_UNMOUNTED_WAITING_FOR_SYSOP:
-      return "closed by user during mount request";
-   case BST_MOUNT:
-      return "mount request";
-   default:
-      return "unknown blocked code";
-   }
-}
-
 void _unlock_device(const char *file, int line, DEVICE *dev)
 {
    Dmsg2(500, "unlock from %s:%d\n", file, line);
@@ -439,7 +417,7 @@ void _block_device(const char *file, int line, DEVICE *dev, int state)
  */
 void _unblock_device(const char *file, int line, DEVICE *dev)
 {
-   Dmsg3(500, "unblock %d from %s:%d\n", dev->dev_blocked, file, line);
+   Dmsg3(500, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
    ASSERT(dev->dev_blocked);
    dev->set_blocked(BST_NOT_BLOCKED);
    dev->no_wait_id = 0;
@@ -454,12 +432,14 @@ void _unblock_device(const char *file, int line, DEVICE *dev)
  */
 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
 {
-   Dmsg4(500, "steal lock. old=%d new=%d from %s:%d\n", dev->dev_blocked, state,
+
+   Dmsg3(400, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
       file, line);
    hold->dev_blocked = dev->get_blocked();
    hold->dev_prev_blocked = dev->dev_prev_blocked;
    hold->no_wait_id = dev->no_wait_id;
    dev->set_blocked(state);
+   Dmsg1(400, "steal lock. new=%s\n", dev->print_blocked());
    dev->no_wait_id = pthread_self();
    V(dev->mutex);
 }
@@ -470,13 +450,15 @@ void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *
  */
 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
 {
-   Dmsg4(500, "return lock. old=%d new=%d from %s:%d\n",
-      dev->dev_blocked, hold->dev_blocked, file, line);
+   Dmsg3(400, "return lock. old=%s from %s:%d\n",
+      dev->print_blocked(), file, line);
    P(dev->mutex);
    dev->dev_blocked = hold->dev_blocked;
    dev->dev_prev_blocked = hold->dev_prev_blocked;
    dev->no_wait_id = hold->no_wait_id;
-   if (dev->dev_blocked == BST_NOT_BLOCKED && dev->num_waiting > 0) {
+   Dmsg1(400, "return lock. new=%s\n", dev->print_blocked());
+   if (dev->num_waiting > 0) {
+      Dmsg0(400, "Broadcase\n");
       pthread_cond_broadcast(&dev->wait); /* wake them up */
    }
 }
index 0c4d2f95b554ef777692721357b04c616805f69c..ecc2b14402b3395426bba18592e7b4593dad9f98 100644 (file)
@@ -326,17 +326,19 @@ static bool do_label(JCR *jcr, int relabel)
       unbash_spaces(mtype);
       dev = find_device(jcr, dev_name);
       if (dev) {
-         /******FIXME**** compare MediaTypes */
          P(dev->mutex);               /* Use P to avoid indefinite block */
          if (!dev->is_open()) {
+            Dmsg0(400, "Can relabel. Device is not open\n");
             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
             force_close_device(dev);
          /* Under certain "safe" conditions, we can steal the lock */
          } else if (dev->can_steal_lock()) {
+            Dmsg0(400, "Can relabel. can_steal_lock\n");
             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
-         } else if (dev->is_busy()) {
+         } else if (dev->is_busy() || dev->is_blocked()) {
             send_dir_busy_message(dir, dev);
          } else {                     /* device not being used */
+            Dmsg0(400, "Can relabel. device not used\n");
             label_volume_if_ok(jcr, dev, oldname, newname, poolname, slot, relabel);
          }
          V(dev->mutex);
@@ -373,6 +375,7 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
 
    dcr->dev = dev;
    steal_device_lock(dev, &hold, BST_WRITING_LABEL);
+   Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name());
 
    /* Note, try_autoload_device() opens the device */
    if (!try_autoload_device(jcr, slot, newname)) {
@@ -402,6 +405,7 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
          bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n"));
          break;
       }
+      free_volume(dev);               /* release old volume name */
       /* Fall through wanted! */
    case VOL_IO_ERROR:
    case VOL_NO_LABEL:
@@ -585,7 +589,7 @@ static bool mount_cmd(JCR *jcr)
             break;
 
          case BST_DOING_ACQUIRE:
-            bnet_fsend(dir, _("3001 Device %s is mounted; doing acquire.\n"),
+            bnet_fsend(dir, _("3001 Device %s is doing acquire.\n"),
                        dev->print_name());
             break;
 
index 9ea663715dc4321943a4134fa1f3cc290636be1e..e052a783d421b0976e8a10a949ffd2ecb55c2513 100644 (file)
@@ -66,7 +66,8 @@ int read_dev_volume_label(DCR *dcr)
    bool want_ansi_label;
 
    Dmsg3(100, "Enter read_volume_label device=%s vol=%s dev_Vol=%s\n",
-      dev->name(), VolName, dev->VolHdr.VolumeName);
+      dev->print_name(), VolName, dev->VolHdr.VolumeName[0]?dev->VolHdr.VolumeName:
+      "*NULL*");
 
    if (!dev->is_open()) {
       Emsg0(M_ABORT, 0, _("BAD call to read_dev_volume_label\n"));
@@ -203,7 +204,7 @@ int read_dev_volume_label(DCR *dcr)
    }
 
    dev->set_labeled();               /* set has Bacula label */
-   new_volume(dev->VolHdr.VolumeName, dev);
+   new_volume(dcr, dev->VolHdr.VolumeName);
 
    /* Compare Volume Names */
    Dmsg2(30, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolumeName);
@@ -726,7 +727,7 @@ bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec)
    unser_string(dev->VolHdr.ProgDate);
 
    ser_end(rec->data, SER_LENGTH_Volume_Label);
-   Dmsg0(90, "ser_read_vol\n");
+   Dmsg0(90, "unser_vol_label\n");
    if (debug_level >= 90) {
       dump_volume_label(dev);
    }
index 46e74647a823d53fa69690d70c29ce8e016fa408..40e584962bddbf8de4b8c1bce5c7c4f439cf4a23 100644 (file)
@@ -438,7 +438,7 @@ void release_volume(DCR *dcr)
    if (dev->is_open()) {
       offline_or_rewind_dev(dev);
    }
-   Dmsg0(190, "===== release_volume ---");
+   Dmsg0(190, "===== release_volume ===\n");
 }
 
 /*
index e08d3833ddaed036e442df9661fa520a0f622979..cb7f856efe83355e759f6d073ff33f8f8ecde682 100644 (file)
@@ -135,10 +135,9 @@ void     _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock
 void     _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
 void     set_new_volume_parameters(DCR *dcr);
 void     set_new_file_parameters(DCR *dcr);
-bool     device_is_unmounted(DEVICE *dev);
+bool     is_device_unmounted(DEVICE *dev);
 void     dev_lock(DEVICE *dev);
 void     dev_unlock(DEVICE *dev);
-const char *edit_blocked_reason(DEVICE *dev);
 
 /* From dircmd.c */
 void     *handle_connection_request(void *arg);
@@ -211,9 +210,10 @@ bool read_records(DCR *dcr,
 
 /* From reserve.c */
 void    release_volume(DCR *dcr);
-VOLRES *new_volume(const char *VolumeName, DEVICE *dev);
+VOLRES *new_volume(DCR *dcr, const char *VolumeName);
 VOLRES *find_volume(const char *VolumeName);
 bool    free_volume(DEVICE *dev);
+void    free_unused_volume(DCR *dcr);
 void    create_volume_list();
 void    free_volume_list();
 void    list_volumes(BSOCK *user);
index f6b17003d90c5ca4ae63241f2a041803a7e4f982..ffcd5b7986a4f98354c74d48d5fcd3a8fd377fd0 100644 (file)
@@ -105,21 +105,22 @@ static int my_compare(void *item1, void *item2)
  *  Return: VOLRES entry on success
  *          NULL if the Volume is already in the list
  */
-VOLRES *new_volume(const char *VolumeName, DEVICE *dev)
+VOLRES *new_volume(DCR *dcr, const char *VolumeName)
 {
    VOLRES *vol, *nvol;
    vol = (VOLRES *)malloc(sizeof(VOLRES));
    memset(vol, 0, sizeof(VOLRES));
    vol->vol_name = bstrdup(VolumeName);
-   vol->dev = dev;
+   vol->dev = dcr->dev;
+   vol->dcr = dcr;
    P(vol_list_lock);
    nvol = (VOLRES *)vol_list->binary_insert(vol, my_compare);
    V(vol_list_lock);
    if (nvol != vol) {
       free(vol->vol_name);
       free(vol);
-      if (dev) {
-         nvol->dev = dev;
+      if (dcr->dev) {
+         nvol->dev = dcr->dev;
       }
       return NULL;
    }
@@ -170,6 +171,23 @@ bool free_volume(DEVICE *dev)
    return fvol != NULL;
 }
 
+/* Free volume reserved by this dcr but not attached to a dev */
+void free_unused_volume(DCR *dcr)
+{
+   VOLRES *vol;
+   P(vol_list_lock);
+   for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
+      if (vol->dcr == dcr && (vol->dev == NULL || 
+          strcmp(vol->vol_name, vol->dev->VolHdr.VolumeName) != 0)) {
+         vol_list->remove(vol);
+         free(vol->vol_name);
+         free(vol);
+         break;
+      }
+   }
+   V(vol_list_lock);
+}
+
 /*
  * List Volumes -- this should be moved to status.c
  */
@@ -198,7 +216,8 @@ void free_volume_list()
       return;
    }
    for (vol=(VOLRES *)vol_list->first(); vol; vol=(VOLRES *)vol_list->next(vol)) {
-      Dmsg1(000, "Unreleased Volume=%s\n", vol->vol_name);
+      Dmsg3(000, "Unreleased Volume=%s dcr=0x%x dev=0x%x\n", vol->vol_name,
+         vol->dcr, vol->dev);
    }
    delete vol_list;
    vol_list = NULL;
@@ -533,7 +552,7 @@ static bool reserve_device_for_read(DCR *dcr)
 
    dev->block(BST_DOING_ACQUIRE);
 
-   if (device_is_unmounted(dev)) {             
+   if (is_device_unmounted(dev)) {             
       Dmsg1(200, "Device %s is BLOCKED due to user unmount.\n", dev->print_name());
       Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"),
            dev->print_name());
@@ -589,7 +608,7 @@ static bool reserve_device_for_append(DCR *dcr, bool PreferMountedVols)
       goto bail_out;
    }
 
-   if (device_is_unmounted(dev)) {
+   if (is_device_unmounted(dev)) {
       Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"), dev->print_name());
       Dmsg1(100, "%s", jcr->errmsg);
       goto bail_out;
index 0d5b6f10cd91409353039a16eb901a0401f175f3..801123d173596465c6ca47a005596bed837f45ec 100644 (file)
@@ -48,8 +48,8 @@ int wait_for_sysop(DCR *dcr)
    JCR *jcr = dcr->jcr;
 
    P(dev->mutex);
-   unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+   Dmsg1(100, "Enter blocked=%s\n", dev->print_blocked());
+   unmounted = is_device_unmounted(dev);
 
    dev->poll = false;
    /*
@@ -70,6 +70,7 @@ int wait_for_sysop(DCR *dcr)
    }
 
    if (!unmounted) {
+      Dmsg1(400, "blocked=%s\n", dev->print_blocked());
       dev->dev_prev_blocked = dev->dev_blocked;
       dev->set_blocked(BST_WAITING_FOR_SYSOP); /* indicate waiting for mount */
    }
@@ -86,7 +87,8 @@ int wait_for_sysop(DCR *dcr)
       start = time(NULL);
       /* Wait required time */
       stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->mutex, &timeout);
-      Dmsg1(400, "Wokeup from sleep on device stat=%d\n", stat);
+      Dmsg2(400, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
+         dev->print_blocked());
 
       now = time(NULL);
       dev->rem_wait_sec -= (now - start);
@@ -109,8 +111,7 @@ int wait_for_sysop(DCR *dcr)
       /*
        * Check if user unmounted the device while we were waiting
        */
-      unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
-                   (dev->dev_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+      unmounted = is_device_unmounted(dev);
 
       if (stat != ETIMEDOUT) {     /* we blocked the device */
          break;                    /* on error return */
@@ -122,14 +123,14 @@ int wait_for_sysop(DCR *dcr)
 
       if (!unmounted && dev->vol_poll_interval &&
           (now - first_start >= dev->vol_poll_interval)) {
-         Dmsg1(400, "In wait blocked=%s\n", edit_blocked_reason(dev));
+         Dmsg1(400, "In wait blocked=%s\n", dev->print_blocked());
          dev->poll = true;            /* returning a poll event */
          break;
       }
       /*
        * Check if user mounted the device while we were waiting
        */
-      if (dev->dev_blocked == BST_MOUNT) {   /* mount request ? */
+      if (dev->get_blocked() == BST_MOUNT) {   /* mount request ? */
          stat = 0;
          break;
       }
@@ -145,7 +146,9 @@ int wait_for_sysop(DCR *dcr)
 
    if (!unmounted) {
       dev->set_blocked(dev->dev_prev_blocked);    /* restore entry state */
+      Dmsg1(400, "set %s\n", dev->print_blocked());
    }
+   Dmsg1(400, "Exit blocked=%s\n", dev->print_blocked());
    V(dev->mutex);
    return stat;
 }
index 86ff5b187da9da0cbd97c43131b3fc5c7a3140a8..531f974a0f71869b79cf9aa6a78853079803d8c2 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
 #define VERSION "1.37.28"
-#define BDATE   "04 July 2005"
-#define LSMDATE "04Jul05"
+#define BDATE   "05 July 2005"
+#define LSMDATE "05Jul05"
 
 /* Debug flags */
 #undef  DEBUG