Implement storage backend functions to deal with gluster volumes and
implement the "stat" and "unlink" backend APIs.
---
Notes:
Version 5:
- adapted to error reporting changes
- tweaked error message
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..6f17b52 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;
+
+ ret = glfs_unlink(priv->vol, priv->path);
+ /* preserve errno */
+
+ VIR_DEBUG("removing storage file %p(%s@%s): ret=%d,errno=%d",
+ file, file->path, file->hosts[0].name, ret, errno);
+ return ret;
+}
+
+
+static int
+virStorageFileBackendGlusterStat(virStorageFilePtr file,
+ struct stat *st)
+{
+ virStorageFileBackendPrivPtr backPriv = file->priv;
+ virStorageFileBackendGlusterPrivPtr priv = backPriv->priv;
+ int ret;
+
+ ret = glfs_stat(priv->vol, priv->path, st);
+ /* preserve errno */
+
+ VIR_DEBUG("stat of storage file %p(%s@%s): ret=%d,errno=%d",
+ file, file->path, file->hosts[0].name, ret, errno);
+ 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