Add APIs that allow to dynamically register driver backends so that the
list of available drivers does not need to be known during compile time.
This will allow us to modularize the storage driver on runtime.
---
src/storage/storage_backend.c | 111 ++++++++++++++++++++++-----------
src/storage/storage_backend.h | 5 ++
src/storage/storage_backend_disk.c | 7 +++
src/storage/storage_backend_disk.h | 4 +-
src/storage/storage_backend_fs.c | 27 ++++++++
src/storage/storage_backend_fs.h | 11 +---
src/storage/storage_backend_gluster.c | 13 +++-
src/storage/storage_backend_gluster.h | 5 +-
src/storage/storage_backend_iscsi.c | 7 +++
src/storage/storage_backend_iscsi.h | 4 +-
src/storage/storage_backend_logical.c | 7 +++
src/storage/storage_backend_logical.h | 4 +-
src/storage/storage_backend_mpath.c | 8 +++
src/storage/storage_backend_mpath.h | 4 +-
src/storage/storage_backend_rbd.c | 7 +++
src/storage/storage_backend_rbd.h | 4 +-
src/storage/storage_backend_scsi.c | 7 +++
src/storage/storage_backend_scsi.h | 4 +-
src/storage/storage_backend_sheepdog.c | 7 +++
src/storage/storage_backend_sheepdog.h | 4 +-
src/storage/storage_backend_vstorage.c | 7 +++
src/storage/storage_backend_vstorage.h | 4 +-
src/storage/storage_backend_zfs.c | 7 +++
src/storage/storage_backend_zfs.h | 4 +-
src/storage/storage_driver.c | 2 +
tests/virstoragetest.c | 4 ++
26 files changed, 200 insertions(+), 78 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 500d7567d..d8099be36 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -72,67 +72,106 @@
VIR_LOG_INIT("storage.storage_backend");
-static virStorageBackendPtr backends[] = {
-#if WITH_STORAGE_DIR
- &virStorageBackendDirectory,
-#endif
-#if WITH_STORAGE_FS
- &virStorageBackendFileSystem,
- &virStorageBackendNetFileSystem,
+#define VIR_STORAGE_BACKENDS_MAX 20
+
+static virStorageBackendPtr virStorageBackends[VIR_STORAGE_BACKENDS_MAX];
+static size_t virStorageBackendsCount;
+static virStorageFileBackendPtr virStorageFileBackends[VIR_STORAGE_BACKENDS_MAX];
+static size_t virStorageFileBackendsCount;
+
+#define VIR_STORAGE_BACKEND_REGISTER(name) \
+ if (name() < 0) \
+ return -1
+
+int
+virStorageBackendDriversRegister(void)
+{
+#if WITH_STORAGE_DIR || WITH_STORAGE_FS
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendFsRegister);
#endif
#if WITH_STORAGE_LVM
- &virStorageBackendLogical,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendLogicalRegister);
#endif
#if WITH_STORAGE_ISCSI
- &virStorageBackendISCSI,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendISCSIRegister);
#endif
#if WITH_STORAGE_SCSI
- &virStorageBackendSCSI,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendSCSIRegister);
#endif
#if WITH_STORAGE_MPATH
- &virStorageBackendMpath,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendMpathRegister);
#endif
#if WITH_STORAGE_DISK
- &virStorageBackendDisk,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendDiskRegister);
#endif
#if WITH_STORAGE_RBD
- &virStorageBackendRBD,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendRBDRegister);
#endif
#if WITH_STORAGE_SHEEPDOG
- &virStorageBackendSheepdog,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendSheepdogRegister);
#endif
#if WITH_STORAGE_GLUSTER
- &virStorageBackendGluster,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendGlusterRegister);
#endif
#if WITH_STORAGE_ZFS
- &virStorageBackendZFS,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendZFSRegister);
#endif
#if WITH_STORAGE_VSTORAGE
- &virStorageBackendVstorage,
+ VIR_STORAGE_BACKEND_REGISTER(virStorageBackendVstorageRegister);
#endif
- NULL
-};
+ return 0;
+}
+#undef VIR_STORAGE_BACKEND_REGISTER
-static virStorageFileBackendPtr fileBackends[] = {
-#if WITH_STORAGE_FS
- &virStorageFileBackendFile,
- &virStorageFileBackendBlock,
-#endif
-#if WITH_STORAGE_GLUSTER
- &virStorageFileBackendGluster,
-#endif
- NULL
-};
+
+int
+virStorageBackendRegister(virStorageBackendPtr backend)
+{
+ VIR_DEBUG("Registering storage backend '%s'",
+ virStorageTypeToString(backend->type));
+
+ if (virStorageBackendsCount >= VIR_STORAGE_BACKENDS_MAX) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Too many drivers, cannot register storage backend
'%s'"),
+ virStorageTypeToString(backend->type));
+ return -1;
+ }
+
+ virStorageBackends[virStorageBackendsCount] = backend;
+ virStorageBackendsCount++;
+ return 0;
+}
+
+
+int
+virStorageBackendFileRegister(virStorageFileBackendPtr backend)
+{
+ VIR_DEBUG("Registering storage file backend '%s' protocol
'%s'",
+ virStorageTypeToString(backend->type),
+ virStorageNetProtocolTypeToString(backend->protocol));
+
+ if (virStorageFileBackendsCount >= VIR_STORAGE_BACKENDS_MAX) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Too many drivers, cannot register storage file "
+ "backend '%s'"),
+ virStorageTypeToString(backend->type));
+ return -1;
+ }
+
+ virStorageFileBackends[virStorageFileBackendsCount] = backend;
+ virStorageFileBackendsCount++;
+ return 0;
+}
virStorageBackendPtr
virStorageBackendForType(int type)
{
size_t i;
- for (i = 0; backends[i]; i++)
- if (backends[i]->type == type)
- return backends[i];
+ for (i = 0; i < virStorageBackendsCount; i++)
+ if (virStorageBackends[i]->type == type)
+ return virStorageBackends[i];
virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing backend for pool type %d (%s)"),
@@ -148,13 +187,13 @@ virStorageFileBackendForTypeInternal(int type,
{
size_t i;
- for (i = 0; fileBackends[i]; i++) {
- if (fileBackends[i]->type == type) {
+ for (i = 0; i < virStorageFileBackendsCount; i++) {
+ if (virStorageFileBackends[i]->type == type) {
if (type == VIR_STORAGE_TYPE_NETWORK &&
- fileBackends[i]->protocol != protocol)
+ virStorageFileBackends[i]->protocol != protocol)
continue;
- return fileBackends[i];
+ return virStorageFileBackends[i];
}
}
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index b8fb368bb..ca6c19c45 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -198,4 +198,9 @@ struct _virStorageFileBackend {
virStorageFileBackendChown storageFileChown;
};
+int virStorageBackendDriversRegister(void);
+
+int virStorageBackendRegister(virStorageBackendPtr backend);
+int virStorageBackendFileRegister(virStorageFileBackendPtr backend);
+
#endif /* __VIR_STORAGE_BACKEND_H__ */
diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c
index 819f1e5c4..50bdd3646 100644
--- a/src/storage/storage_backend_disk.c
+++ b/src/storage/storage_backend_disk.c
@@ -937,3 +937,10 @@ virStorageBackend virStorageBackendDisk = {
.downloadVol = virStorageBackendVolDownloadLocal,
.wipeVol = virStorageBackendDiskVolWipe,
};
+
+
+int
+virStorageBackendDiskRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendDisk);
+}
diff --git a/src/storage/storage_backend_disk.h b/src/storage/storage_backend_disk.h
index aaabe6224..e614ca278 100644
--- a/src/storage/storage_backend_disk.h
+++ b/src/storage/storage_backend_disk.h
@@ -24,8 +24,6 @@
#ifndef __VIR_STORAGE_BACKEND_DISK_H__
# define __VIR_STORAGE_BACKEND_DISK_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendDisk;
+int virStorageBackendDiskRegister(void);
#endif /* __VIR_STORAGE_BACKEND_DISK_H__ */
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 54bcc5777..551fd945d 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -877,3 +877,30 @@ virStorageFileBackend virStorageFileBackendDir = {
.storageFileGetUniqueIdentifier = virStorageFileBackendFileGetUniqueIdentifier,
};
+
+
+int
+virStorageBackendFsRegister(void)
+{
+ if (virStorageBackendRegister(&virStorageBackendDirectory) < 0)
+ return -1;
+
+#if WITH_STORAGE_FS
+ if (virStorageBackendRegister(&virStorageBackendFileSystem) < 0)
+ return -1;
+
+ if (virStorageBackendRegister(&virStorageBackendNetFileSystem) < 0)
+ return -1;
+#endif /* WITH_STORAGE_FS */
+
+ if (virStorageBackendFileRegister(&virStorageFileBackendFile) < 0)
+ return -1;
+
+ if (virStorageBackendFileRegister(&virStorageFileBackendBlock) < 0)
+ return -1;
+
+ if (virStorageBackendFileRegister(&virStorageFileBackendDir) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/src/storage/storage_backend_fs.h b/src/storage/storage_backend_fs.h
index 94fe11138..8f381352c 100644
--- a/src/storage/storage_backend_fs.h
+++ b/src/storage/storage_backend_fs.h
@@ -24,15 +24,6 @@
#ifndef __VIR_STORAGE_BACKEND_FS_H__
# define __VIR_STORAGE_BACKEND_FS_H__
-# include "storage_backend.h"
+int virStorageBackendFsRegister(void);
-# if WITH_STORAGE_FS
-extern virStorageBackend virStorageBackendFileSystem;
-extern virStorageBackend virStorageBackendNetFileSystem;
-# endif
-
-extern virStorageBackend virStorageBackendDirectory;
-
-extern virStorageFileBackend virStorageFileBackendFile;
-extern virStorageFileBackend virStorageFileBackendBlock;
#endif /* __VIR_STORAGE_BACKEND_FS_H__ */
diff --git a/src/storage/storage_backend_gluster.c
b/src/storage/storage_backend_gluster.c
index 7be2d9e81..52c9ee372 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -843,6 +843,17 @@ virStorageFileBackend virStorageFileBackendGluster = {
.storageFileChown = virStorageFileBackendGlusterChown,
.storageFileGetUniqueIdentifier = virStorageFileBackendGlusterGetUniqueIdentifier,
+};
-};
+int
+virStorageBackendGlusterRegister(void)
+{
+ if (virStorageBackendRegister(&virStorageBackendGluster) < 0)
+ return -1;
+
+ if (virStorageBackendFileRegister(&virStorageFileBackendGluster) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/src/storage/storage_backend_gluster.h
b/src/storage/storage_backend_gluster.h
index 679601624..91b8d8275 100644
--- a/src/storage/storage_backend_gluster.h
+++ b/src/storage/storage_backend_gluster.h
@@ -22,9 +22,6 @@
#ifndef __VIR_STORAGE_BACKEND_GLUSTER_H__
# define __VIR_STORAGE_BACKEND_GLUSTER_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendGluster;
-extern virStorageFileBackend virStorageFileBackendGluster;
+int virStorageBackendGlusterRegister(void);
#endif /* __VIR_STORAGE_BACKEND_GLUSTER_H__ */
diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c
index 281334124..866fa7415 100644
--- a/src/storage/storage_backend_iscsi.c
+++ b/src/storage/storage_backend_iscsi.c
@@ -437,3 +437,10 @@ virStorageBackend virStorageBackendISCSI = {
.downloadVol = virStorageBackendVolDownloadLocal,
.wipeVol = virStorageBackendVolWipeLocal,
};
+
+
+int
+virStorageBackendISCSIRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendISCSI);
+}
diff --git a/src/storage/storage_backend_iscsi.h b/src/storage/storage_backend_iscsi.h
index da3b22c44..98d2b3ef2 100644
--- a/src/storage/storage_backend_iscsi.h
+++ b/src/storage/storage_backend_iscsi.h
@@ -24,8 +24,6 @@
#ifndef __VIR_STORAGE_BACKEND_ISCSI_H__
# define __VIR_STORAGE_BACKEND_ISCSI_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendISCSI;
+int virStorageBackendISCSIRegister(void);
#endif /* __VIR_STORAGE_BACKEND_ISCSI_H__ */
diff --git a/src/storage/storage_backend_logical.c
b/src/storage/storage_backend_logical.c
index b0191aa45..756c62e90 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -1112,3 +1112,10 @@ virStorageBackend virStorageBackendLogical = {
.downloadVol = virStorageBackendVolDownloadLocal,
.wipeVol = virStorageBackendLogicalVolWipe,
};
+
+
+int
+virStorageBackendLogicalRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendLogical);
+}
diff --git a/src/storage/storage_backend_logical.h
b/src/storage/storage_backend_logical.h
index c646fd6a6..c0f62cd18 100644
--- a/src/storage/storage_backend_logical.h
+++ b/src/storage/storage_backend_logical.h
@@ -24,8 +24,6 @@
#ifndef __VIR_STORAGE_BACKEND_LOGICAL_H__
# define __VIR_STORAGE_BACKEND_LOGICAL_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendLogical;
+int virStorageBackendLogicalRegister(void);
#endif /* __VIR_STORAGE_BACKEND_LOGICAL_H__ */
diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_backend_mpath.c
index a5d692a07..4bb38bb52 100644
--- a/src/storage/storage_backend_mpath.c
+++ b/src/storage/storage_backend_mpath.c
@@ -32,6 +32,7 @@
#include "virerror.h"
#include "storage_conf.h"
#include "storage_backend.h"
+#include "storage_backend_mpath.h"
#include "viralloc.h"
#include "virlog.h"
#include "virfile.h"
@@ -278,3 +279,10 @@ virStorageBackend virStorageBackendMpath = {
.downloadVol = virStorageBackendVolDownloadLocal,
.wipeVol = virStorageBackendVolWipeLocal,
};
+
+
+int
+virStorageBackendMpathRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendMpath);
+}
diff --git a/src/storage/storage_backend_mpath.h b/src/storage/storage_backend_mpath.h
index b66664576..c14dcc3cf 100644
--- a/src/storage/storage_backend_mpath.h
+++ b/src/storage/storage_backend_mpath.h
@@ -24,8 +24,6 @@
#ifndef __VIR_STORAGE_BACKEND_MPATH_H__
# define __VIR_STORAGE_BACKEND_MPATH_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendMpath;
+int virStorageBackendMpathRegister(void);
#endif /* __VIR_STORAGE_BACKEND_MPATH_H__ */
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index 45beb107a..c806d6d30 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -1294,3 +1294,10 @@ virStorageBackend virStorageBackendRBD = {
.resizeVol = virStorageBackendRBDResizeVol,
.wipeVol = virStorageBackendRBDVolWipe
};
+
+
+int
+virStorageBackendRBDRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendRBD);
+}
diff --git a/src/storage/storage_backend_rbd.h b/src/storage/storage_backend_rbd.h
index e60caa957..21a43fd51 100644
--- a/src/storage/storage_backend_rbd.h
+++ b/src/storage/storage_backend_rbd.h
@@ -23,8 +23,6 @@
#ifndef __VIR_STORAGE_BACKEND_RBD_H__
# define __VIR_STORAGE_BACKEND_RBD_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendRBD;
+int virStorageBackendRBDRegister(void);
#endif /* __VIR_STORAGE_BACKEND_RBD_H__ */
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
index 0cc11486b..6e2e22a8c 100644
--- a/src/storage/storage_backend_scsi.c
+++ b/src/storage/storage_backend_scsi.c
@@ -531,3 +531,10 @@ virStorageBackend virStorageBackendSCSI = {
.downloadVol = virStorageBackendVolDownloadLocal,
.wipeVol = virStorageBackendVolWipeLocal,
};
+
+
+int
+virStorageBackendSCSIRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendSCSI);
+}
diff --git a/src/storage/storage_backend_scsi.h b/src/storage/storage_backend_scsi.h
index 1ba53a57c..efd01658b 100644
--- a/src/storage/storage_backend_scsi.h
+++ b/src/storage/storage_backend_scsi.h
@@ -24,8 +24,6 @@
#ifndef __VIR_STORAGE_BACKEND_SCSI_H__
# define __VIR_STORAGE_BACKEND_SCSI_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendSCSI;
+int virStorageBackendSCSIRegister(void);
#endif /* __VIR_STORAGE_BACKEND_SCSI_H__ */
diff --git a/src/storage/storage_backend_sheepdog.c
b/src/storage/storage_backend_sheepdog.c
index 36458a562..a9a2301e6 100644
--- a/src/storage/storage_backend_sheepdog.c
+++ b/src/storage/storage_backend_sheepdog.c
@@ -417,3 +417,10 @@ virStorageBackend virStorageBackendSheepdog = {
.deleteVol = virStorageBackendSheepdogDeleteVol,
.resizeVol = virStorageBackendSheepdogResizeVol,
};
+
+
+int
+virStorageBackendSheepdogRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendSheepdog);
+}
diff --git a/src/storage/storage_backend_sheepdog.h
b/src/storage/storage_backend_sheepdog.h
index df2ead5ed..e96832309 100644
--- a/src/storage/storage_backend_sheepdog.h
+++ b/src/storage/storage_backend_sheepdog.h
@@ -27,8 +27,6 @@
#ifndef __VIR_STORAGE_BACKEND_SHEEPDOG_H__
# define __VIR_STORAGE_BACKEND_SHEEPDOG_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendSheepdog;
+int virStorageBackendSheepdogRegister(void);
#endif /* __VIR_STORAGE_BACKEND_SHEEPDOG_H__ */
diff --git a/src/storage/storage_backend_vstorage.c
b/src/storage/storage_backend_vstorage.c
index ac1fa756c..fb0613853 100644
--- a/src/storage/storage_backend_vstorage.c
+++ b/src/storage/storage_backend_vstorage.c
@@ -183,3 +183,10 @@ virStorageBackend virStorageBackendVstorage = {
.downloadVol = virStorageBackendVolDownloadLocal,
.wipeVol = virStorageBackendVolWipeLocal,
};
+
+
+int
+virStorageBackendVstorageRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendVstorage);
+}
diff --git a/src/storage/storage_backend_vstorage.h
b/src/storage/storage_backend_vstorage.h
index 262e454c0..0a29c597f 100644
--- a/src/storage/storage_backend_vstorage.h
+++ b/src/storage/storage_backend_vstorage.h
@@ -21,8 +21,6 @@
#ifndef __VIR_STORAGE_BACKEND_VSTORAGE_H__
# define __VIR_STORAGE_BACKEND_VSTORAGE_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendVstorage;
+int virStorageBackendVstorageRegister(void);
#endif /* __VIR_STORAGE_BACKEND_VSTORAGE_H__ */
diff --git a/src/storage/storage_backend_zfs.c b/src/storage/storage_backend_zfs.c
index 70c533a7f..004d95a53 100644
--- a/src/storage/storage_backend_zfs.c
+++ b/src/storage/storage_backend_zfs.c
@@ -467,3 +467,10 @@ virStorageBackend virStorageBackendZFS = {
.uploadVol = virStorageBackendVolUploadLocal,
.downloadVol = virStorageBackendVolDownloadLocal,
};
+
+
+int
+virStorageBackendZFSRegister(void)
+{
+ return virStorageBackendRegister(&virStorageBackendZFS);
+}
diff --git a/src/storage/storage_backend_zfs.h b/src/storage/storage_backend_zfs.h
index 4c34b5909..076ff2799 100644
--- a/src/storage/storage_backend_zfs.h
+++ b/src/storage/storage_backend_zfs.h
@@ -22,8 +22,6 @@
#ifndef __VIR_STORAGE_BACKEND_ZFS_H__
# define __VIR_STORAGE_BACKEND_ZFS_H__
-# include "storage_backend.h"
-
-extern virStorageBackend virStorageBackendZFS;
+int virStorageBackendZFSRegister(void);
#endif /* __VIR_STORAGE_BACKEND_ZFS_H__ */
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index ed4772ad9..7fafbcf75 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -2840,6 +2840,8 @@ static virStateDriver stateDriver = {
int storageRegister(void)
{
+ if (virStorageBackendDriversRegister() < 0)
+ return -1;
if (virSetSharedStorageDriver(&storageDriver) < 0)
return -1;
if (virRegisterStateDriver(&stateDriver) < 0)
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
index f766df115..d715fd762 100644
--- a/tests/virstoragetest.c
+++ b/tests/virstoragetest.c
@@ -32,6 +32,7 @@
#include "dirname.h"
#include "storage/storage_driver.h"
+#include "storage/storage_backend.h"
#define VIR_FROM_THIS VIR_FROM_NONE
@@ -731,6 +732,9 @@ mymain(void)
virStorageSourcePtr chain2; /* short for chain->backingStore */
virStorageSourcePtr chain3; /* short for chain2->backingStore */
+ if (virStorageBackendDriversRegister() < 0)
+ return -1;
+
/* Prep some files with qemu-img; if that is not found on PATH, or
* if it lacks support for qcow2 and qed, skip this test. */
if ((ret = testPrepImages()) != 0)
--
2.11.0