From 74a546e2cbcfa3b05582322c8fd93282a4173155 Mon Sep 17 00:00:00 2001 Message-Id: <74a546e2cbcfa3b05582322c8fd93282a4173155@dist-git> From: Peter Krempa Date: Wed, 26 Feb 2014 14:55:27 +0100 Subject: [PATCH] storage: Add storage file backends for gluster https://bugzilla.redhat.com/show_bug.cgi?id=1032370 Implement storage backend functions to deal with gluster volumes and implement the "stat" and "unlink" backend APIs. (cherry picked from commit a44b7b87bcc6681e2939f65a3552fc96f68bc7b6) Signed-off-by: Jiri Denemark --- src/storage/storage_backend.c | 3 + src/storage/storage_backend_gluster.c | 139 ++++++++++++++++++++++++++++++++++ src/storage/storage_backend_gluster.h | 1 + 3 files changed, 143 insertions(+) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 999f48f..a8c02bd 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -127,6 +127,9 @@ static virStorageFileBackendPtr fileBackends[] = { &virStorageFileBackendFile, &virStorageFileBackendBlock, #endif +#if WITH_STORAGE_GLUSTER + &virStorageFileBackendGluster, +#endif NULL }; diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c index c73cf8a..f17ffea 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -451,3 +451,142 @@ 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->hosts[0].name, file->path); + virStorageFileBackendGlusterPrivPtr priv = file->priv; + + glfs_fini(priv->vol); + VIR_FREE(priv->volname); + + VIR_FREE(priv); + file->priv = NULL; +} + +static int +virStorageFileBackendGlusterInit(virStorageFilePtr file) +{ + 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, hostname, file->path); + + 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; + } + + file->priv = priv; + + return 0; + +error: + VIR_FREE(priv->volname); + glfs_fini(priv->vol); + + return -1; +} + + +static int +virStorageFileBackendGlusterUnlink(virStorageFilePtr file) +{ + virStorageFileBackendGlusterPrivPtr priv = file->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->hosts[0].name, file->path, ret, errno); + return ret; +} + + +static int +virStorageFileBackendGlusterStat(virStorageFilePtr file, + struct stat *st) +{ + virStorageFileBackendGlusterPrivPtr priv = file->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->hosts[0].name, file->path, 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.9.0