Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/bareos/bareos.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/lib/plugin_registry.h75
-rw-r--r--core/src/stored/CMakeLists.txt4
-rw-r--r--core/src/stored/backends/CMakeLists.txt25
-rw-r--r--core/src/stored/backends/droplet_device.cc8
-rw-r--r--core/src/stored/backends/gfapi_device.cc10
-rw-r--r--core/src/stored/backends/unix_fifo_device.cc10
-rw-r--r--core/src/stored/backends/unix_file_device.cc10
-rw-r--r--core/src/stored/backends/unix_tape_device.cc9
-rw-r--r--core/src/stored/backends/win32_fifo_device.cc (renamed from core/src/win32/stored/backends/win32_fifo_device.cc)3
-rw-r--r--core/src/stored/backends/win32_fifo_device.h (renamed from core/src/win32/stored/backends/win32_fifo_device.h)8
-rw-r--r--core/src/stored/backends/win32_file_device.cc (renamed from core/src/win32/stored/backends/win32_file_device.cc)3
-rw-r--r--core/src/stored/backends/win32_file_device.h (renamed from core/src/win32/stored/backends/win32_file_device.h)8
-rw-r--r--core/src/stored/backends/win32_tape_device.cc (renamed from core/src/win32/stored/backends/win32_tape_device.cc)3
-rw-r--r--core/src/stored/backends/win32_tape_device.h (renamed from core/src/win32/stored/backends/win32_tape_device.h)8
-rw-r--r--core/src/stored/dev.cc88
-rw-r--r--core/src/stored/sd_backends.h17
-rw-r--r--core/src/stored/sd_backends_dynamic.cc78
-rw-r--r--core/src/stored/stored_conf.cc30
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);
}