X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fautochanger.c;h=d459689e32d639e135da001e651799d22a05dc10;hb=6bea24b0386f7076c4bdba4c3ce7ffb2953511b3;hp=4f9682766f58f89759276a60dd33c83c7ef30c2e;hpb=c5e8eee37f5bdc96a3bc9771d2807b232b7febdd;p=bacula%2Fbacula diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index 4f9682766f..d459689e32 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -30,7 +30,8 @@ #include "stored.h" /* pull in Storage Deamon headers */ /* Forward referenced functions */ -static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd); +char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd); +static int get_autochanger_loaded_slot(JCR *jcr); /* @@ -44,12 +45,14 @@ static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd); * dir bsock. * * Returns: 1 on success - * 0 on failure + * 0 on failure (no changer available) + * -1 on error on autochanger */ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) { int slot = jcr->VolCatInfo.Slot; - int rtn_stat = 0; + int drive = jcr->device->drive_index; + int rtn_stat = -1; /* error status */ /* * Handle autoloaders here. If we cannot autoload it, we @@ -61,104 +64,121 @@ int autoload_device(JCR *jcr, DEVICE *dev, int writing, BSOCK *dir) } if (dir_find_next_appendable_volume(jcr)) { slot = jcr->VolCatInfo.Slot; + } else { + slot = 0; } } - Dmsg1(100, "Want changer slot=%d\n", slot); + Dmsg1(400, "Want changer slot=%d\n", slot); if (slot > 0 && jcr->device->changer_name && jcr->device->changer_command) { uint32_t timeout = jcr->device->max_changer_wait; - POOLMEM *changer, *results; - int status, loaded; + POOLMEM *changer; + int loaded, status; - results = get_pool_memory(PM_MESSAGE); changer = get_pool_memory(PM_FNAME); - /* Find out what is loaded, zero means device is unloaded */ - if (dir) { - bnet_fsend(dir, _("3301 Issuing autochanger \"loaded\" command.\n")); - } else { - Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"loaded\" command.\n")); - } - changer = edit_device_codes(jcr, changer, jcr->device->changer_command, - "loaded"); - status = run_program(changer, timeout, results); - Dmsg3(100, "run_prog: %s stat=%d result=%s\n", changer, status, results); - if (status == 0) { - loaded = atoi(results); - } else { - if (dir) { - bnet_fsend(dir, _("3991 Bad autochanger \"loaded\" status=%d.\n"), - status); - } else { - Jmsg(jcr, M_INFO, 0, _("Bad autochanger \"load slot\" status=%d.\n"), - status); - } - loaded = -1; /* force unload */ - } - Dmsg1(100, "loaded=%s\n", results); + loaded = get_autochanger_loaded_slot(jcr); - /* If bad status or tape we want is not loaded, load it. */ - if (status != 0 || loaded != slot) { - if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { - offline_dev(dev); - } + /* 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_dev(dev); - if (loaded != 0) { /* must unload drive */ - Dmsg0(100, "Doing changer unload.\n"); - if (dir) { - bnet_fsend(dir, _("3302 Issuing autochanger \"unload\" command.\n")); - } else { - Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"unload\" command.\n")); - } + 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); + jcr->VolCatInfo.Slot = loaded; /* slot to be unloaded */ changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload"); status = run_program(changer, timeout, NULL); - Dmsg1(100, "unload status=%d\n", status); + Dmsg1(400, "unload status=%d\n", status); } /* * Load the desired cassette */ - Dmsg1(100, "Doing changer load slot %d\n", slot); - if (dir) { - bnet_fsend(dir, _("3303 Issuing autochanger \"load slot %d\" command.\n"), - slot); - } else { - Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"load slot %d\" command.\n"), - slot); - } + Dmsg1(400, "Doing changer load slot %d\n", slot); + Jmsg(jcr, M_INFO, 0, + _("3304 Issuing autochanger \"load slot %d, drive %d\" command.\n"), + slot, drive); + jcr->VolCatInfo.Slot = slot; /* slot to be loaded */ changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "load"); status = run_program(changer, timeout, NULL); if (status == 0) { - if (dir) { - bnet_fsend(dir, _("3304 Autochanger \"load slot %d\" status is OK.\n"), - slot); - } else { - Jmsg(jcr, M_INFO, 0, _("Autochanger \"load slot %d\" status is OK.\n"), - slot); - } + Jmsg(jcr, M_INFO, 0, _("3305 Autochanger \"load slot %d, drive %d\", status is OK.\n"), + slot, drive); } else { - if (dir) { - bnet_fsend(dir, _("3992 Bad autochanger \"load slot\" status=%d.\n"), - status); - } else { - Jmsg(jcr, M_INFO, 0, _("Bad autochanger \"load slot\" status=%d.\n"), - status); - } + Jmsg(jcr, M_INFO, 0, _("3992 Bad autochanger \"load slot %d, drive %d\", status=%d.\n"), + slot, drive, status); } - Dmsg2(100, "load slot %d status=%d\n", slot, status); + Dmsg2(400, "load slot %d status=%d\n", slot, status); + } else { + status = 0; /* we got what we want */ } free_pool_memory(changer); - free_pool_memory(results); - Dmsg1(100, "After changer, status=%d\n", status); - if (status == 0) { /* did we succeed? */ - rtn_stat = 1; /* tape loaded by changer */ + Dmsg1(400, "After changer, status=%d\n", status); + if (status == 0) { /* did we succeed? */ + rtn_stat = 1; /* tape loaded by changer */ } + } else { + rtn_stat = 0; /* no changer found */ } return rtn_stat; } +static int get_autochanger_loaded_slot(JCR *jcr) +{ + POOLMEM *changer, *results; + int status, loaded; + uint32_t timeout = jcr->device->max_changer_wait; + int drive = jcr->device->drive_index; + + results = get_pool_memory(PM_MESSAGE); + changer = get_pool_memory(PM_FNAME); + + /* Find out what is loaded, zero means device is unloaded */ + Jmsg(jcr, M_INFO, 0, _("3301 Issuing autochanger \"loaded drive %d\" command.\n"), + drive); + changer = edit_device_codes(jcr, changer, jcr->device->changer_command, + "loaded"); + status = run_program(changer, timeout, results); + Dmsg3(100, "run_prog: %s stat=%d result=%s\n", changer, status, results); + if (status == 0) { + loaded = atoi(results); + if (loaded > 0) { + Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result is Slot %d.\n"), + drive, loaded); + } else { + Jmsg(jcr, M_INFO, 0, _("3302 Autochanger \"loaded drive %d\", result: nothing loaded.\n"), + drive); + } + } else { + Jmsg(jcr, M_INFO, 0, _("3991 Bad autochanger \"loaded drive %d\" command, status=%d.\n"), + drive, status); + loaded = -1; /* force unload */ + } + free_pool_memory(changer); + free_pool_memory(results); + return loaded; +} + +/* + * The Volume is not in the correct slot, so mark this + * Volume as not being in the Changer. + */ +void invalid_slot_in_catalog(JCR *jcr, DEVICE *dev) +{ + Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n" +" Setting slot to zero in catalog.\n"), + jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot); + jcr->VolCatInfo.InChanger = false; + dev->VolCatInfo.InChanger = false; + Dmsg0(100, "update vol info in mount\n"); + dir_update_volume_info(jcr, dev, 1); /* set new status */ +} + /* * List the Volumes that are in the autoloader possibly * with their barcodes. @@ -169,6 +189,7 @@ int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir) uint32_t timeout = jcr->device->max_changer_wait; POOLMEM *changer; BPIPE *bpipe; + int slot, loaded; int len = sizeof_pool_memory(dir->msg) - 1; if (!dev_cap(dev, CAP_AUTOCHANGER) || !jcr->device->changer_name || @@ -178,23 +199,27 @@ int autochanger_list(JCR *jcr, DEVICE *dev, BSOCK *dir) } changer = get_pool_memory(PM_FNAME); - if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) { - offline_dev(dev); - } + offline_or_rewind_dev(dev); /* We are going to load a new tape, so close the device */ force_close_dev(dev); /* First unload any tape */ - bnet_fsend(dir, _("3902 Issuing autochanger \"unload\" command.\n")); - changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload"); - run_program(changer, timeout, NULL); + loaded = get_autochanger_loaded_slot(jcr); + if (loaded > 0) { + bnet_fsend(dir, _("3305 Issuing autochanger \"unload slot %d\" command.\n"), loaded); + slot = jcr->VolCatInfo.Slot; + jcr->VolCatInfo.Slot = loaded; + changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload"); + run_program(changer, timeout, NULL); + jcr->VolCatInfo.Slot = slot; + } /* Now list slots occupied */ changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "list"); - bnet_fsend(dir, _("3305 Issuing autochanger \"list\" command.\n")); + bnet_fsend(dir, _("3306 Issuing autochanger \"list\" command.\n")); bpipe = open_bpipe(changer, timeout, "r"); if (!bpipe) { - bnet_fsend(dir, _("3994 Open bpipe failed.\n")); + bnet_fsend(dir, _("3993 Open bpipe failed.\n")); goto bail_out; } /* Get output from changer */ @@ -217,6 +242,7 @@ bail_out: * %% = % * %a = archive device name * %c = changer device name + * %d = changer drive index * %f = Client's name * %j = Job name * %o = command @@ -230,14 +256,14 @@ bail_out: * cmd = command string (load, unload, ...) * */ -static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd) +char *edit_device_codes(JCR *jcr, char *omsg, const char *imsg, const char *cmd) { - char *p; + const char *p; const char *str; char add[20]; *omsg = 0; - Dmsg1(200, "edit_device_codes: %s\n", imsg); + Dmsg1(400, "edit_device_codes: %s\n", imsg); for (p=imsg; *p; p++) { if (*p == '%') { switch (*++p) { @@ -245,11 +271,15 @@ static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd) str = "%"; break; case 'a': - str = jcr->device->dev->dev_name; + str = dev_name(jcr->device->dev); break; case 'c': str = NPRT(jcr->device->changer_name); break; + case 'd': + sprintf(add, "%d", jcr->device->dev->drive_index); + str = add; + break; case 'o': str = NPRT(cmd); break; @@ -283,9 +313,9 @@ static char *edit_device_codes(JCR *jcr, char *omsg, char *imsg, char *cmd) add[1] = 0; str = add; } - Dmsg1(200, "add_str %s\n", str); + Dmsg1(400, "add_str %s\n", str); pm_strcat(&omsg, (char *)str); - Dmsg1(200, "omsg=%s\n", omsg); + Dmsg1(400, "omsg=%s\n", omsg); } return omsg; }