Implement the APIs added by the previous patch in the default storage driver used by qemu. --- src/check-aclrules.pl | 1 + src/storage/storage_backend.c | 37 ++++++++++++++++++ src/storage/storage_backend.h | 43 +++++++++++++++++++++ src/storage/storage_driver.c | 89 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+) diff --git a/src/check-aclrules.pl b/src/check-aclrules.pl index 057517e..7f34094 100755 --- a/src/check-aclrules.pl +++ b/src/check-aclrules.pl @@ -221,6 +221,7 @@ while (<>) { if ($api ne "no" && $api ne "name" && + $api !~ /^storageFile\w+/ && $table ne "virStateDriver" && !exists $acls{$impl} && !exists $whitelist{$api} && diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 19fb1f0..b59b5b7 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -121,6 +121,12 @@ static virStorageBackendPtr backends[] = { NULL }; + +static virStorageFileBackendPtr fileBackends[] = { + NULL +}; + + enum { TOOL_QEMU_IMG, TOOL_KVM_IMG, @@ -1152,6 +1158,37 @@ virStorageBackendForType(int type) } +virStorageFileBackendPtr +virStorageFileBackendForType(int type, + int protocol) +{ + size_t i; + + for (i = 0; fileBackends[i]; i++) { + if (fileBackends[i]->type == type) { + if (type == VIR_DOMAIN_DISK_TYPE_NETWORK && + fileBackends[i]->protocol != protocol) + continue; + + return fileBackends[i]; + } + } + + if (type == VIR_DOMAIN_DISK_TYPE_NETWORK) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing storage backend for network files " + "using %s protocol"), + virDomainDiskProtocolTypeToString(protocol)); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing storage backend for '%s' storage"), + virDomainDiskTypeToString(type)); + } + + return NULL; +} + + /* * Allows caller to silently ignore files with improper mode * diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 378bc4d..5613285 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -29,6 +29,7 @@ # include "internal.h" # include "storage_conf.h" # include "vircommand.h" +# include "libvirt_private.h" typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, const char *srcSpec, @@ -189,4 +190,46 @@ virStorageBackendCreateQemuImgCmd(virConnectPtr conn, const char *create_tool, int imgformat); +/* ------- virStorageFile backends ------------ */ +typedef int +(*virStorageFileBackendInit)(virStorageFilePtr file); + +typedef void +(*virStorageFileBackendDeinit)(virStorageFilePtr file); + +typedef int +(*virStorageFileBackendCreate)(virStorageFilePtr file); + +typedef int +(*virStorageFileBackendUnlink)(virStorageFilePtr file); + +typedef int +(*virStorageFileBackendStat)(virStorageFilePtr file, + struct stat *st); + +typedef struct _virStorageFileBackend virStorageFileBackend; +typedef virStorageFileBackend *virStorageFileBackendPtr; + +virStorageFileBackendPtr virStorageFileBackendForType(int type, int protocol); + +typedef struct _virStorageFilePriv virStorageFileBackendPriv; +typedef virStorageFileBackendPriv *virStorageFileBackendPrivPtr; +struct _virStorageFilePriv { + virStorageFileBackendPtr backend; + void *priv; +}; + + +struct _virStorageFileBackend { + int type; + int protocol; + + virStorageFileBackendInit backendInit; + virStorageFileBackendDeinit backendDeinit; + + virStorageFileBackendCreate storageFileCreate; + virStorageFileBackendUnlink storageFileUnlink; + virStorageFileBackendStat storageFileStat; +}; + #endif /* __VIR_STORAGE_BACKEND_H__ */ diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index c83aa8a..75e6454 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -2585,6 +2585,86 @@ cleanup: return ret; } + +static int +storageFileInit(virStorageFilePtr file) +{ + virStorageFileBackendPrivPtr priv = NULL; + + if (VIR_ALLOC(priv) < 0) + return -1; + + file->priv = priv; + + if (!(priv->backend = virStorageFileBackendForType(file->type, + file->protocol))) + goto error; + + if (priv->backend->backendInit) { + if (priv->backend->backendInit(file) < 0) + goto error; + } + + return 0; + +error: + file->priv = NULL; + VIR_FREE(priv); + return -1; +} + + +static void +storageFileDeinit(virStorageFilePtr file) +{ + virStorageFileBackendPrivPtr priv = file->priv; + + if (priv->backend && + priv->backend->backendDeinit) + priv->backend->backendDeinit(file); + + VIR_FREE(priv); + file->priv = NULL; +} + + +static int +storageFileCreate(virStorageFilePtr file) +{ + virStorageFileBackendPrivPtr priv = file->priv; + + if (!priv->backend->storageFileCreate) + return ENOSYS; + + return priv->backend->storageFileCreate(file); +} + + +static int +storageFileUnlink(virStorageFilePtr file) +{ + virStorageFileBackendPrivPtr priv = file->priv; + + if (!priv->backend->storageFileUnlink) + return ENOSYS; + + return priv->backend->storageFileUnlink(file); +} + + +static int +storageFileStat(virStorageFilePtr file, + struct stat *st) +{ + virStorageFileBackendPrivPtr priv = file->priv; + + if (!(priv->backend->storageFileStat)) + return ENOSYS; + + return priv->backend->storageFileStat(file, st); +} + + static virStorageDriver storageDriver = { .name = "storage", .storageOpen = storageOpen, /* 0.4.0 */ @@ -2631,6 +2711,15 @@ static virStorageDriver storageDriver = { .storagePoolIsActive = storagePoolIsActive, /* 0.7.3 */ .storagePoolIsPersistent = storagePoolIsPersistent, /* 0.7.3 */ + + /* ----- internal APIs ----- */ + .storageFileInit = storageFileInit, + .storageFileDeinit = storageFileDeinit, + + .storageFileUnlink = storageFileUnlink, + .storageFileStat = storageFileStat, + .storageFileCreate = storageFileCreate, + }; -- 1.8.5.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list