c401cc
From 74a546e2cbcfa3b05582322c8fd93282a4173155 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <74a546e2cbcfa3b05582322c8fd93282a4173155@dist-git>
c401cc
From: Peter Krempa <pkrempa@redhat.com>
c401cc
Date: Wed, 26 Feb 2014 14:55:27 +0100
c401cc
Subject: [PATCH] storage: Add storage file backends for gluster
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
c401cc
c401cc
Implement storage backend functions to deal with gluster volumes and
c401cc
implement the "stat" and "unlink" backend APIs.
c401cc
c401cc
(cherry picked from commit a44b7b87bcc6681e2939f65a3552fc96f68bc7b6)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/storage/storage_backend.c         |   3 +
c401cc
 src/storage/storage_backend_gluster.c | 139 ++++++++++++++++++++++++++++++++++
c401cc
 src/storage/storage_backend_gluster.h |   1 +
c401cc
 3 files changed, 143 insertions(+)
c401cc
c401cc
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
c401cc
index 999f48f..a8c02bd 100644
c401cc
--- a/src/storage/storage_backend.c
c401cc
+++ b/src/storage/storage_backend.c
c401cc
@@ -127,6 +127,9 @@ static virStorageFileBackendPtr fileBackends[] = {
c401cc
     &virStorageFileBackendFile,
c401cc
     &virStorageFileBackendBlock,
c401cc
 #endif
c401cc
+#if WITH_STORAGE_GLUSTER
c401cc
+    &virStorageFileBackendGluster,
c401cc
+#endif
c401cc
     NULL
c401cc
 };
c401cc
 
c401cc
diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
c401cc
index c73cf8a..f17ffea 100644
c401cc
--- a/src/storage/storage_backend_gluster.c
c401cc
+++ b/src/storage/storage_backend_gluster.c
c401cc
@@ -451,3 +451,142 @@ virStorageBackend virStorageBackendGluster = {
c401cc
 
c401cc
     .deleteVol = virStorageBackendGlusterVolDelete,
c401cc
 };
