The storage file code needs to be run in the hypervisor drivers, while the storage backend code needs to be run in the storage driver. Split the source code as a preparatory step for creating separate loadable modules. Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- src/storage/Makefile.inc.am | 2 + src/storage/storage_backend_gluster.c | 305 +--------------------------- src/storage/storage_backend_gluster.h | 2 +- src/storage/storage_file_gluster.c | 366 ++++++++++++++++++++++++++++++++++ src/storage/storage_file_gluster.h | 27 +++ 5 files changed, 399 insertions(+), 303 deletions(-) create mode 100644 src/storage/storage_file_gluster.c create mode 100644 src/storage/storage_file_gluster.h diff --git a/src/storage/Makefile.inc.am b/src/storage/Makefile.inc.am index ae9fdeb6a9..1e81249272 100644 --- a/src/storage/Makefile.inc.am +++ b/src/storage/Makefile.inc.am @@ -55,6 +55,8 @@ STORAGE_DRIVER_SHEEPDOG_SOURCES = \ STORAGE_DRIVER_GLUSTER_SOURCES = \ storage/storage_backend_gluster.h \ storage/storage_backend_gluster.c \ + storage/storage_file_gluster.h \ + storage/storage_file_gluster.c \ $(NULL) STORAGE_DRIVER_ZFS_SOURCES = \ diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c index c6cc531e2f..aca772676c 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -1,7 +1,7 @@ /* * storage_backend_gluster.c: storage backend for Gluster handling * - * Copyright (C) 2013-2014 Red Hat, Inc. + * Copyright (C) 2013-2018 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,11 +24,11 @@ #include <glusterfs/api/glfs.h> #include "storage_backend_gluster.h" +#include "storage_file_gluster.h" #include "storage_conf.h" #include "viralloc.h" #include "virerror.h" #include "virlog.h" -#include "virstoragefilebackend.h" #include "virstring.h" #include "viruri.h" #include "storage_util.h" @@ -561,312 +561,13 @@ virStorageBackend virStorageBackendGluster = { }; -typedef struct _virStorageFileBackendGlusterPriv virStorageFileBackendGlusterPriv; -typedef virStorageFileBackendGlusterPriv *virStorageFileBackendGlusterPrivPtr; - -struct _virStorageFileBackendGlusterPriv { - glfs_t *vol; - char *canonpath; -}; - - -static void -virStorageFileBackendGlusterDeinit(virStorageSourcePtr src) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - - VIR_DEBUG("deinitializing gluster storage file %p (gluster://%s:%u/%s%s)", - src, src->hosts->name, src->hosts->port, src->volume, src->path); - - if (priv->vol) - glfs_fini(priv->vol); - VIR_FREE(priv->canonpath); - - VIR_FREE(priv); - src->drv->priv = NULL; -} - -static int -virStorageFileBackendGlusterInitServer(virStorageFileBackendGlusterPrivPtr priv, - virStorageNetHostDefPtr host) -{ - const char *transport = virStorageNetHostTransportTypeToString(host->transport); - const char *hoststr = NULL; - int port = 0; - - switch ((virStorageNetHostTransport) host->transport) { - case VIR_STORAGE_NET_HOST_TRANS_RDMA: - case VIR_STORAGE_NET_HOST_TRANS_TCP: - hoststr = host->name; - port = host->port; - break; - - case VIR_STORAGE_NET_HOST_TRANS_UNIX: - hoststr = host->socket; - break; - - case VIR_STORAGE_NET_HOST_TRANS_LAST: - break; - } - - VIR_DEBUG("adding gluster host for %p: transport=%s host=%s port=%d", - priv, transport, hoststr, port); - - if (glfs_set_volfile_server(priv->vol, transport, hoststr, port) < 0) { - virReportSystemError(errno, - _("failed to set gluster volfile server '%s'"), - hoststr); - return -1; - } - - return 0; -} - - -static int -virStorageFileBackendGlusterInit(virStorageSourcePtr src) -{ - virStorageFileBackendGlusterPrivPtr priv = NULL; - size_t i; - - if (!src->volume) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("missing gluster volume name for path '%s'"), - src->path); - return -1; - } - - if (VIR_ALLOC(priv) < 0) - return -1; - - VIR_DEBUG("initializing gluster storage file %p " - "(priv='%p' volume='%s' path='%s') as [%u:%u]", - src, priv, src->volume, src->path, - (unsigned int)src->drv->uid, (unsigned int)src->drv->gid); - - if (!(priv->vol = glfs_new(src->volume))) { - virReportOOMError(); - goto error; - } - - for (i = 0; i < src->nhosts; i++) { - if (virStorageFileBackendGlusterInitServer(priv, src->hosts + i) < 0) - goto error; - } - - if (glfs_init(priv->vol) < 0) { - virReportSystemError(errno, - _("failed to initialize gluster connection " - "(src=%p priv=%p)"), src, priv); - goto error; - } - - src->drv->priv = priv; - - return 0; - - error: - if (priv->vol) - glfs_fini(priv->vol); - VIR_FREE(priv); - - return -1; -} - - -static int -virStorageFileBackendGlusterCreate(virStorageSourcePtr src) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - glfs_fd_t *fd = NULL; - mode_t mode = S_IRUSR; - - if (!src->readonly) - mode |= S_IWUSR; - - if (!(fd = glfs_creat(priv->vol, src->path, - O_CREAT | O_TRUNC | O_WRONLY, mode))) - return -1; - - ignore_value(glfs_close(fd)); - return 0; -} - - -static int -virStorageFileBackendGlusterUnlink(virStorageSourcePtr src) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - - return glfs_unlink(priv->vol, src->path); -} - - -static int -virStorageFileBackendGlusterStat(virStorageSourcePtr src, - struct stat *st) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - - return glfs_stat(priv->vol, src->path, st); -} - - -static ssize_t -virStorageFileBackendGlusterRead(virStorageSourcePtr src, - size_t offset, - size_t len, - char **buf) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - glfs_fd_t *fd = NULL; - ssize_t ret = -1; - - *buf = NULL; - - if (!(fd = glfs_open(priv->vol, src->path, O_RDONLY))) { - virReportSystemError(errno, _("Failed to open file '%s'"), - src->path); - return -1; - } - - if (offset > 0) { - if (glfs_lseek(fd, offset, SEEK_SET) == (off_t) -1) { - virReportSystemError(errno, _("cannot seek into '%s'"), src->path); - goto cleanup; - } - } - - ret = virStorageBackendGlusterRead(fd, src->path, len, buf); - - cleanup: - if (fd) - glfs_close(fd); - - return ret; -} - - -static int -virStorageFileBackendGlusterAccess(virStorageSourcePtr src, - int mode) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - - return glfs_access(priv->vol, src->path, mode); -} - -static int -virStorageFileBackendGlusterReadlinkCallback(const char *path, - char **linkpath, - void *data) -{ - virStorageFileBackendGlusterPrivPtr priv = data; - char *buf = NULL; - size_t bufsiz = 0; - ssize_t ret; - struct stat st; - - *linkpath = NULL; - - if (glfs_stat(priv->vol, path, &st) < 0) { - virReportSystemError(errno, - _("failed to stat gluster path '%s'"), - path); - return -1; - } - - if (!S_ISLNK(st.st_mode)) - return 1; - - realloc: - if (VIR_EXPAND_N(buf, bufsiz, 256) < 0) - goto error; - - if ((ret = glfs_readlink(priv->vol, path, buf, bufsiz)) < 0) { - virReportSystemError(errno, - _("failed to read link of gluster file '%s'"), - path); - goto error; - } - - if (ret == bufsiz) - goto realloc; - - buf[ret] = '\0'; - - *linkpath = buf; - - return 0; - - error: - VIR_FREE(buf); - return -1; -} - - -static const char * -virStorageFileBackendGlusterGetUniqueIdentifier(virStorageSourcePtr src) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - char *filePath = NULL; - - if (priv->canonpath) - return priv->canonpath; - - if (!(filePath = virStorageFileCanonicalizePath(src->path, - virStorageFileBackendGlusterReadlinkCallback, - priv))) - return NULL; - - ignore_value(virAsprintf(&priv->canonpath, "gluster://%s:%u/%s/%s", - src->hosts->name, - src->hosts->port, - src->volume, - filePath)); - - VIR_FREE(filePath); - - return priv->canonpath; -} - - -static int -virStorageFileBackendGlusterChown(const virStorageSource *src, - uid_t uid, - gid_t gid) -{ - virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; - - return glfs_chown(priv->vol, src->path, uid, gid); -} - - -virStorageFileBackend virStorageFileBackendGluster = { - .type = VIR_STORAGE_TYPE_NETWORK, - .protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER, - - .backendInit = virStorageFileBackendGlusterInit, - .backendDeinit = virStorageFileBackendGlusterDeinit, - - .storageFileCreate = virStorageFileBackendGlusterCreate, - .storageFileUnlink = virStorageFileBackendGlusterUnlink, - .storageFileStat = virStorageFileBackendGlusterStat, - .storageFileRead = virStorageFileBackendGlusterRead, - .storageFileAccess = virStorageFileBackendGlusterAccess, - .storageFileChown = virStorageFileBackendGlusterChown, - - .storageFileGetUniqueIdentifier = virStorageFileBackendGlusterGetUniqueIdentifier, -}; - - int virStorageBackendGlusterRegister(void) { if (virStorageBackendRegister(&virStorageBackendGluster) < 0) return -1; - if (virStorageFileBackendRegister(&virStorageFileBackendGluster) < 0) + if (virStorageFileGlusterRegister() < 0) return -1; return 0; diff --git a/src/storage/storage_backend_gluster.h b/src/storage/storage_backend_gluster.h index 91b8d8275d..12a1c04f8d 100644 --- a/src/storage/storage_backend_gluster.h +++ b/src/storage/storage_backend_gluster.h @@ -1,7 +1,7 @@ /* * storage_backend_gluster.h: storage backend for Gluster handling * - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (C) 2013-2018 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/storage/storage_file_gluster.c b/src/storage/storage_file_gluster.c new file mode 100644 index 0000000000..f8bbde8cfe --- /dev/null +++ b/src/storage/storage_file_gluster.c @@ -0,0 +1,366 @@ +/* + * storage_file_gluster.c: storage file backend for Gluster handling + * + * Copyright (C) 2013-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <config.h> + +#include <glusterfs/api/glfs.h> + +#include "storage_file_gluster.h" +#include "viralloc.h" +#include "virerror.h" +#include "virlog.h" +#include "virstoragefilebackend.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_LOG_INIT("storage.storage_file_gluster"); + + +typedef struct _virStorageFileBackendGlusterPriv virStorageFileBackendGlusterPriv; +typedef virStorageFileBackendGlusterPriv *virStorageFileBackendGlusterPrivPtr; + +struct _virStorageFileBackendGlusterPriv { + glfs_t *vol; + char *canonpath; +}; + +static void +virStorageFileBackendGlusterDeinit(virStorageSourcePtr src) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + + VIR_DEBUG("deinitializing gluster storage file %p (gluster://%s:%u/%s%s)", + src, src->hosts->name, src->hosts->port, src->volume, src->path); + + if (priv->vol) + glfs_fini(priv->vol); + VIR_FREE(priv->canonpath); + + VIR_FREE(priv); + src->drv->priv = NULL; +} + +static int +virStorageFileBackendGlusterInitServer(virStorageFileBackendGlusterPrivPtr priv, + virStorageNetHostDefPtr host) +{ + const char *transport = virStorageNetHostTransportTypeToString(host->transport); + const char *hoststr = NULL; + int port = 0; + + switch ((virStorageNetHostTransport) host->transport) { + case VIR_STORAGE_NET_HOST_TRANS_RDMA: + case VIR_STORAGE_NET_HOST_TRANS_TCP: + hoststr = host->name; + port = host->port; + break; + + case VIR_STORAGE_NET_HOST_TRANS_UNIX: + hoststr = host->socket; + break; + + case VIR_STORAGE_NET_HOST_TRANS_LAST: + break; + } + + VIR_DEBUG("adding gluster host for %p: transport=%s host=%s port=%d", + priv, transport, hoststr, port); + + if (glfs_set_volfile_server(priv->vol, transport, hoststr, port) < 0) { + virReportSystemError(errno, + _("failed to set gluster volfile server '%s'"), + hoststr); + return -1; + } + + return 0; +} + + +static int +virStorageFileBackendGlusterInit(virStorageSourcePtr src) +{ + virStorageFileBackendGlusterPrivPtr priv = NULL; + size_t i; + + if (!src->volume) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("missing gluster volume name for path '%s'"), + src->path); + return -1; + } + + if (VIR_ALLOC(priv) < 0) + return -1; + + VIR_DEBUG("initializing gluster storage file %p " + "(priv='%p' volume='%s' path='%s') as [%u:%u]", + src, priv, src->volume, src->path, + (unsigned int)src->drv->uid, (unsigned int)src->drv->gid); + + if (!(priv->vol = glfs_new(src->volume))) { + virReportOOMError(); + goto error; + } + + for (i = 0; i < src->nhosts; i++) { + if (virStorageFileBackendGlusterInitServer(priv, src->hosts + i) < 0) + goto error; + } + + if (glfs_init(priv->vol) < 0) { + virReportSystemError(errno, + _("failed to initialize gluster connection " + "(src=%p priv=%p)"), src, priv); + goto error; + } + + src->drv->priv = priv; + + return 0; + + error: + if (priv->vol) + glfs_fini(priv->vol); + VIR_FREE(priv); + + return -1; +} + + +static int +virStorageFileBackendGlusterCreate(virStorageSourcePtr src) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + glfs_fd_t *fd = NULL; + mode_t mode = S_IRUSR; + + if (!src->readonly) + mode |= S_IWUSR; + + if (!(fd = glfs_creat(priv->vol, src->path, + O_CREAT | O_TRUNC | O_WRONLY, mode))) + return -1; + + ignore_value(glfs_close(fd)); + return 0; +} + + +static int +virStorageFileBackendGlusterUnlink(virStorageSourcePtr src) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + + return glfs_unlink(priv->vol, src->path); +} + + +static int +virStorageFileBackendGlusterStat(virStorageSourcePtr src, + struct stat *st) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + + return glfs_stat(priv->vol, src->path, st); +} + + +static ssize_t +virStorageFileBackendGlusterRead(virStorageSourcePtr src, + size_t offset, + size_t len, + char **buf) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + glfs_fd_t *fd = NULL; + ssize_t ret = -1; + char *s; + size_t nread = 0; + + *buf = NULL; + + if (!(fd = glfs_open(priv->vol, src->path, O_RDONLY))) { + virReportSystemError(errno, _("Failed to open file '%s'"), + src->path); + return -1; + } + + if (offset > 0) { + if (glfs_lseek(fd, offset, SEEK_SET) == (off_t) -1) { + virReportSystemError(errno, _("cannot seek into '%s'"), src->path); + goto cleanup; + } + } + + + if (VIR_ALLOC_N(*buf, len) < 0) + return -1; + + s = *buf; + while (len) { + ssize_t r = glfs_read(fd, s, len, 0); + if (r < 0 && errno == EINTR) + continue; + if (r < 0) { + VIR_FREE(*buf); + virReportSystemError(errno, _("unable to read '%s'"), src->path); + return r; + } + if (r == 0) + return nread; + s += r; + len -= r; + nread += r; + } + + ret = nread; + + cleanup: + if (fd) + glfs_close(fd); + + return ret; +} + + +static int +virStorageFileBackendGlusterAccess(virStorageSourcePtr src, + int mode) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + + return glfs_access(priv->vol, src->path, mode); +} + +static int +virStorageFileBackendGlusterReadlinkCallback(const char *path, + char **linkpath, + void *data) +{ + virStorageFileBackendGlusterPrivPtr priv = data; + char *buf = NULL; + size_t bufsiz = 0; + ssize_t ret; + struct stat st; + + *linkpath = NULL; + + if (glfs_stat(priv->vol, path, &st) < 0) { + virReportSystemError(errno, + _("failed to stat gluster path '%s'"), + path); + return -1; + } + + if (!S_ISLNK(st.st_mode)) + return 1; + + realloc: + if (VIR_EXPAND_N(buf, bufsiz, 256) < 0) + goto error; + + if ((ret = glfs_readlink(priv->vol, path, buf, bufsiz)) < 0) { + virReportSystemError(errno, + _("failed to read link of gluster file '%s'"), + path); + goto error; + } + + if (ret == bufsiz) + goto realloc; + + buf[ret] = '\0'; + + *linkpath = buf; + + return 0; + + error: + VIR_FREE(buf); + return -1; +} + + +static const char * +virStorageFileBackendGlusterGetUniqueIdentifier(virStorageSourcePtr src) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + char *filePath = NULL; + + if (priv->canonpath) + return priv->canonpath; + + if (!(filePath = virStorageFileCanonicalizePath(src->path, + virStorageFileBackendGlusterReadlinkCallback, + priv))) + return NULL; + + ignore_value(virAsprintf(&priv->canonpath, "gluster://%s:%u/%s/%s", + src->hosts->name, + src->hosts->port, + src->volume, + filePath)); + + VIR_FREE(filePath); + + return priv->canonpath; +} + + +static int +virStorageFileBackendGlusterChown(const virStorageSource *src, + uid_t uid, + gid_t gid) +{ + virStorageFileBackendGlusterPrivPtr priv = src->drv->priv; + + return glfs_chown(priv->vol, src->path, uid, gid); +} + + +virStorageFileBackend virStorageFileBackendGluster = { + .type = VIR_STORAGE_TYPE_NETWORK, + .protocol = VIR_STORAGE_NET_PROTOCOL_GLUSTER, + + .backendInit = virStorageFileBackendGlusterInit, + .backendDeinit = virStorageFileBackendGlusterDeinit, + + .storageFileCreate = virStorageFileBackendGlusterCreate, + .storageFileUnlink = virStorageFileBackendGlusterUnlink, + .storageFileStat = virStorageFileBackendGlusterStat, + .storageFileRead = virStorageFileBackendGlusterRead, + .storageFileAccess = virStorageFileBackendGlusterAccess, + .storageFileChown = virStorageFileBackendGlusterChown, + + .storageFileGetUniqueIdentifier = virStorageFileBackendGlusterGetUniqueIdentifier, +}; + + +int +virStorageFileGlusterRegister(void) +{ + if (virStorageFileBackendRegister(&virStorageFileBackendGluster) < 0) + return -1; + + return 0; +} diff --git a/src/storage/storage_file_gluster.h b/src/storage/storage_file_gluster.h new file mode 100644 index 0000000000..572254aedb --- /dev/null +++ b/src/storage/storage_file_gluster.h @@ -0,0 +1,27 @@ +/* + * storage_file_gluster.h: storage file backend for Gluster handling + * + * Copyright (C) 2013-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#ifndef __VIR_STORAGE_FILE_GLUSTER_H__ +# define __VIR_STORAGE_FILE_GLUSTER_H__ + +int virStorageFileGlusterRegister(void); + +#endif /* __VIR_STORAGE_FILE_GLUSTER_H__ */ -- 2.14.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list