Implement the APIs added by the previous patch in the default storage
driver used by qemu.
---
Notes:
Version 5:
- adapt to error reporting change
src/check-aclrules.pl | 1 +
src/storage/storage_backend.c | 37 +++++++++++++++++
src/storage/storage_backend.h | 43 ++++++++++++++++++++
src/storage/storage_driver.c | 95 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 176 insertions(+)
diff --git a/src/check-aclrules.pl b/src/check-aclrules.pl
index 9151e6a..8bbdfd9 100755
--- a/src/check-aclrules.pl
+++ b/src/check-aclrules.pl
@@ -224,6 +224,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..a650678 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -2585,6 +2585,92 @@ 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) {
+ errno = ENOSYS;
+ return -2;
+ }
+
+ return priv->backend->storageFileCreate(file);
+}
+
+
+static int
+storageFileUnlink(virStorageFilePtr file)
+{
+ virStorageFileBackendPrivPtr priv = file->priv;
+
+ if (!priv->backend->storageFileUnlink) {
+ errno = ENOSYS;
+ return -2;
+ }
+
+ return priv->backend->storageFileUnlink(file);
+}
+
+
+static int
+storageFileStat(virStorageFilePtr file,
+ struct stat *st)
+{
+ virStorageFileBackendPrivPtr priv = file->priv;
+
+ if (!(priv->backend->storageFileStat)) {
+ errno = ENOSYS;
+ return -2;
+ }
+
+ return priv->backend->storageFileStat(file, st);
+}
+
+
static virStorageDriver storageDriver = {
.name = "storage",
.storageOpen = storageOpen, /* 0.4.0 */
@@ -2631,6 +2717,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