Skip to content

Commit

Permalink
stored: Use logical drive numbers and not drive indexes
Browse files Browse the repository at this point in the history
Currently the mount protocol between the director and the storage daemon
passes a logical drive number (as seen from the end-user) but the search
algorithm uses the drive index in the autochanger to find the right
drive.

We should number the drives logically and perform the search using that
number. This patch removes the use of any drive index which is a
physical number only needed for external programs that address the drive
via its physical drive index. After this change there is only one place
where the drive index is used and that is in edit_device_codes() which
creates the cmdline for the external programs like mtx-changer etc.

Fixes #634: Storage daemon should use logical drive numbers and not
            drive indexes
  • Loading branch information
Marco van Wieringen authored and pstorz committed Mar 30, 2016
1 parent c626a26 commit 7d83a52
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 39 deletions.
64 changes: 42 additions & 22 deletions src/stored/autochanger.c
Expand Up @@ -36,39 +36,56 @@ static bool unload_other_drive(DCR *dcr, int slot);
static char *transfer_edit_device_codes(DCR *dcr, POOLMEM *&omsg, const char *imsg,
const char *cmd, int src_slot, int dst_slot);

/* Init all the autochanger resources found */
/*
* Init all the autochanger resources found
*/
bool init_autochangers()
{
bool OK = true;
AUTOCHANGERRES *changer;
/* Ensure that the media_type for each device is the same */
int logical_drive_number;

/*
* Ensure that the media_type for each device is the same
*/
foreach_res(changer, R_AUTOCHANGER) {
DEVRES *device;

logical_drive_number = 0;
foreach_alist(device, changer->device) {
/*
* If the device does not have a changer name or changer command
* defined, used the one from the Autochanger resource
* defined, used the one from the Autochanger resource
*/
if (!device->changer_name && changer->changer_name) {
device->changer_name = bstrdup(changer->changer_name);
}

if (!device->changer_command && changer->changer_command) {
device->changer_command = bstrdup(changer->changer_command);
}

if (!device->changer_name) {
Jmsg(NULL, M_ERROR, 0,
_("No Changer Name given for device %s. Cannot continue.\n"),
device->name());
_("No Changer Name given for device %s. Cannot continue.\n"),
device->name());
OK = false;
}

if (!device->changer_command) {
Jmsg(NULL, M_ERROR, 0,
_("No Changer Command given for device %s. Cannot continue.\n"),
device->name());
_("No Changer Command given for device %s. Cannot continue.\n"),
device->name());
OK = false;
}

/*
* Give the drive in the autochanger a logical drive number.
*/
device->drive = logical_drive_number++;
}
}

return OK;
}

Expand All @@ -91,7 +108,7 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir)
JCR *jcr = dcr->jcr;
DEVICE * volatile dev = dcr->dev;
int slot;
int drive = dev->drive_index;
int drive = dev->drive;
int rtn_stat = -1; /* error status */
POOLMEM *changer;

Expand Down Expand Up @@ -254,7 +271,7 @@ int get_autochanger_loaded_slot(DCR *dcr)
DEVICE *dev = dcr->dev;
int status, loaded;
uint32_t timeout = dcr->device->max_changer_wait;
int drive = dcr->dev->drive_index;
int drive = dcr->dev->drive;
POOL_MEM results(PM_MESSAGE);
POOLMEM *changer;

Expand Down Expand Up @@ -381,25 +398,27 @@ bool unload_autochanger(DCR *dcr, int loaded)
}

