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
Changes to 1.37.36:
17Aug05
+- Add more debug code for autochangers.
+- Apply fix from Stephan Leemburg <sleemburg@jvc.nl> for
+ improper scanning of schedule resource:
+ Run = Level=Full Pool=Catalog daily at 1:20
- Apply patch from Chris Lee <labmonkey42@gmail.com> for
adding --enable-build-dird --enable-build-stored.
- Tweak datadir definition in configure.in
/* 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 */
*/
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;
}
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 */
/* 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;
}
/* 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
}
}
+/*
+ * 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
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;
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 */
/* 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);
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);
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);
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);
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:
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;
}
}
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;
}
}
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;
}
/*
- * 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 */
/* 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).