c401cc
+
c401cc
+
c401cc
+typedef struct _virStorageFileBackendGlusterPriv virStorageFileBackendGlusterPriv;
c401cc
+typedef virStorageFileBackendGlusterPriv *virStorageFileBackendGlusterPrivPtr;
c401cc
+
c401cc
+struct _virStorageFileBackendGlusterPriv {
c401cc
+    glfs_t *vol;
c401cc
+    char *volname;
c401cc
+    char *path;
c401cc
+};
c401cc
+
c401cc
+
c401cc
+static void
c401cc
+virStorageFileBackendGlusterDeinit(virStorageFilePtr file)
c401cc
+{
c401cc
+    VIR_DEBUG("deinitializing gluster storage file %p(%s/%s)",
c401cc
+              file, file->hosts[0].name, file->path);
c401cc
+    virStorageFileBackendGlusterPrivPtr priv = file->priv;
c401cc
+
c401cc
+    glfs_fini(priv->vol);
c401cc
+    VIR_FREE(priv->volname);
c401cc
+
c401cc
+    VIR_FREE(priv);
c401cc
+    file->priv = NULL;
c401cc
+}
c401cc
+
c401cc
+static int
c401cc
+virStorageFileBackendGlusterInit(virStorageFilePtr file)
c401cc
+{
c401cc
+    virStorageFileBackendGlusterPrivPtr priv = NULL;
c401cc
+    virDomainDiskHostDefPtr host = &(file->hosts[0]);
c401cc
+    const char *hostname = host->name;
c401cc
+    int port = 0;
c401cc
+
c401cc
+    VIR_DEBUG("initializing gluster storage file %p(%s/%s)",
c401cc
+              file, hostname, file->path);
c401cc
+
c401cc
+    if (VIR_ALLOC(priv) < 0)
c401cc
+        return -1;
c401cc
+
c401cc
+    if (VIR_STRDUP(priv->volname, file->path) < 0)
c401cc
+        goto error;
c401cc
+
c401cc
+    if (!(priv->path = strchr(priv->volname, '/'))) {
c401cc
+        virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
+                       _("invalid path of gluster volume: '%s'"),
c401cc
+                       file->path);
c401cc
+        goto error;
c401cc
+    }
c401cc
+
c401cc
+    *priv->path = '\0';
c401cc
+    priv->path++;
c401cc
+
c401cc
+    if (host->port &&
c401cc
+        virStrToLong_i(host->port, NULL, 10, &port) < 0) {
c401cc
+        virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
+                       _("failed to parse port number '%s'"),
c401cc
+                       host->port);
c401cc
+        goto error;
c401cc
+    }
c401cc
+
c401cc
+    if (host->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX)
c401cc
+        hostname = host->socket;
c401cc
+
c401cc
+
c401cc
+    if (!(priv->vol = glfs_new(priv->volname))) {
c401cc
+        virReportOOMError();
c401cc
+        goto error;
c401cc
+    }
c401cc
+
c401cc
+    if (glfs_set_volfile_server(priv->vol,
c401cc
+                                virDomainDiskProtocolTransportTypeToString(host->transport),
c401cc
+                                hostname, port) < 0) {
c401cc
+        virReportSystemError(errno,
c401cc
+                             _("failed to set gluster volfile server '%s'"),
c401cc
+                             hostname);
c401cc
+        goto error;
c401cc
+    }
c401cc
+
c401cc
+    if (glfs_init(priv->vol) < 0) {
c401cc
+        virReportSystemError(errno,
c401cc
+                             _("failed to initialize gluster connection to "
c401cc
+                               "server: '%s'"), hostname);
c401cc
+        goto error;
c401cc
+    }
c401cc
+
c401cc
+    file->priv = priv;
c401cc
+
c401cc
+    return 0;
c401cc
+
c401cc
+error:
c401cc
+    VIR_FREE(priv->volname);
c401cc
+    glfs_fini(priv->vol);
c401cc
+
c401cc
+    return -1;
c401cc
+}
c401cc
+
c401cc
+
c401cc
+static int
c401cc
+virStorageFileBackendGlusterUnlink(virStorageFilePtr file)
c401cc
+{
c401cc
+    virStorageFileBackendGlusterPrivPtr priv = file->priv;
c401cc
+    int ret;
c401cc
+
c401cc
+    ret = glfs_unlink(priv->vol, priv->path);
c401cc
+    /* preserve errno */
c401cc
+
c401cc
+    VIR_DEBUG("removing storage file %p(%s/%s): ret=%d, errno=%d",
c401cc
+              file, file->hosts[0].name, file->path, ret, errno);
c401cc
+    return ret;
c401cc
+}
c401cc
+
c401cc
+
c401cc
+static int
c401cc
+virStorageFileBackendGlusterStat(virStorageFilePtr file,
c401cc
+                                 struct stat *st)
c401cc
+{
c401cc
+    virStorageFileBackendGlusterPrivPtr priv = file->priv;
c401cc
+    int ret;
c401cc
+
c401cc
+    ret = glfs_stat(priv->vol, priv->path, st);
c401cc
+    /* preserve errno */
c401cc
+
c401cc
+    VIR_DEBUG("stat of storage file %p(%s/%s): ret=%d, errno=%d",
c401cc
+              file, file->hosts[0].name, file->path, ret, errno);
c401cc
+    return ret;
c401cc
+}
c401cc
+
c401cc
+
c401cc
+virStorageFileBackend virStorageFileBackendGluster = {
c401cc
+    .type = VIR_DOMAIN_DISK_TYPE_NETWORK,
c401cc
+    .protocol = VIR_DOMAIN_DISK_PROTOCOL_GLUSTER,
c401cc
+
c401cc
+    .backendInit = virStorageFileBackendGlusterInit,
c401cc
+    .backendDeinit = virStorageFileBackendGlusterDeinit,
c401cc
+
c401cc
+    .storageFileUnlink = virStorageFileBackendGlusterUnlink,
c401cc
+    .storageFileStat = virStorageFileBackendGlusterStat,
c401cc
+};
c401cc
diff --git a/src/storage/storage_backend_gluster.h b/src/storage/storage_backend_gluster.h
c401cc
index b21bda7..6796016 100644
c401cc
--- a/src/storage/storage_backend_gluster.h
c401cc
+++ b/src/storage/storage_backend_gluster.h
c401cc
@@ -25,5 +25,6 @@
c401cc
 # include "storage_backend.h"
c401cc
 
c401cc
 extern virStorageBackend virStorageBackendGluster;
c401cc
+extern virStorageFileBackend virStorageFileBackendGluster;
c401cc
 
c401cc
 #endif /* __VIR_STORAGE_BACKEND_GLUSTER_H__ */
c401cc
-- 
c401cc
1.9.0
c401cc