From f813fe810fc3f0ce839f450e662e0173d40a5ce1 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Fri, 13 Jan 2017 16:50:11 +0100 Subject: [PATCH] storage: backend: Refactor registration of the backend drivers 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 500d7567dd..d8099be368 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 b8fb368bb7..ca6c19c457 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 819f1e5c4e..50bdd3646e 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 aaabe62244..e614ca278f 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 71f605b52e..1fc127a8c1 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -884,3 +884,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 94fe11138c..8f381352c2 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 7be2d9e817..52c9ee3725 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 679601624c..91b8d8275d 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 281334124b..866fa74154 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 da3b22c449..98d2b3ef27 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 b0191aa45d..756c62e908 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 c646fd6a6f..c0f62cd185 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 a5d692a07c..4bb38bb528 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 b66664576f..c14dcc3cf7 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 45beb107aa..c806d6d304 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 e60caa957b..21a43fd51d 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 cd05741f92..642e795999 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -544,3 +544,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 1ba53a57c9..efd01658b6 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 36458a562c..a9a2301e63 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 df2ead5ed4..e968323098 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 ac1fa756c7..fb06138538 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 262e454c01..0a29c597fd 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 70c533a7fe..004d95a538 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 4c34b59099..076ff27998 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 ed4772ad97..7fafbcf758 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 f766df1153..d715fd762b 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) -- GitLab