[libvirt] [PATCHv5 2/7] storage: Implement file storage APIs in the default storage driver

Peter Krempa pkrempa at redhat.com
Tue Feb 11 16:26:54 UTC 2014


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




More information about the libvir-list mailing list