-/*
- * Use Device command from Director
- * He tells is what Device Name to use, the Media Type,
- * the Pool Name, and the Pool Type.
- *
- * Ensure that the device exists and is opened, then store
- * the media and pool info in the JCR.
- */
-class DIRSTORE {
-public:
- alist *device;
- char name[MAX_NAME_LENGTH];
- char media_type[MAX_NAME_LENGTH];
- char pool_name[MAX_NAME_LENGTH];
- char pool_type[MAX_NAME_LENGTH];
-};
-
-class DIRDEVICE {
- alist *device;
-};
-
-static bool use_storage_cmd(JCR *jcr)
-{
- POOL_MEM store_name, dev_name, media_type, pool_name, pool_type;
- BSOCK *dir = jcr->dir_bsock;
- DEVRES *device;
- AUTOCHANGER *changer;
- int append;
- bool ok;
- int Copy, Stripe;
-
- /*
- * If there are multiple devices, the director sends us
- * use_device for each device that it wants to use.
- */
- Dmsg1(100, "<dird: %s", dir->msg);
- ok = sscanf(dir->msg, use_storage, store_name.c_str(),
- media_type.c_str(), pool_name.c_str(),
- pool_type.c_str(), &append, &Copy, &Stripe) == 7;
- if (ok) {
- unbash_spaces(store_name);
- unbash_spaces(media_type);
- unbash_spaces(pool_name);
- unbash_spaces(pool_type);
- if (bnet_recv(dir) <= 0) {
- return false;
- }
- ok = sscanf(dir->msg, use_device, dev_name.c_str()) == 1;
- if (!ok) {
- return false;
- }
- /* Eat to BNET_EOD */
- while (bnet_recv(dir) > 0) {
- }
- LockRes();
- foreach_res(device, R_DEVICE) {
- /* Find resource, and make sure we were able to open it */
- if (fnmatch(dev_name.c_str(), device->hdr.name, 0) == 0 &&
- strcmp(device->media_type, media_type.c_str()) == 0) {
- const int name_len = MAX_NAME_LENGTH;
- DCR *dcr;
- UnlockRes();
- if (!device->dev) {
- device->dev = init_dev(jcr, NULL, device);
- }
- if (!device->dev) {
- Jmsg(jcr, M_WARNING, 0, _("\n"
- " Device \"%s\" requested by DIR could not be opened or does not exist.\n"),
- dev_name.c_str());
- bnet_fsend(dir, NOT_open, dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- return false;
- }
- dcr = new_dcr(jcr, device->dev);
- if (!dcr) {
- bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- return false;
- }
- Dmsg1(100, "Found device %s\n", device->hdr.name);
- bstrncpy(dcr->pool_name, pool_name, name_len);
- bstrncpy(dcr->pool_type, pool_type, name_len);
- bstrncpy(dcr->media_type, media_type, name_len);
- bstrncpy(dcr->dev_name, dev_name, name_len);
- dcr->Copy = Copy;
- dcr->Stripe = Stripe;
- jcr->dcr = dcr;
- if (append == SD_APPEND) {
- ok = reserve_device_for_append(dcr);
- } else {
- ok = reserve_device_for_read(dcr);
- }
- if (!ok) {
- bnet_fsend(dir, _("3927 Could not reserve device: %s\n"), dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- free_dcr(jcr->dcr);
- return false;
- }
- Dmsg1(220, "Got: %s", dir->msg);
- bash_spaces(dev_name);
- ok = bnet_fsend(dir, OK_device, dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- return ok;
- }
- }
-
- foreach_res(changer, R_AUTOCHANGER) {
- /* Find resource, and make sure we were able to open it */
- if (fnmatch(dev_name.c_str(), changer->hdr.name, 0) == 0) {
- const int name_len = MAX_NAME_LENGTH;
- DCR *dcr;
- /* Try each device in this AutoChanger */
- foreach_alist(device, changer->device) {
- Dmsg1(100, "Try changer device %s\n", device->hdr.name);
- if (!device->dev) {
- device->dev = init_dev(jcr, NULL, device);
- }
- if (!device->dev) {
- Dmsg1(100, "Device %s could not be opened. Skipped\n", dev_name.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->hdr.name, dev_name.c_str());
- continue;
- }
- if (!device->dev->autoselect) {
- continue; /* device is not available */
- }
- dcr = new_dcr(jcr, device->dev);
- if (!dcr) {
- bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- UnlockRes();
- return false;
- }
- Dmsg1(100, "Found changer device %s\n", device->hdr.name);
- bstrncpy(dcr->pool_name, pool_name, name_len);
- bstrncpy(dcr->pool_type, pool_type, name_len);
- bstrncpy(dcr->media_type, media_type, name_len);
- bstrncpy(dcr->dev_name, dev_name, name_len);
- jcr->dcr = dcr;
- if (append == SD_APPEND) {
- ok = reserve_device_for_append(dcr);
- } else {
- ok = reserve_device_for_read(dcr);
- }
- if (!ok) {
- Jmsg(jcr, M_WARNING, 0, _("Could not reserve device: %s\n"), dev_name.c_str());
- free_dcr(jcr->dcr);
- continue;
- }
- Dmsg1(100, "Device %s opened.\n", dev_name.c_str());
- UnlockRes();
- pm_strcpy(dev_name, device->hdr.name);
- bash_spaces(dev_name);
- ok = bnet_fsend(dir, OK_device, dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- return ok;
- }
- break; /* we found it but could not open a device */
- }
- }
-
- UnlockRes();
- if (verbose) {
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
- Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
- }
- Jmsg(jcr, M_FATAL, 0, _("\n"
- " Device \"%s\" with MediaType \"%s\" requested by DIR not found in SD Device resources.\n"),
- dev_name.c_str(), media_type.c_str());
- bnet_fsend(dir, NO_device, dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- } else {
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
- if (verbose) {
- Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
- }
- Jmsg(jcr, M_FATAL, 0, _("Bad Use Device command: %s\n"), jcr->errmsg);
- bnet_fsend(dir, BAD_use, jcr->errmsg);
- Dmsg1(100, ">dird: %s\n", dir->msg);
- }
-
- return false; /* ERROR return */
-}
-