diff options
18 files changed, 250 insertions, 147 deletions
diff --git a/core/src/lib/plugin_registry.h b/core/src/lib/plugin_registry.h new file mode 100644 index 000000000..3b01a3c59 --- /dev/null +++ b/core/src/lib/plugin_registry.h @@ -0,0 +1,75 @@ +/* + BAREOS® - Backup Archiving REcovery Open Sourced + + Copyright (C) 2022-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 + License as published by the Free Software Foundation and included + in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +/* + * generic plugin registry where you can register factory functions based + * on a name. The registry is templated on the plugin's interface, thus the + * naming is automatically per plugin interface. + */ + +#ifndef BAREOS_LIB_PLUGIN_REGISTRY_H_ +#define BAREOS_LIB_PLUGIN_REGISTRY_H_ + +#include <memory> +#include <functional> +#include <unordered_map> + +template <typename T> class PluginRegistry { + using Factory = std::function<T*()>; + using Map = std::unordered_map<std::string, Factory>; + + static Map& GetMap() + { + // this ensures thread-safe initialization (Meyers' singleton) + static Map plugin_map; + return plugin_map; + } + + public: + static bool Add(const std::string& plugin_name, Factory plugin_factory) + { + GetMap().insert({plugin_name, plugin_factory}); + return true; + } + + static bool IsRegistered(const std::string& plugin_name) + { + auto m = GetMap(); + return m.find(plugin_name) != m.end(); + } + + static T* Create(const std::string& plugin_name) + { + Dmsg0(100, "Creating Instance for '%s'\n", plugin_name.c_str()); + return GetMap().at(plugin_name)(); + } + + static void DumpDbg() + { + Dmsg0(100, "Start plugin registry dump\n"); + for (auto const& [plugin_name, plugin_factory] : GetMap()) { + auto type = plugin_factory.target_type().name(); + Dmsg0(100, "Plugin name %s with factory %s\n", plugin_name.c_str(), type); + } + Dmsg0(100, "end plugin registry dump\n"); + } +}; +#endif // BAREOS_LIB_PLUGIN_REGISTRY_H_ diff --git a/core/src/stored/CMakeLists.txt b/core/src/stored/CMakeLists.txt index 3a5e11291..0555c150a 100644 --- a/core/src/stored/CMakeLists.txt +++ b/core/src/stored/CMakeLists.txt @@ -155,7 +155,9 @@ set_target_properties( SOVERSION "${BAREOS_VERSION_MAJOR}" ) -if(NOT ${HAVE_DYNAMIC_SD_BACKENDS}) +if(${HAVE_DYNAMIC_SD_BACKENDS}) + target_sources(bareossd PRIVATE sd_backends_dynamic.cc) +else() target_link_libraries(bareossd PRIVATE ${LIBBAREOSSD_LIBRARIES}) endif() diff --git a/core/src/stored/backends/CMakeLists.txt b/core/src/stored/backends/CMakeLists.txt index 0f4733c31..b2304f3bc 100644 --- a/core/src/stored/backends/CMakeLists.txt +++ b/core/src/stored/backends/CMakeLists.txt @@ -26,7 +26,7 @@ macro(add_sd_backend backend_name) add_library(${backend_name} MODULE) install(TARGETS ${backend_name} DESTINATION ${backenddir}) else() - add_library(${backend_name} STATIC) + add_library(${backend_name} OBJECT) target_link_libraries(bareossd PRIVATE ${backend_name}) endif() set_property(TARGET ${backend_name} PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -56,14 +56,20 @@ if(TARGET droplet) endif() +add_sd_backend(bareossd-file) add_sd_backend(bareossd-fifo) -target_sources(bareossd-fifo PRIVATE unix_fifo_device.cc) -if(HAVE_DARWIN_OS) - target_link_libraries(bareossd-fifo bareos bareossd) -endif() - add_sd_backend(bareossd-tape) -target_sources(bareossd-tape PRIVATE unix_tape_device.cc) +if(HAVE_WIN32) + target_sources(bareossd-file PRIVATE win32_file_device.cc) + target_sources(bareossd-fifo PRIVATE win32_fifo_device.cc) + target_sources(bareossd-tape PRIVATE win32_tape_device.cc) + + target_link_libraries(bareossd-file PRIVATE bareos) +else() + target_sources(bareossd-file PRIVATE unix_file_device.cc) + target_sources(bareossd-fifo PRIVATE unix_fifo_device.cc) + target_sources(bareossd-tape PRIVATE unix_tape_device.cc) +endif() if(HAVE_DYNAMIC_SD_BACKENDS) add_library(bareossd-gentape SHARED generic_tape_device.cc) @@ -76,7 +82,6 @@ else() target_sources(bareossd-tape PRIVATE generic_tape_device.cc) endif() -if(NOT HAVE_WIN32) - add_sd_backend(bareossd-file) - target_sources(bareossd-file PRIVATE unix_file_device.cc) +if(HAVE_DARWIN_OS) + target_link_libraries(bareossd-fifo bareos bareossd) endif() diff --git a/core/src/stored/backends/droplet_device.cc b/core/src/stored/backends/droplet_device.cc index b3d3bd0ce..0aaf6beaf 100644 --- a/core/src/stored/backends/droplet_device.cc +++ b/core/src/stored/backends/droplet_device.cc @@ -1027,12 +1027,6 @@ DropletDevice::~DropletDevice() unlock_mutex(mutex); } -class Backend : public BackendInterface { - public: - Device* GetDevice() override { return new DropletDevice; } -}; +REGISTER_SD_BACKEND(droplet, DropletDevice) -#ifdef HAVE_DYNAMIC_SD_BACKENDS -extern "C" BackendInterface* GetBackend(void) { return new Backend; } -#endif } /* namespace storagedaemon */ diff --git a/core/src/stored/backends/gfapi_device.cc b/core/src/stored/backends/gfapi_device.cc index 7b866eb5c..0497c9278 100644 --- a/core/src/stored/backends/gfapi_device.cc +++ b/core/src/stored/backends/gfapi_device.cc @@ -575,15 +575,7 @@ gfapi_device::gfapi_device() virtual_filename_ = GetPoolMemory(PM_FNAME); } -class Backend : public BackendInterface { - public: - Device* GetDevice() override { return new gfapi_device; } -}; - -# ifdef HAVE_DYNAMIC_SD_BACKENDS -extern "C" BackendInterface* GetBackend(void) { return new Backend; } -# endif - +REGISTER_SD_BACKEND(gfapi, gfapi_device); } /* namespace storagedaemon */ #endif /* HAVE_GFAPI */ diff --git a/core/src/stored/backends/unix_fifo_device.cc b/core/src/stored/backends/unix_fifo_device.cc index 612b52291..558d1e56d 100644 --- a/core/src/stored/backends/unix_fifo_device.cc +++ b/core/src/stored/backends/unix_fifo_device.cc @@ -315,14 +315,6 @@ boffset_t unix_fifo_device::d_lseek(DeviceControlRecord*, boffset_t, int) bool unix_fifo_device::d_truncate(DeviceControlRecord*) { return true; } -class Backend : public BackendInterface { - public: - Device* GetDevice() override { return new unix_fifo_device; } -}; - -#ifdef HAVE_DYNAMIC_SD_BACKENDS -extern "C" BackendInterface* GetBackend(void) { return new Backend; } -#endif - +REGISTER_SD_BACKEND(fifo, unix_fifo_device); } /* namespace storagedaemon */ diff --git a/core/src/stored/backends/unix_file_device.cc b/core/src/stored/backends/unix_file_device.cc index 5bf95f40d..f866c203e 100644 --- a/core/src/stored/backends/unix_file_device.cc +++ b/core/src/stored/backends/unix_file_device.cc @@ -37,6 +37,7 @@ #include "unix_file_device.h" #include "lib/berrno.h" #include "lib/util.h" +#include "lib/plugin_registry.h" namespace storagedaemon { @@ -311,13 +312,6 @@ bail_out: return true; } -class Backend : public BackendInterface { - public: - Device* GetDevice() override { return new unix_file_device; } -}; - -#ifdef HAVE_DYNAMIC_SD_BACKENDS -extern "C" BackendInterface* GetBackend(void) { return new Backend; } -#endif +REGISTER_SD_BACKEND(file, unix_file_device); } /* namespace storagedaemon */ diff --git a/core/src/stored/backends/unix_tape_device.cc b/core/src/stored/backends/unix_tape_device.cc index b7b62f771..b196b0f09 100644 --- a/core/src/stored/backends/unix_tape_device.cc +++ b/core/src/stored/backends/unix_tape_device.cc @@ -59,13 +59,6 @@ unix_tape_device::unix_tape_device() SetCap(CAP_ADJWRITESIZE); /* Adjust write size to min/max */ } -class Backend : public BackendInterface { - public: - Device* GetDevice() override { return new unix_tape_device; } -}; - -#ifdef HAVE_DYNAMIC_SD_BACKENDS -extern "C" BackendInterface* GetBackend(void) { return new Backend; } -#endif +REGISTER_SD_BACKEND(tape, unix_tape_device) } /* namespace storagedaemon */ diff --git a/core/src/win32/stored/backends/win32_fifo_device.cc b/core/src/stored/backends/win32_fifo_device.cc index 373ea5224..cb4ad27fa 100644 --- a/core/src/win32/stored/backends/win32_fifo_device.cc +++ b/core/src/stored/backends/win32_fifo_device.cc @@ -36,6 +36,7 @@ #include "stored/device_control_record.h" #include "stored/stored.h" #include "stored/autochanger.h" +#include "stored/sd_backends.h" namespace storagedaemon { @@ -318,4 +319,6 @@ boffset_t win32_fifo_device::d_lseek(DeviceControlRecord*, boffset_t, int) bool win32_fifo_device::d_truncate(DeviceControlRecord*) { return true; } +REGISTER_SD_BACKEND(fifo, win32_fifo_device); + } /* namespace storagedaemon */ diff --git a/core/src/win32/stored/backends/win32_fifo_device.h b/core/src/stored/backends/win32_fifo_device.h index 744cb06f8..a1f7716ff 100644 --- a/core/src/win32/stored/backends/win32_fifo_device.h +++ b/core/src/stored/backends/win32_fifo_device.h @@ -2,7 +2,7 @@ BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2015-2015 Planets Communications B.V. - Copyright (C) 2015-2021 Bareos GmbH & Co. KG + Copyright (C) 2015-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 @@ -25,8 +25,8 @@ * Marco van Wieringen, June 2014 */ -#ifndef BAREOS_WIN32_STORED_BACKENDS_WIN32_FIFO_DEVICE_H_ -#define BAREOS_WIN32_STORED_BACKENDS_WIN32_FIFO_DEVICE_H_ +#ifndef BAREOS_STORED_BACKENDS_WIN32_FIFO_DEVICE_H_ +#define BAREOS_STORED_BACKENDS_WIN32_FIFO_DEVICE_H_ #include "stored/dev.h" #include "lib/btimers.h" @@ -61,4 +61,4 @@ class win32_fifo_device : public Device { }; } /* namespace storagedaemon */ -#endif // BAREOS_WIN32_STORED_BACKENDS_WIN32_FIFO_DEVICE_H_ +#endif // BAREOS_STORED_BACKENDS_WIN32_FIFO_DEVICE_H_ diff --git a/core/src/win32/stored/backends/win32_file_device.cc b/core/src/stored/backends/win32_file_device.cc index e0b8bd1e2..07510845f 100644 --- a/core/src/win32/stored/backends/win32_file_device.cc +++ b/core/src/stored/backends/win32_file_device.cc @@ -30,6 +30,7 @@ #include "lib/berrno.h" #include "stored/device_control_record.h" #include "stored/stored.h" +#include "stored/sd_backends.h" #include "win32_file_device.h" namespace storagedaemon { @@ -290,4 +291,6 @@ bool win32_file_device::d_truncate(DeviceControlRecord* dcr) win32_file_device::win32_file_device() {} +REGISTER_SD_BACKEND(file, win32_file_device); + } /* namespace storagedaemon */ diff --git a/core/src/win32/stored/backends/win32_file_device.h b/core/src/stored/backends/win32_file_device.h index 07ac30049..31a87fa98 100644 --- a/core/src/win32/stored/backends/win32_file_device.h +++ b/core/src/stored/backends/win32_file_device.h @@ -2,7 +2,7 @@ BAREOS® - Backup Archiving REcovery Open Sourced Copyright (C) 2013-2014 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 @@ -25,8 +25,8 @@ * Marco van Wieringen, December 2013 */ -#ifndef BAREOS_WIN32_STORED_BACKENDS_WIN32_FILE_DEVICE_H_ -#define BAREOS_WIN32_STORED_BACKENDS_WIN32_FILE_DEVICE_H_ +#ifndef BAREOS_STORED_BACKENDS_WIN32_FILE_DEVICE_H_ +#define BAREOS_STORED_BACKENDS_WIN32_FILE_DEVICE_H_ #include "lib/util.h" namespace storagedaemon { @@ -51,4 +51,4 @@ class win32_file_device : public Device { }; } /* namespace storagedaemon */ -#endif // BAREOS_WIN32_STORED_BACKENDS_WIN32_FILE_DEVICE_H_ +#endif // BAREOS_STORED_BACKENDS_WIN32_FILE_DEVICE_H_ diff --git a/core/src/win32/stored/backends/win32_tape_device.cc b/core/src/stored/backends/win32_tape_device.cc index 35e6954a2..6f666217e 100644 --- a/core/src/win32/stored/backends/win32_tape_device.cc +++ b/core/src/stored/backends/win32_tape_device.cc @@ -43,6 +43,7 @@ #include "include/bareos.h" #include "stored/stored.h" +#include "stored/sd_backends.h" #include "generic_tape_device.h" #include "win32_tape_device.h" @@ -1110,4 +1111,6 @@ win32_tape_device::win32_tape_device() SetCap(CAP_ADJWRITESIZE); /* Adjust write size to min/max */ } +REGISTER_SD_BACKEND(tape, win32_tape_device) + } /* namespace storagedaemon */ diff --git a/core/src/win32/stored/backends/win32_tape_device.h b/core/src/stored/backends/win32_tape_device.h index a62d07dce..b5aad9609 100644 --- a/core/src/win32/stored/backends/win32_tape_device.h +++ b/core/src/stored/backends/win32_tape_device.h @@ -1,7 +1,7 @@ /* BAREOS® - Backup Archiving REcovery Open Sourced - Copyright (C) 2013-2021 Bareos GmbH & Co. KG + Copyright (C) 2013-2022 Bareos GmbH & Co. KG Copyright (C) 2013-2014 Planets Communications B.V. This program is Free Software; you can redistribute it and/or @@ -25,8 +25,8 @@ * Marco van Wieringen, December 2013 */ -#ifndef BAREOS_WIN32_STORED_BACKENDS_WIN32_TAPE_DEVICE_H_ -#define BAREOS_WIN32_STORED_BACKENDS_WIN32_TAPE_DEVICE_H_ +#ifndef BAREOS_STORED_BACKENDS_WIN32_TAPE_DEVICE_H_ +#define BAREOS_STORED_BACKENDS_WIN32_TAPE_DEVICE_H_ namespace storagedaemon { @@ -46,4 +46,4 @@ class win32_tape_device : public generic_tape_device { }; } /* namespace storagedaemon */ -#endif // BAREOS_WIN32_STORED_BACKENDS_WIN32_TAPE_DEVICE_H_ +#endif // BAREOS_STORED_BACKENDS_WIN32_TAPE_DEVICE_H_ diff --git a/core/src/stored/dev.cc b/core/src/stored/dev.cc index 90c91acf5..285396764 100644 --- a/core/src/stored/dev.cc +++ b/core/src/stored/dev.cc @@ -82,26 +82,6 @@ #include "include/jcr.h" #include "lib/berrno.h" -#ifndef HAVE_DYNAMIC_SD_BACKENDS -# ifdef HAVE_GFAPI -# include "backends/gfapi_device.h" -# endif -# ifdef HAVE_BAREOSSD_DROPLET_DEVICE -# include "backends/chunked_device.h" -# include "backends/droplet_device.h" -# endif -# include "backends/generic_tape_device.h" -# ifdef HAVE_WIN32 -# include "backends/win32_file_device.h" -# include "backends/win32_tape_device.h" -# include "backends/win32_fifo_device.h" -# else -# include "backends/unix_file_device.h" -# include "backends/unix_tape_device.h" -# include "backends/unix_fifo_device.h" -# endif -#endif /* HAVE_DYNAMIC_SD_BACKENDS */ - #ifndef O_NONBLOCK # define O_NONBLOCK 0 #endif @@ -142,77 +122,27 @@ Device* FactoryCreateDevice(JobControlRecord* jcr, Dmsg1(400, "max_block_size in device_resource res is %u\n", device_resource->max_block_size); - // If no device type specified, try to guess - if (device_resource->dev_type == DeviceType::B_UNKNOWN_DEV) { + if (!PluginRegistry<BackendInterface>::IsRegistered( + device_resource->dev_type)) { 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. - */ -#if !defined(HAVE_DYNAMIC_SD_BACKENDS) -# 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 - if (device_resource->dev_type == DeviceType::B_GFAPI_DEV) { - dev = new gfapi_device; - } else -# endif -# ifdef HAVE_BAREOSSD_DROPLET_DEVICE - if (device_resource->dev_type == DeviceType::B_DROPLET_DEV) { - dev = new DropletDevice; - } else -# endif - { - 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); - if (!dev) { - try { - Jmsg2(jcr, M_ERROR, 0, - _("Initialization of dynamic %s device \"%s\" with archive " - "device \"%s\" failed. Backend " - "library might be missing or backend directory incorrect.\n"), - 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 - } - return nullptr; - } -#endif // !defined(HAVE_DYNAMIC_SD_BACKENDS) + // FIXME: the PluginRegistry should return the device instead of the factory + // so we save one call and a delete. + auto factory + = PluginRegistry<BackendInterface>::Create(device_resource->dev_type); + Device* dev = factory->GetDevice(); + delete factory; dev->device_resource = device_resource; device_resource->dev = dev; InitiateDevice(jcr, dev); return dev; -} // namespace storagedaemon +} static void InitiateDevice(JobControlRecord* jcr, Device* dev) { diff --git a/core/src/stored/sd_backends.h b/core/src/stored/sd_backends.h index 72896cc53..2ecc69e6a 100644 --- a/core/src/stored/sd_backends.h +++ b/core/src/stored/sd_backends.h @@ -28,6 +28,8 @@ #ifndef BAREOS_STORED_SD_BACKENDS_H_ #define BAREOS_STORED_SD_BACKENDS_H_ +#include <lib/plugin_registry.h> + namespace storagedaemon { class BackendInterface { @@ -36,6 +38,12 @@ class BackendInterface { virtual Device* GetDevice() = 0; }; +template <typename T> class Backend : public BackendInterface { + public: + Device* GetDevice(void) override { return new T(); } +}; + +template <typename T> BackendInterface* BackendFactory(void) { return new T(); } extern "C" { typedef BackendInterface* (*t_backend_base)(void); @@ -52,7 +60,6 @@ BackendInterface* GetBackend(void); # define DYN_LIB_EXTENSION ".so" #endif - #if defined(HAVE_DYNAMIC_SD_BACKENDS) # include <map> void SetBackendDeviceDirectories(std::vector<std::string>&& new_backend_dirs); @@ -60,7 +67,15 @@ Device* InitBackendDevice(JobControlRecord* jcr, const std::string& device_type); void FlushAndCloseBackendDevices(); +bool LoadStorageBackend(const std::string& dev_type, + const std::vector<std::string>& backend_directories); #endif + +#define REGISTER_SD_BACKEND(backend_name, backend_class) \ + [[maybe_unused]] static bool backend_name##_backend_ \ + = PluginRegistry<BackendInterface>::Add( \ + #backend_name, BackendFactory<Backend<backend_class>>); + } /* namespace storagedaemon */ #endif // BAREOS_STORED_SD_BACKENDS_H_ diff --git a/core/src/stored/sd_backends_dynamic.cc b/core/src/stored/sd_backends_dynamic.cc new file mode 100644 index 000000000..4917f08b9 --- /dev/null +++ b/core/src/stored/sd_backends_dynamic.cc @@ -0,0 +1,78 @@ +/* + BAREOS® - Backup Archiving REcovery Open Sourced + + Copyright (C) 2022-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 + License as published by the Free Software Foundation and included + in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ +/** + * @file + * Dynamic loading of SD backend plugins. + */ + +#include "include/bareos.h" + +#include "stored/stored.h" +#include "sd_backends.h" +#include <dlfcn.h> + +namespace storagedaemon { + +#if defined(HAVE_WIN32) +static const char* kDynLibExtension = ".dll"; +#else +static const char* kDynLibExtension = ".so"; +#endif + +static bool LoadDynamicLibrary( + const std::string& library_file, + const std::vector<std::string>& library_directories) +{ + for (const auto& library_dir : library_directories) { + if (dlopen((library_dir + "/" + library_file).c_str(), RTLD_NOW)) { + Dmsg0(50, "Loaded dynamic library %s/%s\n", library_dir.c_str(), + library_file.c_str()); + return true; + } + Dmsg0(50, "Could not load library %s/%s: %s\n", library_dir.c_str(), + library_file.c_str(), dlerror()); + } + return false; +} + +bool LoadStorageBackend(const std::string& dev_type, + const std::vector<std::string>& backend_directories) +{ + using namespace std::string_literals; + + if (dev_type.empty() || backend_directories.empty()) { return false; } + + if (!LoadDynamicLibrary("libbareossd-"s + dev_type + kDynLibExtension, + backend_directories)) { + return false; + } + + if (!PluginRegistry<BackendInterface>::IsRegistered(dev_type)) { + Jmsg(nullptr, M_ERROR_TERM, 0, + "Loaded backend library for %s did not register its backend. This is " + "probably a bug in the backend library.\n", + dev_type.c_str()); + } + + return true; +} + +} /* namespace storagedaemon */ diff --git a/core/src/stored/stored_conf.cc b/core/src/stored/stored_conf.cc index 38fc5fd3c..4e00244ef 100644 --- a/core/src/stored/stored_conf.cc +++ b/core/src/stored/stored_conf.cc @@ -43,6 +43,7 @@ #define NEED_JANSSON_NAMESPACE 1 #include "lib/output_formatter.h" #include "lib/output_formatter_resource.h" +#include "lib/plugin_registry.h" #include "include/auth_types.h" #include "include/jcr.h" @@ -544,18 +545,40 @@ static void GuessMissingDeviceTypes(ConfigurationParser& my_config) } } -static void CheckDeviceBackends(ConfigurationParser& my_config) +static void CheckAndLoadDeviceBackends(ConfigurationParser& my_config) { PluginRegistry<BackendInterface>::DumpDbg(); +#if defined(HAVE_DYNAMIC_SD_BACKENDS) + auto storage_res + = dynamic_cast<StorageResource*>(my_config.GetNextRes(R_STORAGE, NULL)); +#endif + BareosResource* p = nullptr; while ((p = my_config.GetNextRes(R_DEVICE, p)) != nullptr) { DeviceResource* d = dynamic_cast<DeviceResource*>(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()); + if (!PluginRegistry<BackendInterface>::IsRegistered(d->dev_type)) { +#if defined(HAVE_DYNAMIC_SD_BACKENDS) + if (!storage_res || storage_res->backend_directories.empty()) { + Jmsg2(nullptr, M_ERROR_TERM, 0, + "Backend Directory not set. Cannot load dynamic backend %s\n", + d->dev_type.c_str()); + } + if (!LoadStorageBackend(d->dev_type, + storage_res->backend_directories)) { + Jmsg2(nullptr, M_ERROR_TERM, 0, + "Could not load storage backend %s for device %s.\n", + d->dev_type.c_str(), d->resource_name_); + } +#else + Jmsg2(nullptr, M_ERROR_TERM, 0, + "Backend %s for device %s not available.\n", d->dev_type.c_str(), + d->resource_name_); +#endif + } } } } @@ -564,6 +587,7 @@ static void ConfigReadyCallback(ConfigurationParser& my_config) { MultiplyConfiguredDevices(my_config); GuessMissingDeviceTypes(my_config); + CheckAndLoadDeviceBackends(my_config); CheckDropletDevices(my_config); } |