[libvirt] [PATCHv4 5/7] storage: Add storage file backends for gluster

Peter Krempa pkrempa at redhat.com
Mon Feb 3 16:54:29 UTC 2014


Implement storage backend functions to deal with gluster volumes and
implement the "stat" and "unlink" backend APIs.
---
 src/storage/storage_backend.c         |   3 +
 src/storage/storage_backend_gluster.c | 143 ++++++++++++++++++++++++++++++++++
 src/storage/storage_backend_gluster.h |   1 +
 3 files changed, 147 insertions(+)

diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index da81da9..1253343 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -125,6 +125,9 @@ static virStorageBackendPtr backends[] = {
 static virStorageFileBackendPtr fileBackends[] = {
     &virStorageFileBackendFile,
     &virStorageFileBackendBlock,
+#if WITH_STORAGE_GLUSTER
+    &virStorageFileBackendGluster,
+#endif
     NULL
 };

diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
index d7a1553..c5ff07a 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -477,3 +477,146 @@ virStorageBackend virStorageBackendGluster = {

     .deleteVol = virStorageBackendGlusterVolDelete,
 };
+
+
+typedef struct _virStorageFileBackendGlusterPriv virStorageFileBackendGlusterPriv;
+typedef virStorageFileBackendGlusterPriv *virStorageFileBackendGlusterPrivPtr;
+
+struct _virStorageFileBackendGlusterPriv {
+    glfs_t *vol;
+    char *volname;
+    char *path;
+};
+
+
+static void
+virStorageFileBackendGlusterDeinit(virStorageFilePtr file)
+{
+    VIR_DEBUG("deinitializing gluster storage file %p(%s@%s)",
+              file, file->path, file->hosts[0].name);
+    virStorageFileBackendPrivPtr backPriv = file->priv;
+    virStorageFileBackendGlusterPrivPtr priv = backPriv->priv;
+
+    glfs_fini(priv->vol);
+    VIR_FREE(priv->volname);
+
+    VIR_FREE(priv);
+    backPriv->priv = NULL;
+}
+
+static int
+virStorageFileBackendGlusterInit(virStorageFilePtr file)
+{
+    virStorageFileBackendPrivPtr backPriv = file->priv;
+    virStorageFileBackendGlusterPrivPtr priv = NULL;
+    virDomainDiskHostDefPtr host = &(file->hosts[0]);
+    const char *hostname = host->name;
+    int port = 0;
+
+    VIR_DEBUG("initializing gluster storage file %p(%s@%s)",
+              file, file->path, hostname);
+
+    if (VIR_ALLOC(priv) < 0)
+        return -1;
+
+    if (VIR_STRDUP(priv->volname, file->path) < 0)
+        goto error;
+
+    if (!(priv->path  = strchr(priv->volname, '/'))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("invalid path of gluster volume: '%s'"),
+                       file->path);
+        goto error;
+    }
+
+    *priv->path = '\0';
+    priv->path++;
+
+    if (host->port &&
+        virStrToLong_i(host->port, NULL, 10, &port) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("failed to parse port number '%s'"),
+                       host->port);
+        goto error;
+    }
+
+    if (host->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX)
+        hostname = host->socket;
+
+
+    if (!(priv->vol = glfs_new(priv->volname))) {
+        virReportOOMError();
+        goto error;
+    }
+
+    if (glfs_set_volfile_server(priv->vol,
+                                virDomainDiskProtocolTransportTypeToString(host->transport),
+                                hostname, port) < 0) {
+        virReportSystemError(errno,
+                             _("failed to set gluster volfile server '%s'"),
+                             hostname);
+        goto error;
+    }
+
+    if (glfs_init(priv->vol) < 0) {
+        virReportSystemError(errno,
+                             _("failed to initialize gluster connection to "
+                               "server: '%s'"), hostname);
+        goto error;
+    }
+
+    backPriv->priv = priv;
+
+    return 0;
+
+error:
+    VIR_FREE(priv->volname);
+    glfs_fini(priv->vol);
+
+    return -1;
+}
+
+
+static int
+virStorageFileBackendGlusterUnlink(virStorageFilePtr file)
+{
+    virStorageFileBackendPrivPtr backPriv = file->priv;
+    virStorageFileBackendGlusterPrivPtr priv = backPriv->priv;
+    int ret = 0;
+
+    if (glfs_unlink(priv->vol, priv->path) < 0)
+        ret = errno;
+
+    VIR_DEBUG("removing storage file %p(%s@%s): %d",
+              file, file->path, file->hosts[0].name, ret);
+    return ret;
+}
+
+
+static int
+virStorageFileBackendGlusterStat(virStorageFilePtr file,
+                                 struct stat *st)
+{
+    virStorageFileBackendPrivPtr backPriv = file->priv;
+    virStorageFileBackendGlusterPrivPtr priv = backPriv->priv;
+    int ret = 0;
+
+    if (glfs_stat(priv->vol, priv->path, st) < 0)
+        ret = errno;
+
+    VIR_DEBUG("stat of gluster storage file %p(%s@%s): %d",
+              file, file->path, file->hosts[0].name, ret);
+    return ret;
+}
+
+
+virStorageFileBackend virStorageFileBackendGluster = {
+    .type = VIR_DOMAIN_DISK_TYPE_NETWORK,
+    .protocol = VIR_DOMAIN_DISK_PROTOCOL_GLUSTER,
+
+    .backendInit = virStorageFileBackendGlusterInit,
+    .backendDeinit = virStorageFileBackendGlusterDeinit,
+
+    .storageFileUnlink = virStorageFileBackendGlusterUnlink,
+    .storageFileStat = virStorageFileBackendGlusterStat,
+};
diff --git a/src/storage/storage_backend_gluster.h b/src/storage/storage_backend_gluster.h
index b21bda7..6796016 100644
--- a/src/storage/storage_backend_gluster.h
+++ b/src/storage/storage_backend_gluster.h
@@ -25,5 +25,6 @@
 # include "storage_backend.h"

 extern virStorageBackend virStorageBackendGluster;
+extern virStorageFileBackend virStorageFileBackendGluster;

 #endif /* __VIR_STORAGE_BACKEND_GLUSTER_H__ */
-- 
1.8.5.3




More information about the libvir-list mailing list