Skip to content

Commit

Permalink
stored: make device_type a std::string
Browse files Browse the repository at this point in the history
This patch turns the SD's device_type into a std::string, so we can use
arbitrary backend names without registering them in a central list of
backends.
  • Loading branch information
arogge committed Nov 7, 2022
1 parent 30dc42f commit 8aada01
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 188 deletions.
2 changes: 1 addition & 1 deletion core/src/lib/parse_conf.h
Expand Up @@ -166,7 +166,7 @@ enum
CFG_TYPE_META = 91, /* Meta tag */

// Storage daemon resource types
CFG_TYPE_DEVTYPE = 201, /* Device Type */
// CFG_TYPE_DEVTYPE = 201, /* Device Type */
CFG_TYPE_MAXBLOCKSIZE = 202, /* Maximum Blocksize */
CFG_TYPE_IODIRECTION = 203, /* AutoXflateMode IO Direction */
CFG_TYPE_CMPRSALGO = 204, /* Compression Algorithm */
Expand Down
2 changes: 1 addition & 1 deletion core/src/lib/res.cc
Expand Up @@ -2205,7 +2205,7 @@ static DatatypeName datatype_names[] = {
{CFG_TYPE_META, "META_TAG", "Meta tag"},

// Storage daemon resource types
{CFG_TYPE_DEVTYPE, "DEVICE_TYPE", "Device Type"},
//{CFG_TYPE_DEVTYPE, "DEVICE_TYPE", "Device Type"},
{CFG_TYPE_MAXBLOCKSIZE, "MAX_BLOCKSIZE", "Maximum Blocksize"},
{CFG_TYPE_IODIRECTION, "IO_DIRECTION", "IO Direction"},
{CFG_TYPE_CMPRSALGO, "COMPRESSION_ALGORITHM", "Compression Algorithm"},
Expand Down
7 changes: 7 additions & 0 deletions core/src/lib/util.cc
Expand Up @@ -35,6 +35,7 @@
#include "include/allow_deprecated.h"

#include <algorithm>
#include <cctype>
#include <sstream>
#include <string>
#include <vector>
Expand Down Expand Up @@ -1182,3 +1183,9 @@ regex_t* StringToRegex(const char* input)
}
return output;
}

