[libvirt] [PATCH v3 1/3] storage: add gluster backend initialization support for multiple servers
Daniel P. Berrange
berrange at redhat.com
Fri Jul 22 10:01:18 UTC 2016
On Fri, Jul 22, 2016 at 01:50:29PM +0530, Prasanna Kumar Kalever wrote:
> This patch adds support for initialization of gluster backend
> with multiple servers which acts as gluster volfile servers for
> the gluster storage backend.
>
> This will help in achieving high availability of gluster backend
> connectivity via libgfapi i.e. when the first volfile server fails,
> then other servers specified are used as volfile server to re-establish
> the backend gluster connectivity.
>
> Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever at redhat.com>
> ---
> src/storage/storage_backend_gluster.c | 100 ++++++++++++++++++++++++----------
> 1 file changed, 71 insertions(+), 29 deletions(-)
>
> diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
> index eda060d..ab61619 100644
> --- a/src/storage/storage_backend_gluster.c
> +++ b/src/storage/storage_backend_gluster.c
> @@ -32,6 +32,8 @@
> #include "virstring.h"
> #include "viruri.h"
>
> +#define QEMU_DEFAULT_GLUSTER_PORT 24007
> +
> #define VIR_FROM_THIS VIR_FROM_STORAGE
>
> VIR_LOG_INIT("storage.storage_backend_gluster");
> @@ -573,20 +575,18 @@ static int
> virStorageFileBackendGlusterInit(virStorageSourcePtr src)
> {
> virStorageFileBackendGlusterPrivPtr priv = NULL;
> - virStorageNetHostDefPtr host = &(src->hosts[0]);
> - const char *hostname;
> + const char *transport;
> + bool is_unix = false;
> int port = 0;
> + size_t i = 0;
>
> - if (src->nhosts != 1) {
> + if (src->nhosts < 1) {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> - _("Expected exactly 1 host for the gluster volume"));
> + _("Expected atleast 1 host for the gluster volume"));
s/atleast/at least/
> return -1;
> }
>
> - hostname = host->name;
> -
> - VIR_DEBUG("initializing gluster storage file %p (gluster://%s:%s/%s%s)[%u:%u]",
> - src, hostname, host->port ? host->port : "0",
> + VIR_DEBUG("Initializing gluster volume=%s path=%s with uid=%u gid=%u",
> NULLSTR(src->volume), src->path,
> (unsigned int)src->drv->uid, (unsigned int)src->drv->gid);
>
> @@ -600,35 +600,77 @@ virStorageFileBackendGlusterInit(virStorageSourcePtr src)
> if (VIR_ALLOC(priv) < 0)
> return -1;
>
> - 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_STORAGE_NET_HOST_TRANS_UNIX)
> - hostname = host->socket;
> -
> if (!(priv->vol = glfs_new(src->volume))) {
> virReportOOMError();
> goto error;
> }
>
> - if (glfs_set_volfile_server(priv->vol,
> - virStorageNetHostTransportTypeToString(host->transport),
> - hostname, port) < 0) {
> - virReportSystemError(errno,
> - _("failed to set gluster volfile server '%s'"),
> - hostname);
> - goto error;
> + for (i = 0; i < src->nhosts; i++) {
> +
> + if ((src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_TCP) ||
> + (src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_UNIX)) {
> + transport = virStorageNetHostTransportTypeToString(src->hosts[i].transport);
> + } else {
> + virReportSystemError(errno,
> + _("gluster only supports tcp|unix not '%s'"),
> + virStorageNetHostTransportTypeToString(src->hosts[i].transport));
> + goto error;
> + }
> +
> +
> + if (src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_UNIX) {
> + is_unix = true;
> + } else if (!src->hosts[i].port) {
> + port = QEMU_DEFAULT_GLUSTER_PORT;
> + } else {
> + if (virStrToLong_i(src->hosts[i].port, NULL, 10, &port) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("failed to parse port number '%s'"),
> + src->hosts[i].port);
> + goto error;
> + }
Indentation is screwed up here.
> + }
> + if (glfs_set_volfile_server(priv->vol, transport,
> + is_unix ? (src->hosts[i].socket) : (src->hosts[i].name),
The () used here serve no useful purpose.
> + is_unix ? 0 : port) < 0) {
> + if (is_unix) {
> + virReportSystemError(errno,
> + _("failed to set gluster volfile server with "
> + "socket '%s'"), src->hosts[i].socket);
> + } else {
> + virReportSystemError(errno,
> + _("failed to set gluster volfile server with "
> + "host '%s' and port '%s'"), src->hosts[i].name,
> + src->hosts[i].port);
> + }
> + goto error;
> + } else {
> + if (is_unix) {
> + VIR_DEBUG("Successfully set volfile server with socket:'%s' ",
> + src->hosts[i].socket);
> + } else {
> + VIR_DEBUG("Successfully set volfile server with host:'%s' "
> + "port:'%d' transport:'%s'", src->hosts[i].name,
> + port, transport);
> + }
> + }
> + is_unix = false;
> }
>
> if (glfs_init(priv->vol) < 0) {
> - virReportSystemError(errno,
> - _("failed to initialize gluster connection to "
> - "server: '%s'"), hostname);
> + virReportSystemError(errno,
> + _("failed to initialize gluster connection"
> + " for volume %s, path %s with"),
> + NULLSTR(src->volume), src->path);
> + for (i = 0; i < src->nhosts; i++) {
> + if (src->hosts[i].transport == VIR_STORAGE_NET_HOST_TRANS_TCP) {
> + virReportSystemError(errno, _("host: %s and port %s"),
> + src->hosts[i].name, src->hosts[i].port);
> + } else {
> + virReportSystemError(errno, _("socket %s"),
> + src->hosts[i].socket);
> + }
> + }
This code looks really messed up - any codepath should only call the
virReportXXXXXXError functions *once*, certainly never report
errors in a loop.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list