if (loaded > 0) {
int status;
POOL_MEM results(PM_MESSAGE);
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);
loaded, dev->drive);
slot = dcr->VolCatInfo.Slot;
dcr->VolCatInfo.Slot = loaded;
changer = edit_device_codes(dcr, changer,
dcr->device->changer_command, "unload");
dcr->device->changer_command, "unload");
dev->close(dcr);
Dmsg1(100, "Run program=%s\n", changer);
int status = run_program_full_output(changer, timeout, results.addr());
status = run_program_full_output(changer, timeout, results.addr());
dcr->VolCatInfo.Slot = slot;
if (status != 0) {
berrno be;
be.set_errno(status);
Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": "
"ERR=%s\nResults=%s\n"),
loaded, dev->drive_index, be.bstrerror(), results.c_str());
loaded, dev->drive, be.bstrerror(), results.c_str());
ok = false;
dev->clear_slot(); /* unknown */
} else {
Expand Down Expand Up @@ -499,12 +518,13 @@ static bool unload_other_drive(DCR *dcr, int slot)
*/
bool unload_dev(DCR *dcr, DEVICE *dev)
{
JCR *jcr = dcr->jcr;
int status;
int save_slot;
bool ok = true;
DEVICE *save_dev;
JCR *jcr = dcr->jcr;
uint32_t timeout = dcr->device->max_changer_wait;
AUTOCHANGERRES *changer = dcr->dev->device->changer_res;
DEVICE *save_dev;
int save_slot;

if (!changer) {
return false;
Expand Down Expand Up @@ -534,28 +554,28 @@ bool unload_dev(DCR *dcr, DEVICE *dev)
lock_changer(dcr);
Jmsg(jcr, M_INFO, 0,
_("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
dev->get_slot(), dev->drive_index);
dev->get_slot(), dev->drive);

Dmsg2(100, "Issuing autochanger \"unload slot %d, drive %d\" command.\n",
dev->get_slot(), dev->drive_index);
dev->get_slot(), dev->drive);

changer_cmd = edit_device_codes(dcr, changer_cmd,
dcr->device->changer_command, "unload");
dcr->device->changer_command, "unload");
dev->close(dcr);
Dmsg2(200, "close dev=%s reserve=%d\n", dev->print_name(),
dev->num_reserved());
Dmsg1(100, "Run program=%s\n", changer_cmd);
int status = run_program_full_output(changer_cmd, timeout, results.addr());
status = run_program_full_output(changer_cmd, timeout, results.addr());
dcr->VolCatInfo.Slot = save_slot;
dcr->set_dev(save_dev);
if (status != 0) {
berrno be;
be.set_errno(status);
Jmsg(jcr, M_INFO, 0, _("3997 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
dev->get_slot(), dev->drive_index, be.bstrerror());
dev->get_slot(), dev->drive, be.bstrerror());

Dmsg3(100, "Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n",
dev->get_slot(), dev->drive_index, be.bstrerror());
dev->get_slot(), dev->drive, be.bstrerror());
ok = false;
dev->clear_slot(); /* unknown */
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/stored/btape.c
Expand Up @@ -1532,9 +1532,9 @@ static int autochanger_test()
/* We are going to load a new tape, so close the device */
dev->close(dcr);
Pmsg2(-1, _("3302 Issuing autochanger \"unload %d %d\" command.\n"),
loaded, dev->drive_index);
loaded, dev->drive);
changer = edit_device_codes(dcr, changer,
dcr->device->changer_command, "unload");
dcr->device->changer_command, "unload");
status = run_program(changer, timeout, results);
Pmsg2(-1, _("unload status=%s %d\n"), status==0?_("OK"):_("Bad"), status);
if (status != 0) {
Expand All @@ -1551,15 +1551,15 @@ static int autochanger_test()
slot = 1;
dcr->VolCatInfo.Slot = slot;
Pmsg2(-1, _("3303 Issuing autochanger \"load %d %d\" command.\n"),
slot, dev->drive_index);
slot, dev->drive);
changer = edit_device_codes(dcr, changer,
dcr->device->changer_command, "load");
dcr->device->changer_command, "load");
Dmsg1(100, "Changer=%s\n", changer);
dev->close(dcr);
status = run_program(changer, timeout, results);
if (status == 0) {
Pmsg2(-1, _("3303 Autochanger \"load %d %d\" status is OK.\n"),
slot, dev->drive_index);
slot, dev->drive);
} else {
berrno be;
Pmsg1(-1, _("3993 Bad autochanger command: %s\n"), changer);
Expand Down
1 change: 1 addition & 0 deletions src/stored/dev.c
Expand Up @@ -272,6 +272,7 @@ static inline DEVICE *m_init_dev(JCR *jcr, DEVRES *device, bool new_init)
dev->max_open_vols = device->max_open_vols;
dev->vol_poll_interval = device->vol_poll_interval;
dev->max_spool_size = device->max_spool_size;
dev->drive = device->drive;
dev->drive_index = device->drive_index;
dev->autoselect = device->autoselect;
dev->norewindonclose = device->norewindonclose;
Expand Down
3 changes: 2 additions & 1 deletion src/stored/dev.h
Expand Up @@ -297,7 +297,8 @@ class DEVICE: public SMARTALLOC {
bool norewindonclose; /* Don't rewind tape drive on close */
bool initiated; /* Set when init_dev() called */
int label_type; /* Bareos/ANSI/IBM label types */
uint32_t drive_index; /* Autochanger drive index (base 0) */
uint32_t drive; /* Autochanger logical drive number (base 0) */
uint32_t drive_index; /* Autochanger physical drive index (base 0) */
POOLMEM *dev_name; /* Physical device name */
POOLMEM *dev_options; /* Device specific options */
POOLMEM *prt_name; /* Name used for display purposes */
Expand Down
21 changes: 14 additions & 7 deletions src/stored/dir_cmd.c
Expand Up @@ -829,14 +829,16 @@ static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive, BLOCKSIZES *bloc

unbash_spaces(devname);
foreach_res(device, R_DEVICE) {
/* Find resource, and make sure we were able to open it */
/*
* Find resource, and make sure we were able to open it
*/
if (bstrcmp(device->name(), devname.c_str())) {
if (!device->dev) {
device->dev = init_dev(jcr, device);
}
if (!device->dev) {
Jmsg(jcr, M_WARNING, 0, _("\n"
" Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
" Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
devname.c_str());
continue;
}
Expand All @@ -845,11 +847,16 @@ static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive, BLOCKSIZES *bloc
break;
}
}

if (!found) {
foreach_res(changer, R_AUTOCHANGER) {
/* Find resource, and make sure we were able to open it */
/*
* Find resource, and make sure we were able to open it
*/
if (bstrcmp(devname.c_str(), changer->name())) {
/* Try each device in this AutoChanger */
/*
* Try each device in this AutoChanger
*/
foreach_alist(device, changer->device) {
Dmsg1(100, "Try changer device %s\n", device->name());
if (!device->dev) {
Expand All @@ -858,21 +865,21 @@ static DCR *find_device(JCR *jcr, POOL_MEM &devname, int drive, BLOCKSIZES *bloc
if (!device->dev) {
Dmsg1(100, "Device %s could not be opened. Skipped\n", devname.c_str());
Jmsg(jcr, M_WARNING, 0, _("\n"
" Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
" Device \"%s\" in changer \"%s\" requested by DIR could not be opened or does not exist.\n"),
device->name(), devname.c_str());
continue;
}
if (!device->dev->autoselect) {
Dmsg1(100, "Device %s not autoselect skipped.\n", devname.c_str());
continue; /* device is not available */
}
if (drive < 0 || drive == (int)device->dev->drive_index) {
if (drive < 0 || drive == (int)device->dev->drive) {
Dmsg1(20, "Found changer device %s\n", device->name());
found = true;
break;
}
Dmsg3(100, "Device %s drive wrong: want=%d got=%d skipping\n",
devname.c_str(), drive, (int)device->dev->drive_index);
devname.c_str(), drive, (int)device->dev->drive);
}
break; /* we found it but could not open a device */
}
Expand Down
9 changes: 6 additions & 3 deletions src/stored/status.c
Expand Up @@ -527,14 +527,17 @@ static void send_blocked_status(DEVICE *dev, STATUS_PKT *sp)
default:
break;
}
/* Send autochanger slot status */

/*
* Send autochanger slot status
*/
if (dev->is_autochanger()) {
if (dev->get_slot() > 0) {
len = Mmsg(msg, _(" Slot %d %s loaded in drive %d.\n"),
dev->get_slot(), dev->is_open() ? "is" : "was last", dev->drive_index);
dev->get_slot(), dev->is_open() ? "is" : "was last", dev->drive);
sendit(msg, len, sp);
} else if (dev->get_slot() <= 0) {
len = Mmsg(msg, _(" Drive %d is not loaded.\n"), dev->drive_index);
len = Mmsg(msg, _(" Drive %d is not loaded.\n"), dev->drive);
sendit(msg, len, sp);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/stored/stored_conf.h
Expand Up @@ -158,7 +158,8 @@ class DEVRES : public BRSRES {
bool drive_crypto_enabled; /* Enable hardware crypto */
bool query_crypto_status; /* Query device for crypto status */
bool collectstats; /* Set if statistics should be collected */
uint32_t drive_index; /* Autochanger drive index */
uint32_t drive; /* Autochanger logical drive number */
uint32_t drive_index; /* Autochanger physical drive index */
char cap_bits[CAP_BYTES]; /* Capabilities of this device */
utime_t max_changer_wait; /* Changer timeout */
utime_t max_rewind_wait; /* Maximum secs to wait for rewind */
Expand Down

0 comments on commit 7d83a52

Please sign in to comment.