void to_lower(std::string& s)
{
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c) { return std::tolower(c); });
}
1 change: 1 addition & 0 deletions core/src/lib/util.h
Expand Up @@ -91,5 +91,6 @@ std::string CreateDelimitedStringForSqlQueries(

std::string TPAsString(const std::chrono::system_clock::time_point& tp);
regex_t* StringToRegex(const char* input);
void to_lower(std::string& s);

#endif // BAREOS_LIB_UTIL_H_
181 changes: 90 additions & 91 deletions core/src/stored/dev.cc
Expand Up @@ -108,6 +108,8 @@

namespace storagedaemon {

static void InitiateDevice(JobControlRecord* jcr, Device* dev);

const char* Device::mode_to_str(DeviceMode mode)
{
static const char* modes[] = {"CREATE_READ_WRITE", "OPEN_READ_WRITE",
Expand Down Expand Up @@ -142,55 +144,51 @@ Device* FactoryCreateDevice(JobControlRecord* jcr,

// If no device type specified, try to guess
if (device_resource->dev_type == DeviceType::B_UNKNOWN_DEV) {
Jmsg2(jcr, M_ERROR, 0,
_("device type for %s was not identified. Cannot continue.\n"),
device_resource->archive_device_string);
Jmsg2(jcr, M_ERROR, 0, _("%s has an unknown device type %s\n"),
device_resource->archive_device_string,
device_resource->dev_type.c_str());
return nullptr;
}

Device* dev = nullptr;

/*
* When using dynamic loading use the InitBackendDevice() function
* for any type of device.
*/
/*
* When using dynamic loading use the InitBackendDevice() function
* for any type of device.
*/
#if !defined(HAVE_DYNAMIC_SD_BACKENDS)
switch (device_resource->dev_type) {
# ifdef HAVE_WIN32
if (device_resource->dev_type == DeviceType::B_FILE_DEV) {
dev = new win32_file_device;
} else if (device_resource->dev_type == DeviceType::B_TAPE_DEV) {
dev = new win32_tape_device;
} else if (device_resource->dev_type == DeviceType::B_FIFO_DEV) {
dev = new win32_fifo_device;
} else
# else
if (device_resource->dev_type == DeviceType::B_FILE_DEV) {
dev = new unix_file_device;
} else if (device_resource->dev_type == DeviceType::B_TAPE_DEV) {
dev = new unix_tape_device;
} else if (device_resource->dev_type == DeviceType::B_FIFO_DEV) {
dev = new unix_fifo_device;
} else
# endif
# ifdef HAVE_GFAPI
case DeviceType::B_GFAPI_DEV:
dev = new gfapi_device;
break;
if (device_resource->dev_type == DeviceType::B_GFAPI_DEV) {
dev = new gfapi_device;
} else
# endif
# ifdef HAVE_BAREOSSD_DROPLET_DEVICE
case DeviceType::B_DROPLET_DEV:
dev = new DropletDevice;
break;
if (device_resource->dev_type == DeviceType::B_DROPLET_DEV) {
dev = new DropletDevice;
} else
# endif
# ifdef HAVE_WIN32
case DeviceType::B_FILE_DEV:
dev = new win32_file_device;
break;
case DeviceType::B_TAPE_DEV:
dev = new win32_tape_device;
break;
case DeviceType::B_FIFO_DEV:
dev = new win32_fifo_device;
break;
# else
case DeviceType::B_FILE_DEV:
dev = new unix_file_device;
break;
case DeviceType::B_TAPE_DEV:
dev = new unix_tape_device;
break;
case DeviceType::B_FIFO_DEV:
dev = new unix_fifo_device;
break;
# endif
case DeviceType::B_UNKNOWN_DEV:
Jmsg2(jcr, M_ERROR, 0, _("%s has an unknown device type %d\n"),
device_resource->archive_device_string, device_resource->dev_type);
return nullptr;
{
Jmsg2(jcr, M_ERROR, 0, _("%s has unsupported device type %s\n"),
device_resource->archive_device_string,
device_resource->dev_type.c_str());
return nullptr;
}
#else
dev = InitBackendDevice(jcr, device_resource->dev_type);
Expand All @@ -200,8 +198,7 @@ Device* FactoryCreateDevice(JobControlRecord* jcr,
_("Initialization of dynamic %s device \"%s\" with archive "
"device \"%s\" failed. Backend "
"library might be missing or backend directory incorrect.\n"),
device_type_to_name_mapping.at(device_resource->dev_type),
device_resource->resource_name_,
device_resource->dev_type.c_str(), device_resource->resource_name_,
device_resource->archive_device_string);
} catch (const std::out_of_range&) {
// device_resource->dev_type could exceed limits of map
Expand All @@ -210,45 +207,54 @@ Device* FactoryCreateDevice(JobControlRecord* jcr,
}
#endif // !defined(HAVE_DYNAMIC_SD_BACKENDS)

dev->device_resource = device_resource;
device_resource->dev = dev;

InitiateDevice(jcr, dev);
return dev;
} // namespace storagedaemon

static void InitiateDevice(JobControlRecord* jcr, Device* dev)
{
dev->InvalidateSlotNumber(); /* unknown */

// Copy user supplied device parameters from Resource
dev->archive_device_string
= GetMemory(strlen(device_resource->archive_device_string) + 1);
PmStrcpy(dev->archive_device_string, device_resource->archive_device_string);
if (device_resource->device_options) {
dev->dev_options = GetMemory(strlen(device_resource->device_options) + 1);
PmStrcpy(dev->dev_options, device_resource->device_options);
= GetMemory(strlen(dev->device_resource->archive_device_string) + 1);
PmStrcpy(dev->archive_device_string,
dev->device_resource->archive_device_string);
if (dev->device_resource->device_options) {
dev->dev_options
= GetMemory(strlen(dev->device_resource->device_options) + 1);
PmStrcpy(dev->dev_options, dev->device_resource->device_options);
}
dev->prt_name = GetMemory(strlen(device_resource->archive_device_string)
+ strlen(device_resource->resource_name_) + 20);
dev->prt_name
= GetMemory(strlen(dev->device_resource->archive_device_string)
+ strlen(dev->device_resource->resource_name_) + 20);


Mmsg(dev->prt_name, "\"%s\" (%s)", device_resource->resource_name_,
device_resource->archive_device_string);
Mmsg(dev->prt_name, "\"%s\" (%s)", dev->device_resource->resource_name_,
dev->device_resource->archive_device_string);
Dmsg1(400, "Allocate dev=%s\n", dev->print_name());
CopySetBits(CAP_MAX, device_resource->cap_bits, dev->capabilities);
CopySetBits(CAP_MAX, dev->device_resource->cap_bits, dev->capabilities);


dev->min_block_size = device_resource->min_block_size;
dev->max_block_size = device_resource->max_block_size;
dev->min_block_size = dev->device_resource->min_block_size;
dev->max_block_size = dev->device_resource->max_block_size;
dev->max_volume_size = 0;
dev->max_file_size = device_resource->max_file_size;
dev->max_concurrent_jobs = device_resource->max_concurrent_jobs;
dev->volume_capacity = device_resource->volume_capacity;
dev->max_rewind_wait = device_resource->max_rewind_wait;
dev->max_open_wait = device_resource->max_open_wait;
dev->max_open_vols = device_resource->max_open_vols;
dev->vol_poll_interval = device_resource->vol_poll_interval;
dev->max_spool_size = device_resource->max_spool_size;
dev->drive = device_resource->drive;
dev->drive_index = device_resource->drive_index;
dev->autoselect = device_resource->autoselect;
dev->norewindonclose = device_resource->norewindonclose;
dev->dev_type = device_resource->dev_type;
dev->device_resource = device_resource;

device_resource->dev = dev;
dev->max_file_size = dev->device_resource->max_file_size;
dev->max_concurrent_jobs = dev->device_resource->max_concurrent_jobs;
dev->volume_capacity = dev->device_resource->volume_capacity;
dev->max_rewind_wait = dev->device_resource->max_rewind_wait;
dev->max_open_wait = dev->device_resource->max_open_wait;
dev->max_open_vols = dev->device_resource->max_open_vols;
dev->vol_poll_interval = dev->device_resource->vol_poll_interval;
dev->max_spool_size = dev->device_resource->max_spool_size;
dev->drive = dev->device_resource->drive;
dev->drive_index = dev->device_resource->drive_index;
dev->autoselect = dev->device_resource->autoselect;
dev->norewindonclose = dev->device_resource->norewindonclose;
dev->dev_type = dev->device_resource->dev_type;

if (dev->vol_poll_interval && dev->vol_poll_interval < 60) {
dev->vol_poll_interval = 60;
Expand All @@ -263,15 +269,16 @@ Device* FactoryCreateDevice(JobControlRecord* jcr,
*/
if (dev->IsFile() && dev->RequiresMount()) {
struct stat statp;
if (!device_resource->mount_point
|| stat(device_resource->mount_point, &statp) < 0) {
if (!dev->device_resource->mount_point
|| stat(dev->device_resource->mount_point, &statp) < 0) {
BErrNo be;
dev->dev_errno = errno;
Jmsg2(jcr, M_ERROR_TERM, 0, _("Unable to stat mount point %s: ERR=%s\n"),
device_resource->mount_point, be.bstrerror());
dev->device_resource->mount_point, be.bstrerror());
}

if (!device_resource->mount_command || !device_resource->unmount_command) {
if (!dev->device_resource->mount_command
|| !dev->device_resource->unmount_command) {
Jmsg0(jcr, M_ERROR_TERM, 0,
_("Mount and unmount commands must defined for a device which "
"requires mount.\n"));
Expand Down Expand Up @@ -361,8 +368,6 @@ Device* FactoryCreateDevice(JobControlRecord* jcr,
dev->initiated = true;
Dmsg3(100, "dev=%s dev_max_bs=%u max_bs=%u\n", dev->archive_device_string,
dev->device_resource->max_block_size, dev->max_block_size);

return dev;
}

// This routine initializes the device wait timers
Expand Down Expand Up @@ -575,7 +580,7 @@ bool Device::open(DeviceControlRecord* dcr, DeviceMode omode)
}

Dmsg4(100, "open dev: type=%d archive_device_string=%s vol=%s mode=%s\n",
dev_type, print_name(), getVolCatName(), mode_to_str(omode));
dev_type.c_str(), print_name(), getVolCatName(), mode_to_str(omode));

ClearBit(ST_LABEL, state);
ClearBit(ST_APPENDREADY, state);
Expand Down Expand Up @@ -941,21 +946,15 @@ bool Device::close(DeviceControlRecord* dcr)

if (!norewindonclose) { OfflineOrRewind(); }

switch (dev_type) {
case DeviceType::B_TAPE_DEV:
UnlockDoor();
[[fallthrough]];
default:
status = d_close(fd);
if (status < 0) {
BErrNo be;

Mmsg2(errmsg, _("Unable to close device %s. ERR=%s\n"), print_name(),
be.bstrerror());
dev_errno = errno;
retval = false;
}
break;
if (dev_type == DeviceType::B_TAPE_DEV) { UnlockDoor(); }
status = d_close(fd);
if (status < 0) {
BErrNo be;

Mmsg2(errmsg, _("Unable to close device %s. ERR=%s\n"), print_name(),
be.bstrerror());
dev_errno = errno;
retval = false;
}

unmount(dcr, 1); /* do unmount if required */
Expand Down
24 changes: 10 additions & 14 deletions core/src/stored/dev.h
Expand Up @@ -86,19 +86,6 @@ enum class DeviceMode : int
OPEN_WRITE_ONLY
};

enum class DeviceType : int
{
B_FILE_DEV = 1,
B_TAPE_DEV = 2,
B_FIFO_DEV = 3,
// B_VTL_DEV = 4,
B_GFAPI_DEV = 5,
B_DROPLET_DEV = 6,
// B_RADOS_DEV = 7,
// B_CEPHFS_DEV = 8
B_UNKNOWN_DEV = 0
};

// Generic status bits returned from StatusDev()
enum
{
Expand Down Expand Up @@ -183,6 +170,15 @@ enum
// Make sure you have enough bits to store all above bit fields.
#define ST_BYTES NbytesForBits(ST_MAX + 1)

struct DeviceType {
static constexpr std::string_view B_DROPLET_DEV = "droplet";
static constexpr std::string_view B_FIFO_DEV = "fifo";
static constexpr std::string_view B_FILE_DEV = "file";
static constexpr std::string_view B_GFAPI_DEV = "gfapi";
static constexpr std::string_view B_TAPE_DEV = "tape";
static constexpr std::string_view B_UNKNOWN_DEV = "";
};

/*
* Device structure definition.
*
Expand Down Expand Up @@ -222,7 +218,7 @@ class Device {
int dev_errno{}; /**< Our own errno */
int oflags{}; /**< Read/write flags */
DeviceMode open_mode{DeviceMode::kUndefined};
DeviceType dev_type{DeviceType::B_UNKNOWN_DEV};
std::string dev_type{};
bool autoselect{}; /**< Autoselect in autochanger */
bool norewindonclose{}; /**< Don't rewind tape drive on close */
bool initiated{}; /**< Set when FactoryCreateDevice() called */
Expand Down
4 changes: 2 additions & 2 deletions core/src/stored/device_resource.h
Expand Up @@ -3,7 +3,7 @@
Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
Copyright (C) 2011-2012 Planets Communications B.V.
Copyright (C) 2013-2021 Bareos GmbH & Co. KG
Copyright (C) 2013-2022 Bareos GmbH & Co. KG
This program is Free Software; you can redistribute it and/or
modify it under the terms of version three of the GNU Affero General Public
Expand Down Expand Up @@ -43,7 +43,7 @@ class DeviceResource : public BareosResource {
char* changer_command; /**< Changer command -- external program */
char* alert_command; /**< Alert command -- external program */
char* spool_directory; /**< Spool file directory */
DeviceType dev_type; /**< device type */
std::string dev_type; /**< device type */
uint32_t label_type; /**< label type */
bool autoselect; /**< Automatically select from AutoChanger */
bool norewindonclose; /**< Don't rewind tape drive on close */
Expand Down
4 changes: 2 additions & 2 deletions core/src/stored/mount.cc
Expand Up @@ -726,8 +726,8 @@ bool DeviceControlRecord::is_eod_valid()
} else {
Mmsg1(
jcr->errmsg,
_("Don't know how to check if EOD is valid for a device of type %d\n"),
dev->dev_type);
_("Don't know how to check if EOD is valid for a device of type %s\n"),
dev->dev_type.c_str());
Jmsg(jcr, M_ERROR, 0, jcr->errmsg);
Dmsg0(050, jcr->errmsg);
return false;
Expand Down

0 comments on commit 8aada01

Please sign in to comment.