diff --git a/src/conf/virstorageobj.h b/src/conf/virstorageobj.h index 1106aa71bd..c41d4c16ad 100644 --- a/src/conf/virstorageobj.h +++ b/src/conf/virstorageobj.h @@ -24,6 +24,8 @@ # include "storage_conf.h" +# include "capabilities.h" + typedef struct _virStoragePoolObj virStoragePoolObj; typedef virStoragePoolObj *virStoragePoolObjPtr; @@ -45,6 +47,9 @@ struct _virStorageDriverState { /* Immutable pointer, self-locking APIs */ virObjectEventStatePtr storageEventState; + + /* Immutable pointer, read only after initialized */ + virCapsPtr caps; }; typedef bool diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 5c8275e978..295d8de479 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -182,3 +182,19 @@ virStorageBackendForType(int type) type, NULLSTR(virStoragePoolTypeToString(type))); return NULL; } + + +virCapsPtr +virStorageBackendGetCapabilities(void) +{ + virCapsPtr caps; + size_t i; + + if (!(caps = virCapabilitiesNew(VIR_ARCH_NONE, false, false))) + return NULL; + + for (i = 0; i < virStorageBackendsCount; i++) + virCapabilitiesAddStoragePool(caps, virStorageBackends[i]->type); + + return caps; +} diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 2b178494ae..c670c66287 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -126,4 +126,7 @@ int virStorageBackendDriversRegister(bool allmodules); int virStorageBackendRegister(virStorageBackendPtr backend); +virCapsPtr +virStorageBackendGetCapabilities(void); + #endif /* LIBVIRT_STORAGE_BACKEND_H */ diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 98be434005..caa255dd3d 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -298,6 +298,12 @@ storageStateInitialize(bool privileged, driver->storageEventState = virObjectEventStateNew(); + /* Only one load of storage driver plus backends exists. Unlike + * domains where new binaries could change the capabilities. A + * new/changed backend requires a reinitialization. */ + if (!(driver->caps = virStorageBackendGetCapabilities())) + goto error; + storageDriverUnlock(); return 0; @@ -346,6 +352,7 @@ storageStateCleanup(void) storageDriverLock(); + virObjectUnref(driver->caps); virObjectUnref(driver->storageEventState); /* free inactive pools */ @@ -555,6 +562,18 @@ storageConnectListStoragePools(virConnectPtr conn, names, maxnames); } + +static char * +storageConnectGetCapabilities(virConnectPtr conn) +{ + + if (virConnectGetCapabilitiesEnsureACL(conn) < 0) + return NULL; + + return virCapabilitiesFormatXML(driver->caps); +} + + static int storageConnectNumOfDefinedStoragePools(virConnectPtr conn) { @@ -2805,6 +2824,7 @@ static virHypervisorDriver storageHypervisorDriver = { .connectIsEncrypted = storageConnectIsEncrypted, /* 4.1.0 */ .connectIsSecure = storageConnectIsSecure, /* 4.1.0 */ .connectIsAlive = storageConnectIsAlive, /* 4.1.0 */ + .connectGetCapabilities = storageConnectGetCapabilities, /* 5.2.0 */ }; static virConnectDriver storageConnectDriver = {