diff --git a/core/src/lib/parse_conf.h b/core/src/lib/parse_conf.h index 7368224ea74..9a0507df5aa 100644 --- a/core/src/lib/parse_conf.h +++ b/core/src/lib/parse_conf.h @@ -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 */ diff --git a/core/src/lib/res.cc b/core/src/lib/res.cc index 54c7d05f1c9..1279b6e50d9 100644 --- a/core/src/lib/res.cc +++ b/core/src/lib/res.cc @@ -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"}, diff --git a/core/src/lib/util.cc b/core/src/lib/util.cc index 52a96e6d6da..3f7231491aa 100644 --- a/core/src/lib/util.cc +++ b/core/src/lib/util.cc @@ -35,6 +35,7 @@ #include "include/allow_deprecated.h" #include +#include #include #include #include @@ -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); }); +} diff --git a/core/src/lib/util.h b/core/src/lib/util.h index fdaa58b1a73..d0d62c3f110 100644 --- a/core/src/lib/util.h +++ b/core/src/lib/util.h @@ -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_ diff --git a/core/src/stored/dev.cc b/core/src/stored/dev.cc index d9cf8f119ba..90c91acf5cf 100644 --- a/core/src/stored/dev.cc +++ b/core/src/stored/dev.cc @@ -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", @@ -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); @@ -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 @@ -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; @@ -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")); @@ -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 @@ -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); @@ -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 */ diff --git a/core/src/stored/dev.h b/core/src/stored/dev.h index 9be47b5dec0..e8e8b2ed7c7 100644 --- a/core/src/stored/dev.h +++ b/core/src/stored/dev.h @@ -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 { @@ -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. * @@ -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 */ diff --git a/core/src/stored/device_resource.h b/core/src/stored/device_resource.h index 987cf2708b0..40a1c927ded 100644 --- a/core/src/stored/device_resource.h +++ b/core/src/stored/device_resource.h @@ -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 @@ -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 */ diff --git a/core/src/stored/mount.cc b/core/src/stored/mount.cc index 0091d714b8a..33ab5e10768 100644 --- a/core/src/stored/mount.cc +++ b/core/src/stored/mount.cc @@ -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; diff --git a/core/src/stored/sd_backends.cc b/core/src/stored/sd_backends.cc index 6f3aadb178a..f19d88c974d 100644 --- a/core/src/stored/sd_backends.cc +++ b/core/src/stored/sd_backends.cc @@ -43,14 +43,14 @@ namespace storagedaemon { struct BackendDeviceLibraryDescriptor { public: - DeviceType device_type{DeviceType::B_UNKNOWN_DEV}; + std::string device_type{}; private: void* dynamic_library_handle{}; BackendInterface* backend_interface{}; public: - BackendDeviceLibraryDescriptor(DeviceType t_device_type, + BackendDeviceLibraryDescriptor(const std::string& t_device_type, void* t_dynamic_library_handle, BackendInterface* t_backend_interface) : device_type(t_device_type) @@ -71,31 +71,14 @@ struct BackendDeviceLibraryDescriptor { const BackendDeviceLibraryDescriptor& other) = delete; BackendDeviceLibraryDescriptor(BackendDeviceLibraryDescriptor&& other) - { - device_type = other.device_type; - std::swap(dynamic_library_handle, other.dynamic_library_handle); - std::swap(backend_interface, other.backend_interface); - } + = default; BackendDeviceLibraryDescriptor& operator=( BackendDeviceLibraryDescriptor&& other) - { - device_type = other.device_type; - std::swap(dynamic_library_handle, other.dynamic_library_handle); - std::swap(backend_interface, other.backend_interface); - return *this; - } + = default; Device* GetDevice() { return backend_interface->GetDevice(); } }; -const std::map device_type_to_name_mapping - = {{DeviceType::B_FIFO_DEV, "fifo"}, - {DeviceType::B_FILE_DEV, "file"}, - {DeviceType::B_TAPE_DEV, "tape"}, - {DeviceType::B_GFAPI_DEV, "gfapi"}, - {DeviceType::B_DROPLET_DEV, "droplet"}, - {DeviceType::B_UNKNOWN_DEV, nullptr}}; - static std::vector> loaded_backends; static std::vector backend_directories; @@ -112,20 +95,14 @@ static inline const char* get_dlerror() return error != nullptr ? error : ""; } -Device* InitBackendDevice(JobControlRecord* jcr, DeviceType device_type) +Device* InitBackendDevice(JobControlRecord* jcr, const std::string& device_type) { if (backend_directories.empty()) { - Jmsg(jcr, M_ERROR_TERM, 0, _("Catalog Backends Dir not configured.\n")); + Jmsg(jcr, M_ERROR_TERM, 0, _("storage backend dir not configured.\n")); // does not return } - const char* interface_name = nullptr; - - try { - interface_name = device_type_to_name_mapping.at(device_type); - } catch (const std::out_of_range&) { - return nullptr; - } + const char* interface_name = device_type.c_str(); for (const auto& b : loaded_backends) { if (b->device_type == device_type) { return b->GetDevice(); } diff --git a/core/src/stored/sd_backends.h b/core/src/stored/sd_backends.h index b16681246cf..72896cc536a 100644 --- a/core/src/stored/sd_backends.h +++ b/core/src/stored/sd_backends.h @@ -56,10 +56,10 @@ BackendInterface* GetBackend(void); #if defined(HAVE_DYNAMIC_SD_BACKENDS) # include void SetBackendDeviceDirectories(std::vector&& new_backend_dirs); -Device* InitBackendDevice(JobControlRecord* jcr, DeviceType device_type); +Device* InitBackendDevice(JobControlRecord* jcr, + const std::string& device_type); void FlushAndCloseBackendDevices(); -extern const std::map device_type_to_name_mapping; #endif } /* namespace storagedaemon */ diff --git a/core/src/stored/stored_conf.cc b/core/src/stored/stored_conf.cc index d3b391517a0..38fc5fd3c40 100644 --- a/core/src/stored/stored_conf.cc +++ b/core/src/stored/stored_conf.cc @@ -147,7 +147,7 @@ static ResourceItem dev_items[] = { {"Description", CFG_TYPE_STR, ITEM(res_dev, description_), 0, 0, NULL, NULL, "The Description directive provides easier human recognition, but is not used by Bareos directly."}, {"MediaType", CFG_TYPE_STRNAME, ITEM(res_dev, media_type), 0, CFG_ITEM_REQUIRED, NULL, NULL, NULL}, - {"DeviceType", CFG_TYPE_DEVTYPE, ITEM(res_dev, dev_type), 0, 0, NULL, NULL, NULL}, + {"DeviceType", CFG_TYPE_STDSTR, ITEM(res_dev, dev_type), 0, CFG_ITEM_DEFAULT, "", NULL, NULL}, {"ArchiveDevice", CFG_TYPE_STRNAME, ITEM(res_dev, archive_device_string), 0, CFG_ITEM_REQUIRED, NULL, NULL, NULL}, {"DeviceOptions", CFG_TYPE_STR, ITEM(res_dev, device_options), 0, 0, NULL, "15.2.0-", NULL}, {"DiagnosticDevice", CFG_TYPE_STRNAME, ITEM(res_dev, diag_device_name), 0, 0, NULL, NULL, NULL}, @@ -247,21 +247,6 @@ static ResourceTable resources[] = { static struct s_kw authentication_methods[] = {{"None", AT_NONE}, {"Clear", AT_CLEAR}, {"MD5", AT_MD5}, {NULL, 0}}; -struct s_dvt_kw { - const char* name; - DeviceType token; -}; - -static s_dvt_kw device_types[] - = {{"file", DeviceType::B_FILE_DEV}, - {"tape", DeviceType::B_TAPE_DEV}, - {"fifo", DeviceType::B_FIFO_DEV}, - {"gfapi", DeviceType::B_GFAPI_DEV}, - /* compatibility: object have been renamed to droplet */ - {"object", DeviceType::B_DROPLET_DEV}, - {"droplet", DeviceType::B_DROPLET_DEV}, - {nullptr, DeviceType::B_UNKNOWN_DEV}}; - struct s_io_kw { const char* name; AutoXflateMode token; @@ -328,27 +313,6 @@ static void StoreAutopassword(LEX* lc, ResourceItem* item, int index, int pass) } } -static void StoreDeviceType(LEX* lc, ResourceItem* item, int index, int) -{ - int i; - - LexGetToken(lc, BCT_NAME); - // Store the label pass 2 so that type is defined - for (i = 0; device_types[i].name; i++) { - if (Bstrcasecmp(lc->str, device_types[i].name)) { - SetItemVariable(*item, device_types[i].token); - i = 0; - break; - } - } - if (i != 0) { - scan_err1(lc, _("Expected a Device Type keyword, got: %s"), lc->str); - } - ScanToEol(lc); - SetBit(index, (*item->allocated_resource)->item_present_); - ClearBit(index, (*item->allocated_resource)->inherit_content_); -} - // Store Maximum Block Size, and check it is not greater than MAX_BLOCK_LENGTH static void StoreMaxblocksize(LEX* lc, ResourceItem* item, int index, int pass) { @@ -447,9 +411,6 @@ static void ParseConfigCb(LEX* lc, case CFG_TYPE_AUTHTYPE: StoreAuthenticationType(lc, item, index, pass); break; - case CFG_TYPE_DEVTYPE: - StoreDeviceType(lc, item, index, pass); - break; case CFG_TYPE_MAXBLOCKSIZE: StoreMaxblocksize(lc, item, index, pass); break; @@ -583,6 +544,22 @@ static void GuessMissingDeviceTypes(ConfigurationParser& my_config) } } +static void CheckDeviceBackends(ConfigurationParser& my_config) +{ + PluginRegistry::DumpDbg(); + + BareosResource* p = nullptr; + + while ((p = my_config.GetNextRes(R_DEVICE, p)) != nullptr) { + DeviceResource* d = dynamic_cast(p); + if (d) { + to_lower(d->dev_type); + Dmsg0(50, "device %s has dev_type %s\n", d->resource_name_, + d->dev_type.c_str()); + } + } +} + static void ConfigReadyCallback(ConfigurationParser& my_config) { MultiplyConfiguredDevices(my_config); diff --git a/docs/manuals/source/include/autogenerated/bareos-dir-config-schema.json b/docs/manuals/source/include/autogenerated/bareos-dir-config-schema.json index 9e408c4d378..66cccf090d8 100644 --- a/docs/manuals/source/include/autogenerated/bareos-dir-config-schema.json +++ b/docs/manuals/source/include/autogenerated/bareos-dir-config-schema.json @@ -3393,10 +3393,6 @@ "number": 91, "description": "Meta tag" }, - "DEVICE_TYPE": { - "number": 201, - "description": "Device Type" - }, "MAX_BLOCKSIZE": { "number": 202, "description": "Maximum Blocksize" diff --git a/docs/manuals/source/include/autogenerated/bareos-sd-config-schema.json b/docs/manuals/source/include/autogenerated/bareos-sd-config-schema.json index 41d3c8208a7..0275769df49 100644 --- a/docs/manuals/source/include/autogenerated/bareos-sd-config-schema.json +++ b/docs/manuals/source/include/autogenerated/bareos-sd-config-schema.json @@ -505,8 +505,9 @@ "required": true }, "DeviceType": { - "datatype": "DEVICE_TYPE", + "datatype": "STRING", "code": 0, + "default_value": "", "equals": true }, "ArchiveDevice": {