From: Kern Sibbald Date: Tue, 5 Jul 2005 19:02:19 +0000 (+0000) Subject: - Add code to ensure that reserved but unused volumes X-Git-Tag: Release-7.0.0~8656 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6ad207a664aa21a14cf5a888b54f39291b5cd013;p=bacula%2Fbacula - 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. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2175 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index 0987d224dd..4b44aa4931 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -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". diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index 0a2d597748..dd12b3177c 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -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 diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 79c337692f..7af71868f1 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -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); diff --git a/bacula/src/lib/btimers.c b/bacula/src/lib/btimers.c index 6578f7efc1..fcb0b3540c 100644 --- a/bacula/src/lib/btimers.c +++ b/bacula/src/lib/btimers.c @@ -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); } diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index d5d753debd..9b205b9741 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -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"); diff --git a/bacula/src/stored/ansi_label.c b/bacula/src/stored/ansi_label.c index c87f2d484f..f0eed69f51 100644 --- a/bacula/src/stored/ansi_label.c +++ b/bacula/src/stored/ansi_label.c @@ -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; diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index 0fa4699c76..8578711d7d 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -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; } diff --git a/bacula/src/stored/bcopy.c b/bacula/src/stored/bcopy.c index 1897cf6dc6..e508a48f9a 100644 --- a/bacula/src/stored/bcopy.c +++ b/bacula/src/stored/bcopy.c @@ -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) diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c index 6e6c9d8817..bcc3f24012 100644 --- a/bacula/src/stored/bextract.c +++ b/bacula/src/stored/bextract.c @@ -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) diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 56b7bd54f6..976f5a54a4 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -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; } diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 58a9cefd61..d6009b3aaa 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -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) diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 92a1fd0bf0..8de282c633 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -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) { diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 94ecfb312e..92582eafee 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -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) { } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 1484edcf66..ebdd6779bd 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -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. diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 9f1114842b..19a9599a99 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -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; }; diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index f5d53743c5..7a66f618f4 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -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 */ } } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 0c4d2f95b5..ecc2b14402 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -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; diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index 9ea663715d..e052a783d4 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -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); } diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 46e74647a8..40e584962b 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -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"); } /* diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index e08d3833dd..cb7f856efe 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -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); diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index f6b17003d9..ffcd5b7986 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -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; diff --git a/bacula/src/stored/wait.c b/bacula/src/stored/wait.c index 0d5b6f10cd..801123d173 100644 --- a/bacula/src/stored/wait.c +++ b/bacula/src/stored/wait.c @@ -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; } diff --git a/bacula/src/version.h b/bacula/src/version.h index 86ff5b187d..531f974a0f 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -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