From 459a8784e5070a445f221972da8d2e8854ce7770 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 24 Sep 2007 16:01:25 +0000 Subject: [PATCH] kes Back out one small change to the reservation system (reserving a volume). kes Rework how a Volume is mounted. It is now much more intelligent and will always attempt to use any mounted volume if possible and reduces calls to the Director asking about volumes. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5636 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/stored/acquire.c | 43 ++++++++++++++++++++++++++----------- bacula/src/stored/askdir.c | 4 +++- bacula/src/stored/device.c | 3 ++- bacula/src/stored/mount.c | 18 ++++++++++------ bacula/src/stored/protos.h | 2 +- bacula/src/stored/reserve.c | 5 +---- bacula/src/version.h | 4 ++-- bacula/technotes-2.3 | 5 +++++ 8 files changed, 55 insertions(+), 29 deletions(-) diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 31f81d8adc..e3a9d813b1 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -38,6 +38,7 @@ /* Forward referenced functions */ static void attach_dcr_to_dev(DCR *dcr); +static bool is_suitable_volume_mounted(DCR *dcr); /********************************************************************* @@ -316,9 +317,9 @@ get_out: */ DCR *acquire_device_for_append(DCR *dcr) { - bool release = false; - bool recycle = false; bool do_mount = false; + bool release = false; + bool find; DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; @@ -337,6 +338,11 @@ DCR *acquire_device_for_append(DCR *dcr) goto get_out; } + /* + * find defines whether or not mount_next_write_volume should + * as the Director again about what Volume to use. + */ + find = is_suitable_volume_mounted(dcr); if (dev->can_append()) { Dmsg0(190, "device already in append.\n"); /* @@ -351,21 +357,20 @@ DCR *acquire_device_for_append(DCR *dcr) * 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) && + if (!find && !(dir_find_next_appendable_volume(dcr) && strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */ 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]) { - volume_unused(dcr); - } if (dev->num_writers != 0) { Jmsg3(jcr, M_FATAL, 0, _("Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName); Dmsg3(200, "Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n", dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName); + /* Release volume reserved by dir_find_next_appendable_volume() */ + if (dcr->VolumeName[0]) { + volume_unused(dcr); + } goto get_out; } /* Wrong tape mounted, release it, then fall through to get correct one */ @@ -378,9 +383,9 @@ DCR *acquire_device_for_append(DCR *dcr) * we do not need to do mount_next_write_volume(), unless * we need to recycle the tape. */ - recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0; - Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle); - if (recycle && dev->num_writers != 0) { + do_mount = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0; + Dmsg1(190, "Correct tape mounted. recycle=%d\n", do_mount); + if (do_mount && dev->num_writers != 0) { Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\"" " on device %s because it is in use by another job.\n"), dev->VolHdr.VolumeName, dev->print_name()); @@ -420,9 +425,9 @@ DCR *acquire_device_for_append(DCR *dcr) do_mount = true; } - if (do_mount || recycle) { + if (do_mount) { Dmsg0(190, "Do mount_next_write_vol\n"); - bool mounted = mount_next_write_volume(dcr, release); + bool mounted = mount_next_write_volume(dcr, find, release); if (!mounted) { if (!job_canceled(jcr)) { /* Reduce "noise" -- don't print if job canceled */ @@ -468,6 +473,18 @@ get_out: } +static bool is_suitable_volume_mounted(DCR *dcr) +{ + DEVICE *dev = dcr->dev; + + /* Volume mounted? */ + if (dev->VolHdr.VolumeName[0] == 0) { + return false; /* no */ + } + bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName)); + return dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE); +} + /* * This job is done, so release the device. From a Unix standpoint, * the device remains open. diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index c3c448f872..753f1a34ae 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -254,7 +254,9 @@ bool dir_find_next_appendable_volume(DCR *dcr) BSOCK *dir = jcr->dir_bsock; bool found = false; - Dmsg0(200, "dir_find_next_appendable_volume\n"); + Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n", + dcr->reserved_device, dcr->VolumeName); + /* * Try the twenty oldest or most available volumes. Note, * the most available could already be mounted on another diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 34fbc0cec7..eb79ab9318 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -122,7 +122,8 @@ bool fixup_device_block_write_error(DCR *dcr) edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2), bstrftime(dt, sizeof(dt), time(NULL))); - if (!mount_next_write_volume(dcr, 1)) { + /* Called with find=true, release=true */ + if (!mount_next_write_volume(dcr, true, true)) { free_block(label_blk); dcr->block = block; dev->dlock(); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 8eb2f3f91b..9d0137b8b8 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -60,7 +60,7 @@ enum { * impossible to get the requested Volume. * */ -bool mount_next_write_volume(DCR *dcr, bool release) +bool mount_next_write_volume(DCR *dcr, bool find, bool release) { int retry = 0; bool ask = false, recycle, autochanger; @@ -108,12 +108,16 @@ mount_next_vol: * in dcr->VolCatInfo */ Dmsg0(200, "Before dir_find_next_appendable_volume.\n"); - while (!dir_find_next_appendable_volume(dcr)) { - Dmsg0(200, "not dir_find_next\n"); - if (!dir_ask_sysop_to_create_appendable_volume(dcr)) { - return false; + if (find) { + while (!dir_find_next_appendable_volume(dcr)) { + Dmsg0(200, "not dir_find_next\n"); + if (!dir_ask_sysop_to_create_appendable_volume(dcr)) { + return false; + } + Dmsg0(200, "Again dir_find_next_append...\n"); } - Dmsg0(200, "Again dir_find_next_append...\n"); + } else { + find = true; /* set true for next pass if any */ } if (job_canceled(jcr)) { return false; @@ -144,7 +148,7 @@ mount_next_vol: * If we autochanged to correct Volume or (we have not just * released the Volume AND we can automount) we go ahead * and read the label. If there is no tape in the drive, - * we will err, recurse and ask the operator the next time. + * we will fail, recurse and ask the operator the next time. */ if (!release && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) { Dmsg0(150, "(1)Ask=0\n"); diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 783241d30b..842a1493d6 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -182,7 +182,7 @@ BSR *find_next_bsr(BSR *root_bsr, DEVICE *dev); bool is_this_bsr_done(BSR *bsr, DEV_RECORD *rec); /* From mount.c */ -bool mount_next_write_volume(DCR *dcr, bool release); +bool mount_next_write_volume(DCR *dcr, bool find, bool release); bool mount_next_read_volume(DCR *dcr); void mark_volume_in_error(DCR *dcr); diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index e90e9d0127..e45fa752ea 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -329,12 +329,9 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) * because it was probably inserted by another job. */ if (strcmp(vol->vol_name, VolumeName) == 0) { + Dmsg2(dbglvl, "jid=%u OK, vol=%s on device.\n", (int)dcr->jcr->JobId, VolumeName); goto get_out; /* Volume already on this device */ } else { - if (dev->is_busy() && dev->VolHdr.VolumeName[0]) { - vol = NULL; - goto get_out; - } Dmsg3(dbglvl, "jid=%u reserve_vol free vol=%s at %p\n", (int)dcr->jcr->JobId, vol->vol_name, vol->vol_name); debug_list_volumes("reserve_vol free"); diff --git a/bacula/src/version.h b/bacula/src/version.h index eb19750a59..db28a38de3 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.3.5" -#define BDATE "23 September 2007" -#define LSMDATE "23Sep07" +#define BDATE "24 September 2007" +#define LSMDATE "24Sep07" #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n" #define BYEAR "2007" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.3 b/bacula/technotes-2.3 index 33cd3fe787..cd7be4926a 100644 --- a/bacula/technotes-2.3 +++ b/bacula/technotes-2.3 @@ -1,6 +1,11 @@ Technical notes on version 2.3 General: +24Sep07 +kes Back out one small change to the reservation system (reserving a volume). +kes Rework how a Volume is mounted. It is now much more intelligent and + will always attempt to use any mounted volume if possible and reduces + calls to the Director asking about volumes. 23Sep07 kes Turn off some code when batch insert not enabled. kes Edit FD name in connect error messages. -- 2.39.5