From: Kern Sibbald Date: Wed, 17 Aug 2005 13:48:38 +0000 (+0000) Subject: - Create unload_autochanger() subroutine, and unload X-Git-Tag: Release-1.38.0~183 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=7301c21c965b98288e934d3903be74158c540d77;p=bacula%2Fbacula - Create unload_autochanger() subroutine, and unload any drive that changes pool during reservation. - Improve the logic of the reservation. - Add more debug code for autochangers. - Apply fix from Stephan Leemburg for improper scanning of schedule resource: Run = Level=Full Pool=Catalog daily at 1:20 git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2321 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index b136ea1ece..0927e1e83a 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -18,6 +18,8 @@ Final items for 1.37 before release: chaos. - Look at fixing restore status stats in SD. - My database is growing +- Call GetLastError() in the berrno constructor rather + than delaying until strerror. - --without-openssl breaks at least on Solaris. 9. Run the regression scripts on Solaris and FreeBSD diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index 1eee8477fa..75f9aa96e6 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -5,6 +5,10 @@ General: Changes to 1.37.36: 17Aug05 +- Add more debug code for autochangers. +- Apply fix from Stephan Leemburg for + improper scanning of schedule resource: + Run = Level=Full Pool=Catalog daily at 1:20 - Apply patch from Chris Lee for adding --enable-build-dird --enable-build-stored. - Tweak datadir definition in configure.in diff --git a/bacula/src/dird/run_conf.c b/bacula/src/dird/run_conf.c index 2a06fc5aff..6a9946feb8 100644 --- a/bacula/src/dird/run_conf.c +++ b/bacula/src/dird/run_conf.c @@ -297,12 +297,14 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) /* At this point, it is not a keyword. Check for old syle * Job Levels without keyword. This form is depreciated!!! */ - for (j=0; joblevels[j].level_name; j++) { - if (strcasecmp(lc->str, joblevels[j].level_name) == 0) { - lrun.level = joblevels[j].level; - lrun.job_type = joblevels[j].job_type; - found = true; - break; + if (!found) { + for (j=0; joblevels[j].level_name; j++) { + if (strcasecmp(lc->str, joblevels[j].level_name) == 0) { + lrun.level = joblevels[j].level; + lrun.job_type = joblevels[j].job_type; + found = true; + break; + } } } } /* end for found */ diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index f0ceb6d6a5..a581828fc8 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -326,6 +326,7 @@ DCR *acquire_device_for_append(DCR *dcr) */ if (dev->can_read()) { Jmsg1(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev->print_name()); + Dmsg1(200, "Device %s is busy reading.\n", dev->print_name()); goto get_out; } @@ -356,6 +357,8 @@ DCR *acquire_device_for_append(DCR *dcr) if (dev->num_writers != 0 || dev->reserved_device) { Jmsg3(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName); + Dmsg3(200, "Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n", + dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName); goto get_out; } /* Wrong tape mounted, release it, then fall through to get correct one */ @@ -395,6 +398,8 @@ DCR *acquire_device_for_append(DCR *dcr) /* Reduce "noise" -- don't print if job canceled */ Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"), dev->print_name()); + Dmsg1(200, "Could not ready device %s for append.\n", + dev->print_name()); } goto get_out; } diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index 689965d428..49505dd4f8 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -77,29 +77,8 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir) /* If tape we want is not loaded, load it. */ if (loaded != slot) { - offline_or_rewind_dev(dev); - /* We are going to load a new tape, so close the device */ - force_close_device(dev); - lock_changer(dcr); - if (loaded != 0 && loaded != -1) { /* must unload drive */ - Dmsg0(400, "Doing changer unload.\n"); - Jmsg(jcr, M_INFO, 0, - _("3303 Issuing autochanger \"unload slot %d, drive %d\" command.\n"), - loaded, drive); - dcr->VolCatInfo.Slot = loaded; /* slot to be unloaded */ - changer = edit_device_codes(dcr, changer, - dcr->device->changer_command, "unload"); - status = run_program(changer, timeout, NULL); - if (status != 0) { - berrno be; - be.set_errno(status); - Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"), - slot, drive, be.strerror()); - goto bail_out; - } else { - dev->Slot = 0; /* nothing loaded now */ - } - Dmsg1(400, "unload status=%d\n", status); + if (!unload_autochanger(dcr, loaded)) { + goto bail_out; } /* * Load the desired cassette @@ -212,6 +191,56 @@ static void unlock_changer(DCR *dcr) } } +/* + * Unload the volume, if any, in this drive + */ +bool unload_autochanger(DCR *dcr, int loaded) +{ + DEVICE *dev = dcr->dev; + JCR *jcr = dcr->jcr; + int slot; + uint32_t timeout = dcr->device->max_changer_wait; + + if (!dev->is_autochanger() || !dcr->device->changer_name || + !dcr->device->changer_command) { + return false; + } + + offline_or_rewind_dev(dev); + /* We are going to load a new tape, so close the device */ + force_close_device(dev); + + if (loaded <= 0) { + loaded = get_autochanger_loaded_slot(dcr); + } + if (loaded > 0) { + POOLMEM *changer = get_pool_memory(PM_FNAME); + Jmsg(jcr, M_INFO, 0, + _("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"), + loaded, dev->drive_index); + slot = dcr->VolCatInfo.Slot; + dcr->VolCatInfo.Slot = loaded; + changer = edit_device_codes(dcr, changer, + dcr->device->changer_command, "unload"); + lock_changer(dcr); + int stat = run_program(changer, timeout, NULL); + unlock_changer(dcr); + dcr->VolCatInfo.Slot = slot; + if (stat != 0) { + berrno be; + be.set_errno(stat); + Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"), + slot, dev->drive_index, be.strerror()); + free_pool_memory(changer); + return false; + } else { + dev->Slot = 0; /* nothing loaded */ + } + free_pool_memory(changer); + } + return true; +} + /* * List the Volumes that are in the autoloader possibly @@ -221,11 +250,9 @@ static void unlock_changer(DCR *dcr) bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd) { DEVICE *dev = dcr->dev; - JCR *jcr = dcr->jcr; uint32_t timeout = dcr->device->max_changer_wait; POOLMEM *changer; BPIPE *bpipe; - int slot, loaded; int len = sizeof_pool_memory(dir->msg) - 1; bool ok = false; int stat; @@ -240,35 +267,7 @@ bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd) changer = get_pool_memory(PM_FNAME); /* List command? */ if (strcmp(cmd, "list") == 0) { - int drive = dev->device->drive_index; - /* Yes, to get a good listing, we unload any volumes */ - offline_or_rewind_dev(dev); - /* We are going to load a new tape, so close the device */ - force_close_device(dev); - - /* First unload any tape */ - loaded = get_autochanger_loaded_slot(dcr); - if (loaded > 0) { - bnet_fsend(dir, - _("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"), - loaded, drive); - slot = dcr->VolCatInfo.Slot; - dcr->VolCatInfo.Slot = loaded; - changer = edit_device_codes(dcr, changer, - dcr->device->changer_command, "unload"); - lock_changer(dcr); - int stat = run_program(changer, timeout, NULL); - unlock_changer(dcr); - if (stat != 0) { - berrno be; - be.set_errno(stat); - Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"), - slot, drive, be.strerror()); - } else { - dev->Slot = 0; /* nothing loaded */ - } - dcr->VolCatInfo.Slot = slot; - } + unload_autochanger(dcr, 0); } /* Now issue the command */ diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index a7f4044091..85443ad3be 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -51,6 +51,7 @@ int authenticate_filed(JCR *jcr); /* From autochanger.c */ int autoload_device(DCR *dcr, int writing, BSOCK *dir); bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd); +bool unload_autochanger(DCR *dcr, int loaded); char *edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd); int get_autochanger_loaded_slot(DCR *dcr); diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index 48f3d76b3d..e72d9a29f3 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -109,6 +109,8 @@ static int my_compare(void *item1, void *item2) VOLRES *new_volume(DCR *dcr, const char *VolumeName) { VOLRES *vol, *nvol; + + Dmsg1(400, "new_volume %s\n", VolumeName); vol = (VOLRES *)malloc(sizeof(VOLRES)); memset(vol, 0, sizeof(VOLRES)); vol->vol_name = bstrdup(VolumeName); @@ -158,6 +160,7 @@ bool free_volume(DEVICE *dev) if (dev->VolHdr.VolumeName[0] == 0) { return false; } + Dmsg1(400, "free_volume %s\n", dev->VolHdr.VolumeName); vol.vol_name = bstrdup(dev->VolHdr.VolumeName); P(vol_list_lock); fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare); @@ -353,7 +356,7 @@ static bool use_storage_cmd(JCR *jcr) Jmsg(jcr, M_INFO, 0, "%s", error); } #endif - Dmsg1(100, ">dird: %s\n", dir->msg); + Dmsg1(100, ">dird: %s", dir->msg); } else { unbash_spaces(dir->msg); pm_strcpy(jcr->errmsg, dir->msg); @@ -361,7 +364,7 @@ static bool use_storage_cmd(JCR *jcr) Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg); } bnet_fsend(dir, BAD_use, jcr->errmsg); - Dmsg1(100, ">dird: %s\n", dir->msg); + Dmsg1(100, ">dird: %s", dir->msg); } done: @@ -462,7 +465,7 @@ static int search_res_for_device(RCTX &rctx) Dmsg1(220, "Got: %s", dir->msg); bash_spaces(rctx.device_name); ok = bnet_fsend(dir, OK_device, rctx.device_name); - Dmsg1(100, ">dird: %s\n", dir->msg); + Dmsg1(100, ">dird dev: %s", dir->msg); return ok ? 1 : -1; } } @@ -485,7 +488,7 @@ static int search_res_for_device(RCTX &rctx) pm_strcpy(dev_name, rctx.device->hdr.name); bash_spaces(dev_name); ok = bnet_fsend(dir, OK_device, dev_name.c_str()); /* Return real device name */ - Dmsg1(100, ">dird: %s\n", dir->msg); + Dmsg1(100, ">dird changer: %s", dir->msg); return ok ? 1 : -1; } } @@ -531,7 +534,7 @@ static int reserve_device(RCTX &rctx) if (!dcr) { BSOCK *dir = rctx.jcr->dir_bsock; bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name); - Dmsg1(100, ">dird: %s\n", dir->msg); + Dmsg1(100, ">dird: %s", dir->msg); return -1; } rctx.jcr->dcr = dcr; @@ -663,9 +666,9 @@ static int can_reserve_drive(DCR *dcr, bool PreferMountedVols) } /* - * Handle the case that the drive is not yet in append mode + * Handle the case that there are no writers */ - if (!dev->can_append() && dev->num_writers == 0) { + if (dev->num_writers == 0) { /* Now check if there are any reservations on the drive */ if (dev->reserved_device) { /* Yes, now check if we want the same Pool and pool type */ @@ -676,23 +679,22 @@ static int can_reserve_drive(DCR *dcr, bool PreferMountedVols) /* Drive not suitable for us */ return 0; /* wait */ } - } else { - /* Device is available but not yet reserved, reserve it for us */ - bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name)); - bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type)); + } else if (dev->can_append()) { + /* Device in append mode, check if changing pool */ + if (strcmp(dev->pool_name, dcr->pool_name) == 0 && + strcmp(dev->pool_type, dcr->pool_type) == 0) { + /* OK, compatible device */ + } else { + /* Changing pool, unload old tape if any in drive */ + unload_autochanger(dcr, 0); + } } - return 1; /* reserve drive */ - } - - /* - * Check if device in append mode with no writers (i.e. available) - */ - if (dev->can_append() && dev->num_writers == 0) { /* Device is available but not yet reserved, reserve it for us */ bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name)); bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type)); - return 1; + return 1; /* reserve drive */ } + /* * Check if the device is in append mode with writers (i.e. * available if pool is the same).