diff options
| author | Vijay Bellur <vijay@gluster.com> | 2010-08-06 05:25:16 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-08-06 04:09:03 -0700 | 
| commit | 453cb4bf0b70c876eb468def34054095cfd66359 (patch) | |
| tree | 46593e13f4ceb37a4d13a5f420c300b8860e0aa6 | |
| parent | 3f6e5e670b7c1e30c64f2f11419947bd8982d51b (diff) | |
v2[PATCH BUG:1286] glusterd: Regain volume state upon re-start
Signed-off-by: Vijay Bellur <vijay@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 1286 ()
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1286
| -rw-r--r-- | xlators/mgmt/glusterd/src/Makefile.am | 4 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-ha.c | 171 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-ha.h | 46 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-mem-types.h | 2 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 14 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.c | 961 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.h | 90 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-utils.c | 1 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.c | 29 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 40 | 
10 files changed, 1112 insertions, 246 deletions
diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index 83f67b92eeb..adc7ee30bf9 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -2,12 +2,12 @@ xlator_LTLIBRARIES = glusterd.la  xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mgmt  glusterd_la_LDFLAGS = -module -avoidversion  glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c glusterd-op-sm.c \ -	glusterd-utils.c glusterd3_1-mops.c glusterd-ha.c glusterd-handshake.c +	glusterd-utils.c glusterd3_1-mops.c glusterd-store.c glusterd-handshake.c  glusterd_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la\  		     $(top_builddir)/rpc/xdr/src/libgfxdr.la\  		     $(top_builddir)/rpc/rpc-lib/src/libgfrpc.la -noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h glusterd-sm.h glusterd-ha.h glusterd-mem-types.h +noinst_HEADERS = glusterd.h glusterd-utils.h glusterd-op-sm.h glusterd-sm.h glusterd-store.h glusterd-mem-types.h  AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\  	-I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\ diff --git a/xlators/mgmt/glusterd/src/glusterd-ha.c b/xlators/mgmt/glusterd/src/glusterd-ha.c deleted file mode 100644 index ebf6ce066b6..00000000000 --- a/xlators/mgmt/glusterd/src/glusterd-ha.c +++ /dev/null @@ -1,171 +0,0 @@ -/* -  Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com> -  This file is part of GlusterFS. - -  GlusterFS is free software; you can redistribute it and/or modify -  it under the terms of the GNU General Public License as published -  by the Free Software Foundation; either version 3 of the License, -  or (at your option) any later version. - -  GlusterFS 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 -  General Public License for more details. - -  You should have received a copy of the GNU General Public License -  along with this program.  If not, see -  <http://www.gnu.org/licenses/>. -*/ -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif -#include <inttypes.h> - - -#include "globals.h" -#include "glusterfs.h" -#include "compat.h" -#include "dict.h" -#include "protocol-common.h" -#include "xlator.h" -#include "logging.h" -#include "timer.h" -#include "defaults.h" -#include "compat.h" -#include "compat-errno.h" -#include "statedump.h" -#include "glusterd-mem-types.h" -#include "glusterd.h" -#include "glusterd-sm.h" -#include "glusterd-op-sm.h" -#include "glusterd-utils.h" -#include "glusterd-ha.h" - -#include "glusterd1.h" -#include "cli1.h" -#include "rpc-clnt.h" - -#include <sys/resource.h> -#include <inttypes.h> -#include <dirent.h> - -int32_t -glusterd_ha_create_volume (glusterd_volinfo_t *volinfo) -{ -        char                    pathname[PATH_MAX] = {0,}; -        int32_t                 ret = -1; -        char                    filepath[PATH_MAX] = {0,}; -        char                    buf[4096] = {0,}; -        int                     fd = -1; -        glusterd_conf_t         *priv = NULL; - -        GF_ASSERT (volinfo); -        priv = THIS->private; - -        GF_ASSERT (priv); - -        snprintf (pathname, 1024, "%s/vols/%s", priv->workdir, -                  volinfo->volname); - -        ret = mkdir (pathname, 0x777); - -        if (-1 == ret) { -                gf_log ("", GF_LOG_ERROR, "mkdir() failed on path %s," -                        "errno: %d", pathname, errno); -                goto out; -        } - -        snprintf (filepath, 1024, "%s/info", pathname); - -        fd = open (filepath, O_RDWR | O_CREAT | O_APPEND, 0644); - -        if (-1 == fd) { -                gf_log ("", GF_LOG_ERROR, "open() failed on path %s," -                        "errno: %d", filepath, errno); -                ret = -1; -                goto out; -        } - -        snprintf (buf, 4096, "type=%d\n", volinfo->type); -        ret = write (fd, buf, strlen (buf)); -        snprintf (buf, 4096, "count=%d\n", volinfo->brick_count); -        ret = write (fd, buf, strlen (buf)); -        close (fd); - -        ret = 0; - -out: -        if (ret) { -                glusterd_ha_delete_volume (volinfo); -        } - -        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); - -        return ret; -} - - -int32_t -glusterd_ha_delete_volume (glusterd_volinfo_t *volinfo) -{ -        char    pathname[PATH_MAX] = {0,}; -        int32_t ret = -1; -        glusterd_conf_t *priv = NULL; -        DIR     *dir = NULL; -        struct dirent *entry = NULL; -        char path[PATH_MAX] = {0,}; - -        GF_ASSERT (volinfo); -        priv = THIS->private; - -        GF_ASSERT (priv); -        snprintf (pathname, 1024, "%s/vols/%s", priv->workdir, -                  volinfo->volname); - -        dir = opendir (pathname); -        if (!dir) -                goto out; - -        entry = readdir (dir); -        while (entry != NULL) { -                if (!strcmp (entry->d_name, ".") || -                    !strcmp (entry->d_name, "..")) { -                        entry = readdir (dir); -                        continue; -                } -                snprintf (path, PATH_MAX, "%s/%s", pathname, entry->d_name); -                if (DT_DIR  == entry->d_type) -                        ret = rmdir (path); -                else -                        ret = unlink (path); - -                gf_log ("", GF_LOG_NORMAL, "%s %s", -                                ret?"Failed to remove":"Removed", -                                entry->d_name); -                if (ret) -                        gf_log ("", GF_LOG_NORMAL, "errno:%d", errno); -                entry = readdir (dir); -                memset (path, 0, sizeof(path)); -        } - -        ret = closedir (dir); -        if (ret) { -                gf_log ("", GF_LOG_NORMAL, "Failed to close dir, errno:%d", -                        errno); -        } - -        ret = rmdir (pathname); -        if (ret) { -                gf_log ("", GF_LOG_ERROR, "Failed to rmdir: %s, errno: %d", -                        pathname, errno); -        } - - -out: -        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); - -        return ret; -} - - diff --git a/xlators/mgmt/glusterd/src/glusterd-ha.h b/xlators/mgmt/glusterd/src/glusterd-ha.h deleted file mode 100644 index b31142a6707..00000000000 --- a/xlators/mgmt/glusterd/src/glusterd-ha.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -  Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com> -  This file is part of GlusterFS. - -  GlusterFS is free software; you can redistribute it and/or modify -  it under the terms of the GNU General Public License as published -  by the Free Software Foundation; either version 3 of the License, -  or (at your option) any later version. - -  GlusterFS 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 -  General Public License for more details. - -  You should have received a copy of the GNU General Public License -  along with this program.  If not, see -  <http://www.gnu.org/licenses/>. -*/ - -#ifndef _GLUSTERD_HA_H_ -#define _GLUSTERD_HA_H_ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <pthread.h> -#include "uuid.h" - -#include "glusterfs.h" -#include "xlator.h" -#include "logging.h" -#include "call-stub.h" -#include "fd.h" -#include "byte-order.h" -#include "glusterd.h" -#include "rpcsvc.h" - -int32_t -glusterd_ha_create_volume (glusterd_volinfo_t *volinfo); - -int32_t -glusterd_ha_delete_volume (glusterd_volinfo_t *volinfo); - -#endif diff --git a/xlators/mgmt/glusterd/src/glusterd-mem-types.h b/xlators/mgmt/glusterd/src/glusterd-mem-types.h index 2cbdf22ab91..8df94163d61 100644 --- a/xlators/mgmt/glusterd/src/glusterd-mem-types.h +++ b/xlators/mgmt/glusterd/src/glusterd-mem-types.h @@ -52,6 +52,8 @@ enum gf_gld_mem_types_ {          gf_gld_mt_glusterd_brickinfo_t,          gf_gld_mt_peer_hostname_t,          gf_gld_mt_ifreq, +        gf_gld_mt_store_handle_t, +        gf_gld_mt_store_iter_t,          gf_gld_mt_end  };  #endif diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 55533c1181e..31e2a9e50f2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -43,7 +43,7 @@  #include "glusterd-sm.h"  #include "glusterd-op-sm.h"  #include "glusterd-utils.h" -#include "glusterd-ha.h" +#include "glusterd-store.h"  #include "cli1.h"  static struct list_head gd_op_sm_queue; @@ -690,7 +690,7 @@ glusterd_op_create_volume (gd1_mgmt_stage_op_req *req)          }          list_add_tail (&volinfo->vol_list, &priv->volumes); -        ret = glusterd_ha_create_volume (volinfo); +        ret = glusterd_store_create_volume (volinfo);          if (ret)                  goto out; @@ -816,11 +816,11 @@ glusterd_op_add_brick (gd1_mgmt_stage_op_req *req)                          goto out;          } -/*        ret = glusterd_ha_update_volume (volinfo); +        ret = glusterd_store_update_volume (volinfo);          if (ret)                  goto out; -*/ +  out: @@ -938,11 +938,11 @@ glusterd_op_remove_brick (gd1_mgmt_stage_op_req *req)                          goto out;          } -/*        ret = glusterd_ha_update_volume (volinfo); +        ret = glusterd_store_update_volume (volinfo);          if (ret)                  goto out; -*/ +  out: @@ -973,7 +973,7 @@ glusterd_op_delete_volume (gd1_mgmt_stage_op_req *req)          if (ret)                  goto out; -        ret = glusterd_ha_delete_volume (volinfo); +        ret = glusterd_store_delete_volume (volinfo);          if (ret)                  goto out; diff --git a/xlators/mgmt/glusterd/src/glusterd-store.c b/xlators/mgmt/glusterd/src/glusterd-store.c new file mode 100644 index 00000000000..8d66fe6feaa --- /dev/null +++ b/xlators/mgmt/glusterd/src/glusterd-store.c @@ -0,0 +1,961 @@ +/* +  Copyright (c) 2007-2010 Gluster, Inc. <http://www.gluster.com> +  This file is part of GlusterFS. + +  GlusterFS is free software; you can redistribute it and/or modify +  it under the terms of the GNU General Public License as published +  by the Free Software Foundation; either version 3 of the License, +  or (at your option) any later version. + +  GlusterFS 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 +  General Public License for more details. + +  You should have received a copy of the GNU General Public License +  along with this program.  If not, see +  <http://www.gnu.org/licenses/>. +*/ +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif +#include <inttypes.h> + + +#include "globals.h" +#include "glusterfs.h" +#include "compat.h" +#include "dict.h" +#include "protocol-common.h" +#include "xlator.h" +#include "logging.h" +#include "timer.h" +#include "defaults.h" +#include "compat.h" +#include "compat-errno.h" +#include "statedump.h" +#include "glusterd-mem-types.h" +#include "glusterd.h" +#include "glusterd-sm.h" +#include "glusterd-op-sm.h" +#include "glusterd-utils.h" +#include "glusterd-store.h" + +#include "glusterd1.h" +#include "cli1.h" +#include "rpc-clnt.h" + +#include <sys/resource.h> +#include <inttypes.h> +#include <dirent.h> + +static int32_t +glusterd_store_create_volume_dir (char *volname) +{ +        int32_t                 ret = -1; +        char                    path[PATH_MAX] = {0,}; +        glusterd_conf_t         *priv = NULL; + +        GF_ASSERT (volname); +        priv = THIS->private; + +        GF_ASSERT (priv); + +        snprintf (path, 1024, "%s/vols/%s", priv->workdir, +                  volname); + +        ret = mkdir (path, 0x777); + +        if (-1 == ret) { +                gf_log ("", GF_LOG_ERROR, "mkdir() failed on path %s," +                        "errno: %d", path, errno); +                goto out; +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +} + +int32_t +glusterd_store_create_brick (glusterd_volinfo_t *volinfo, +                             glusterd_brickinfo_t *brickinfo) +{ +        int32_t                 ret = -1; +        glusterd_conf_t         *priv = NULL; +        char                    path[PATH_MAX] = {0,}; +        char                    brickpath[PATH_MAX] = {0,}; +        struct  stat            stbuf = {0,}; +        int                     fd = -1; +        char                    buf[4096] = {0,}; +        char                    *tmppath = NULL; +        char                    *ptr = NULL; + +        GF_ASSERT (volinfo); +        GF_ASSERT (brickinfo); + +        priv = THIS->private; + +        GF_ASSERT (priv); + +        GLUSTERD_GET_BRICK_DIR (path, volinfo, priv); + +        ret = stat (path, &stbuf); + +        if (ret == -1 && ENOENT == errno) { +                ret = mkdir (path, 0x777); +                if (ret) +                        goto out; +        } + +        tmppath = gf_strdup (brickinfo->path); + +        ptr = strchr (tmppath, '/'); + +        while (ptr) { +                *ptr = '-'; +                ptr = strchr (tmppath, '/'); +        } + +        snprintf (brickpath, sizeof (brickpath), "%s/%s:%s", +                  path, brickinfo->hostname, tmppath); + +        GF_FREE (tmppath); + +        fd = open (brickpath, O_RDWR | O_CREAT | O_APPEND, 0666); + +        if (fd < 0) { +                gf_log ("", GF_LOG_ERROR, "Open failed on %s", +                        brickpath); +                ret = -1; +                goto out; +        } + + +        snprintf (buf, sizeof(buf), "hostname=%s\n", brickinfo->hostname); +        write (fd, buf, strlen(buf)); +        snprintf (buf, sizeof(buf), "path=%s\n", brickinfo->path); +        write (fd, buf, strlen(buf)); + +        ret = 0; + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +} + +int32_t +glusterd_store_delete_brick (glusterd_volinfo_t *volinfo, +                             glusterd_brickinfo_t *brickinfo) +{ +        int32_t                 ret = -1; +        glusterd_conf_t         *priv = NULL; +        char                    path[PATH_MAX] = {0,}; +        char                    brickpath[PATH_MAX] = {0,}; +        char                    *ptr = NULL; +        char                    *tmppath = NULL; + +        GF_ASSERT (volinfo); +        GF_ASSERT (brickinfo); + +        priv = THIS->private; + +        GF_ASSERT (priv); + +        GLUSTERD_GET_BRICK_DIR (path, volinfo, priv); + +        tmppath = gf_strdup (brickinfo->path); + +        ptr = strchr (tmppath, '/'); + +        while (ptr) { +                *ptr = '-'; +                ptr = strchr (tmppath, '/'); +        } + +        snprintf (brickpath, sizeof (brickpath), "%s/%s:%s", +                  path, brickinfo->hostname, tmppath); + +        GF_FREE (tmppath); + +        ret = unlink (brickpath); + +        if (ret < 0) { +                gf_log ("", GF_LOG_ERROR, "Unlink failed on %s", +                        brickpath); +                ret = -1; +                goto out; +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +} + +int32_t +glusterd_store_remove_bricks (glusterd_volinfo_t *volinfo) +{ +        int32_t                 ret = -1; +        glusterd_brickinfo_t    *tmp = NULL; +        glusterd_conf_t         *priv = NULL; +        char                    brickdir [PATH_MAX] = {0,}; +        DIR                     *dir = NULL; +        struct dirent           *entry = NULL; +        char                    path[PATH_MAX] = {0,}; + +        GF_ASSERT (volinfo); + +        list_for_each_entry (tmp, &volinfo->bricks, brick_list) { +                ret = glusterd_store_delete_brick (volinfo, tmp); +                if (ret) +                        goto out; +        } + +        priv = THIS->private; +        GF_ASSERT (priv); + +        GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv); + +        dir = opendir (brickdir); + +        glusterd_for_each_entry (entry, dir); + +        while (entry) { +                snprintf (path, sizeof (path), "%s/%s", +                          brickdir, entry->d_name); +                ret = unlink (path); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to unlink %s", +                                path); +                } +                glusterd_for_each_entry (entry, dir); +        } + +        closedir (dir); + +        ret = rmdir (brickdir); + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +} + +int32_t +glusterd_store_create_volume (glusterd_volinfo_t *volinfo) +{ +        int32_t                 ret = -1; +        char                    filepath[PATH_MAX] = {0,}; +        char                    buf[4096] = {0,}; +        glusterd_conf_t         *priv = NULL; +        glusterd_brickinfo_t    *brickinfo = NULL; + +        GF_ASSERT (volinfo); +        priv = THIS->private; + +        GF_ASSERT (priv); + +        ret = glusterd_store_create_volume_dir (volinfo->volname); + +        if (ret) +                goto out; + +        snprintf (filepath, 1024, "%s/%s/%s/%s", priv->workdir, +                  GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, +                  GLUSTERD_VOLUME_INFO_FILE); + +        ret = glusterd_store_handle_new (filepath, &volinfo->shandle); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to create store" +                        " handle for path: %s", filepath); +                goto out; +        } + +        snprintf (buf, sizeof (buf), "%d", volinfo->type); +        ret = glusterd_store_save_value (volinfo->shandle, +                                        GLUSTERD_STORE_KEY_VOL_TYPE, buf); +        if (ret) +                goto out; + +        snprintf (buf, sizeof (buf), "%d", volinfo->brick_count); +        ret = glusterd_store_save_value (volinfo->shandle, +                                        GLUSTERD_STORE_KEY_VOL_COUNT, buf); +        if (ret) +                goto out; + +        snprintf (buf, sizeof (buf), "%d", volinfo->status); +        ret = glusterd_store_save_value (volinfo->shandle, +                                        GLUSTERD_STORE_KEY_VOL_STATUS, buf); +        if (ret) +                goto out; + +        snprintf (buf, sizeof (buf), "%d", volinfo->status); +        ret = glusterd_store_save_value (volinfo->shandle, +                                        GLUSTERD_STORE_KEY_VOL_PORT, buf); +        if (ret) +                goto out; + +        snprintf (buf, sizeof (buf), "%d", volinfo->sub_count); +        ret = glusterd_store_save_value (volinfo->shandle, +                                        GLUSTERD_STORE_KEY_VOL_SUB_COUNT, buf); +        if (ret) +                goto out; + +        list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) { +                ret = glusterd_store_create_brick (volinfo, brickinfo); +                if (ret) +                        goto out; +        } + +        ret = 0; + +out: +        if (ret) { +                glusterd_store_delete_volume (volinfo); +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + + +int32_t +glusterd_store_delete_volume (glusterd_volinfo_t *volinfo) +{ +        char    pathname[PATH_MAX] = {0,}; +        int32_t ret = -1; +        glusterd_conf_t *priv = NULL; +        DIR     *dir = NULL; +        struct dirent *entry = NULL; +        char path[PATH_MAX] = {0,}; + +        GF_ASSERT (volinfo); +        priv = THIS->private; + +        GF_ASSERT (priv); +        snprintf (pathname, 1024, "%s/vols/%s", priv->workdir, +                  volinfo->volname); + +        dir = opendir (pathname); +        if (!dir) +                goto out; +        ret = glusterd_store_remove_bricks (volinfo); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Remove bricks failed"); +        } + +        glusterd_for_each_entry (entry, dir); +        while (entry) { + +                snprintf (path, PATH_MAX, "%s/%s", pathname, entry->d_name); +                if (DT_DIR  == entry->d_type) +                        ret = rmdir (path); +                else +                        ret = unlink (path); + +                gf_log ("", GF_LOG_NORMAL, "%s %s", +                                ret?"Failed to remove":"Removed", +                                entry->d_name); +                if (ret) +                        gf_log ("", GF_LOG_NORMAL, "errno:%d", errno); +                memset (path, 0, sizeof(path)); +                glusterd_for_each_entry (entry, dir); +        } + +        ret = closedir (dir); +        if (ret) { +                gf_log ("", GF_LOG_NORMAL, "Failed to close dir, errno:%d", +                        errno); +        } + +        ret = rmdir (pathname); +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Failed to rmdir: %s, errno: %d", +                        pathname, errno); +        } + + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + + + +int32_t +glusterd_store_retrieve_value (glusterd_store_handle_t *handle, +                               char *key, char **value) +{ +        int32_t         ret = -1; +        char            scan_str[4096] = {0,}; +        char            *iter_key = NULL; +        char            *iter_val = NULL; +        char            *str = NULL; + +        GF_ASSERT (handle); +        GF_ASSERT (handle->fd > 0); + +        if (!handle->read) +                handle->read = fdopen (handle->fd, "r"); + +        if (!handle->read) { +                gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %d", +                        handle->path, errno); +                goto out; +        } + +        ret = fscanf (handle->read, "%s", scan_str); + +        while (ret != EOF) { +                str = gf_strdup (scan_str); +                if (!str) +                        goto out; +                iter_key = strtok (str, "="); +                gf_log ("", GF_LOG_DEBUG, "key %s read", iter_key); + +                if (!strcmp (key, iter_key)) { +                        gf_log ("", GF_LOG_DEBUG, "key %s found", key); +                        iter_val = strtok (NULL, "="); +                        ret = 0; +                        *value = gf_strdup (iter_val); +                        goto out; +                } + +                ret = fscanf (handle->read, "%s", scan_str); +        } + +        if (EOF == ret) +                ret = -1; +out: + +        return ret; +} + +int32_t +glusterd_store_save_value (glusterd_store_handle_t *handle, +                           char *key, char *value) +{ +        int32_t         ret = -1; +        char            buf[4096] = {0,}; + +        GF_ASSERT (handle); +        GF_ASSERT (handle->fd > 0); +        GF_ASSERT (key); +        GF_ASSERT (value); + +        if (!handle->write) +                handle->write = fdopen (handle->fd, "a+"); + +        if (!handle->write) { +                gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %d", +                        handle->path, errno); +                goto out; +        } + +        snprintf (buf, sizeof (buf), "%s=%s\n", key, value); +        ret = write (handle->fd, buf, strlen (buf)); +        //ret = fprintf (handle->write, "%s=%s\n", key, value); + +        if (ret < 0) { +                gf_log ("", GF_LOG_CRITICAL, "Unable to store key: %s," +                        "value: %s, error: %s", key, value, +                        strerror (errno)); +                ret = -1; +                goto out; +        } + +        ret = 0; + +out: + +        gf_log ("", GF_LOG_DEBUG, "returning: %d", ret); +        return ret; +} + +int32_t +glusterd_store_handle_new (char *path, glusterd_store_handle_t **handle) +{ +        int32_t                 ret = -1; +        glusterd_store_handle_t *shandle = NULL; + +        shandle = GF_CALLOC (1, sizeof (*shandle), gf_gld_mt_store_handle_t); +        if (!shandle) +                goto out; + +        shandle->path = gf_strdup (path); + +        if (!shandle->path) +                goto out; + +        shandle->fd = open (path, O_RDWR | O_CREAT | O_APPEND, 0644); +        if (!shandle->fd) +                goto out; + +        *handle = shandle; + +        ret = 0; + +out: +        if (ret == -1) { +                if (shandle) { +                        if (shandle->path) +                                GF_FREE (shandle->path); +                        GF_FREE (shandle); +                } +        } + +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + +        return ret; +} + +int32_t +glusterd_store_uuid () +{ +        char            str[GLUSTERD_UUID_LEN] = {0,}; +        glusterd_conf_t *priv = NULL; +        char            path[PATH_MAX] = {0,}; +        int32_t         ret = -1; +        glusterd_store_handle_t *handle = NULL; + +        priv = THIS->private; + +        uuid_unparse (priv->uuid, str); + +        snprintf (path, PATH_MAX, "%s/%s", priv->workdir, +                  GLUSTERD_INFO_FILE); + +        if (!priv->handle) { +                ret = glusterd_store_handle_new (path, &handle); + +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to get store" +                                " handle!"); +                        goto out; +                } + +                priv->handle = handle; +        } + +        ret = glusterd_store_save_value (priv->handle, GLUSTERD_STORE_UUID_KEY, +                                         str); + +        if (ret) { +                gf_log ("", GF_LOG_CRITICAL, "Storing uuid failed" +                        "ret = %d", ret); +                goto out; +        } + + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + + +int32_t +glusterd_retrieve_uuid () +{ +        char            *uuid_str = NULL; +        int32_t         ret = -1; +        glusterd_store_handle_t *handle = NULL; +        glusterd_conf_t *priv = NULL; +        char            path[PATH_MAX] = {0,}; + +        priv = THIS->private; + + +        if (!priv->handle) { +                snprintf (path, PATH_MAX, "%s/%s", priv->workdir, +                          GLUSTERD_INFO_FILE); +                ret = glusterd_store_handle_new (path, &handle); + +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to get store " +                                "handle!"); +                        goto out; +                } + +                priv->handle = handle; +        } + +        ret = glusterd_store_retrieve_value (priv->handle, +                                             GLUSTERD_STORE_UUID_KEY, +                                             &uuid_str); + +        if (ret) { +                gf_log ("", GF_LOG_CRITICAL, "Retrieving uuid failed" +                        " ret = %d", ret); +                goto out; +        } + +        uuid_parse (uuid_str, priv->uuid); + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +int32_t +glusterd_store_iter_new (glusterd_store_handle_t  *shandle, +                         glusterd_store_iter_t  **iter) +{ +        int32_t                 ret = -1; +        glusterd_store_iter_t   *tmp_iter = NULL; +        int                     fd = -1; + +        GF_ASSERT (shandle); +        GF_ASSERT (shandle->fd > 0); +        GF_ASSERT (iter); + +        tmp_iter = GF_CALLOC (1, sizeof (*tmp_iter), +                             gf_gld_mt_store_iter_t); + +        if (!tmp_iter) { +                gf_log ("", GF_LOG_ERROR, "Out of Memory"); +                goto out; +        } + +        fd = open (shandle->path, O_RDWR); + +        if (fd < 0) { +                gf_log ("", GF_LOG_ERROR, "Unable to open %s", +                        shandle->path); +                goto out; +        } + +        tmp_iter->fd = fd; + +        tmp_iter->file = fdopen (shandle->fd, "r"); + +        if (!tmp_iter->file) { +                gf_log ("", GF_LOG_ERROR, "Unable to open file %s errno: %d", +                        shandle->path, errno); +                goto out; +        } + +        *iter = tmp_iter; +        ret = 0; + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +} + +int32_t +glusterd_store_iter_get_next (glusterd_store_iter_t *iter, +                              char  **key, char **value) +{ +        int32_t         ret = -1; +        char            scan_str[4096] = {0,}; +        char            *str = NULL; +        char            *iter_key = NULL; +        char            *iter_val = NULL; + +        GF_ASSERT (iter); +        GF_ASSERT (iter->file); + +        ret = fscanf (iter->file, "%s", scan_str); + +        if (ret <= 0) { +                ret = -1; +                goto out; +        } + +        str = gf_strdup (scan_str); +        if (!str) +                goto out; + +        iter_key = strtok (str, "="); +        gf_log ("", GF_LOG_DEBUG, "key %s read", iter_key); + + +        iter_val = strtok (NULL, "="); +        gf_log ("", GF_LOG_DEBUG, "value %s read", iter_val); + +        *value = gf_strdup (iter_val); +        *key   = gf_strdup (iter_key); + +        ret = 0; + +out: +        if (str) +                GF_FREE (str); + +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); +        return ret; +} + +int32_t +glusterd_store_iter_destroy (glusterd_store_iter_t *iter) +{ +        int32_t         ret = -1; + +        GF_ASSERT (iter); +        GF_ASSERT (iter->fd > 0); + +        ret = fclose (iter->file); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to close fd: %d, ret: %d, " +                        "errno: %d" ,iter->fd, ret, errno); +        } + +        GF_FREE (iter); + +        return ret; +} + +int32_t +glusterd_store_retrieve_bricks (glusterd_volinfo_t *volinfo) +{ + +        int32_t                 ret = -1; +        glusterd_brickinfo_t    *brickinfo = NULL; +        glusterd_store_iter_t   *iter = NULL; +        char                    *key = NULL; +        char                    *value = NULL; +        char                    brickdir[PATH_MAX] = {0,}; +        char                    path[PATH_MAX] = {0,}; +        glusterd_conf_t         *priv = NULL; +        DIR                     *dir = NULL; +        struct dirent           *entry = NULL; + +        GF_ASSERT (volinfo); +        GF_ASSERT (volinfo->volname); + +        priv = THIS->private; + +        GLUSTERD_GET_BRICK_DIR (brickdir, volinfo, priv); + +        dir = opendir (brickdir); + +        glusterd_for_each_entry (entry, dir); + +        while (entry) { +                ret = glusterd_brickinfo_new (&brickinfo); + +                if (ret) +                        goto out; + +                snprintf (path, sizeof (path), "%s/%s", brickdir, +                          entry->d_name); + +                ret = glusterd_store_handle_new (path, &brickinfo->shandle); + +                if (ret) +                        goto out; + +                ret = glusterd_store_iter_new (brickinfo->shandle, &iter); + +                if (ret) +                        goto out; + +                ret = glusterd_store_iter_get_next (iter, &key, &value); + +                while (!ret) { +                        if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_HOSTNAME, +                                      strlen (GLUSTERD_STORE_KEY_BRICK_HOSTNAME))) { +                                strncpy (brickinfo->hostname, value, 1024); +                        } else if (!strncmp (key, GLUSTERD_STORE_KEY_BRICK_PATH, +                                    strlen (GLUSTERD_STORE_KEY_BRICK_PATH))) { +                                strncpy (brickinfo->path, value, +                                         sizeof (brickinfo->path)); +                        }else { +                                gf_log ("", GF_LOG_ERROR, "Unknown key: %s", +                                        key); +                        } + +                        GF_FREE (key); +                        GF_FREE (value); + +                        ret = glusterd_store_iter_get_next (iter, &key, &value); +                } + +                ret = glusterd_store_iter_destroy (iter); + +                if (ret) +                        goto out; + +                list_add_tail (&brickinfo->brick_list, &volinfo->bricks); +                glusterd_for_each_entry (entry, dir); +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + +        return ret; +} + + +int32_t +glusterd_store_retrieve_volume (char    *volname) +{ +        int32_t                 ret = -1; +        glusterd_volinfo_t      *volinfo = NULL; +        glusterd_store_iter_t   *iter = NULL; +        char                    *key = NULL; +        char                    *value = NULL; +        char                    volpath[PATH_MAX] = {0,}; +        glusterd_conf_t         *priv = NULL; +        char                    path[PATH_MAX] = {0,}; + +        ret = glusterd_volinfo_new (&volinfo); + +        if (ret) +                goto out; + +        strncpy (volinfo->volname, volname, GLUSTERD_MAX_VOLUME_NAME); + +        priv = THIS->private; + +        GLUSTERD_GET_VOLUME_DIR(volpath, volinfo, priv); +        snprintf (path, sizeof (path), "%s/%s", volpath, +                  GLUSTERD_VOLUME_INFO_FILE); + +        ret = glusterd_store_handle_new (path, &volinfo->shandle); + +        if (ret) +                goto out; + +        ret = glusterd_store_iter_new (volinfo->shandle, &iter); + +        if (ret) +                goto out; + +        ret = glusterd_store_iter_get_next (iter, &key, &value); + +        while (!ret) { +                if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_TYPE, +                              strlen (GLUSTERD_STORE_KEY_VOL_TYPE))) { +                        volinfo->type = atoi (value); +                } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_COUNT, +                            strlen (GLUSTERD_STORE_KEY_VOL_COUNT))) { +                        volinfo->brick_count = atoi (value); +                } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_STATUS, +                            strlen (GLUSTERD_STORE_KEY_VOL_STATUS))) { +                        volinfo->status = atoi (value); +                } else if (!strncmp (key, GLUSTERD_STORE_KEY_VOL_PORT, +                            strlen (GLUSTERD_STORE_KEY_VOL_PORT))) { +                        volinfo->port = atoi (value); +                } else { +                        gf_log ("", GF_LOG_ERROR, "Unknown key: %s", +                                        key); +                } + +                GF_FREE (key); +                GF_FREE (value); + +                ret = glusterd_store_iter_get_next (iter, &key, &value); +        } + +        ret = glusterd_store_iter_destroy (iter); + +        if (ret) +                goto out; + +        ret = glusterd_store_retrieve_bricks (volinfo); + +        list_add_tail (&volinfo->vol_list, &priv->volumes); + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + +        return ret; +} + + +int32_t +glusterd_store_retrieve_volumes (xlator_t  *this) +{ +        int32_t         ret = 0; +        char            path[PATH_MAX] = {0,}; +        glusterd_conf_t *priv = NULL; +        DIR             *dir = NULL; +        struct dirent   *entry = NULL; + +        GF_ASSERT (this); +        priv = this->private; + +        GF_ASSERT (priv); + +        snprintf (path, PATH_MAX, "%s/%s", priv->workdir, +                        GLUSTERD_VOLUME_DIR_PREFIX); + +        dir = opendir (path); + +        if (!dir) { +                gf_log ("", GF_LOG_ERROR, "Unable to open dir %s", path); +                ret = -1; +                goto out; +        } + +        glusterd_for_each_entry (entry, dir); + +        while (entry) { +                ret = glusterd_store_retrieve_volume (entry->d_name); +                if (ret) { +                        gf_log ("", GF_LOG_ERROR, "Unable to restore " +                                "volume: %s", entry->d_name); +                        goto out; +                } +                glusterd_for_each_entry (entry, dir); +        } + +out: +        if (dir) +                closedir (dir); +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + +        return ret; +} + +int32_t +glusterd_store_update_volume (glusterd_volinfo_t *volinfo) +{ +        int32_t         ret = -1; + +        ret = glusterd_store_delete_volume (volinfo); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to delete " +                        "volume: %s", volinfo->volname); +                goto out; +        } + +        ret = glusterd_store_create_volume (volinfo); + +        if (ret) { +                gf_log ("", GF_LOG_ERROR, "Unable to create " +                        "volume: %s", volinfo->volname); +                goto out; +        } + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning with %d", ret); + +        return ret; +} + + +int32_t +glusterd_restore () +{ +        int             ret = -1; +        xlator_t        *this = NULL; + +        this = THIS; + +        ret = glusterd_store_retrieve_volumes (this); + +        if (ret) +                goto out; + +out: +        gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h new file mode 100644 index 00000000000..c3be21502af --- /dev/null +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -0,0 +1,90 @@ +/* +  Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com> +  This file is part of GlusterFS. + +  GlusterFS is free software; you can redistribute it and/or modify +  it under the terms of the GNU General Public License as published +  by the Free Software Foundation; either version 3 of the License, +  or (at your option) any later version. + +  GlusterFS 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 +  General Public License for more details. + +  You should have received a copy of the GNU General Public License +  along with this program.  If not, see +  <http://www.gnu.org/licenses/>. +*/ + +#ifndef _GLUSTERD_HA_H_ +#define _GLUSTERD_HA_H_ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include "uuid.h" + +#include "glusterfs.h" +#include "xlator.h" +#include "logging.h" +#include "call-stub.h" +#include "fd.h" +#include "byte-order.h" +#include "glusterd.h" +#include "rpcsvc.h" + + +#define GLUSTERD_STORE_UUID_KEY  "UUID" + +#define GLUSTERD_STORE_KEY_VOL_TYPE "type" +#define GLUSTERD_STORE_KEY_VOL_COUNT "count" +#define GLUSTERD_STORE_KEY_VOL_STATUS "status" +#define GLUSTERD_STORE_KEY_VOL_PORT   "port" +#define GLUSTERD_STORE_KEY_VOL_SUB_COUNT   "sub_count" +#define GLUSTERD_STORE_KEY_VOL_BRICK  "brick" + +#define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname" +#define GLUSTERD_STORE_KEY_BRICK_PATH "path" + +#define glusterd_for_each_entry(entry, dir) \ +        do {\ +                entry = readdir (dir);\ +                while (entry && (!strcmp (entry->d_name, ".") ||\ +                    !strcmp (entry->d_name, ".."))) {\ +                        entry = readdir (dir);\ +                }\ +        } while (0); \ + +int32_t +glusterd_store_create_volume (glusterd_volinfo_t *volinfo); + +int32_t +glusterd_store_delete_volume (glusterd_volinfo_t *volinfo); + +int32_t +glusterd_store_uuid (); + +int32_t +glusterd_store_handle_new (char *path, glusterd_store_handle_t **handle); + +int32_t +glusterd_store_save_value (glusterd_store_handle_t *handle, +                           char *key, char *value); + +int32_t +glusterd_store_retrieve_value (glusterd_store_handle_t *handle, +                               char *key, char **value); + +int32_t +glusterd_store_update_volume (glusterd_volinfo_t *volinfo); + +int32_t +glusterd_retrieve_uuid (); + +int32_t +glusterd_restore (); +#endif diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c index 338ebc2778a..6b32bd3a0d8 100644 --- a/xlators/mgmt/glusterd/src/glusterd-utils.c +++ b/xlators/mgmt/glusterd/src/glusterd-utils.c @@ -878,6 +878,7 @@ glusterd_is_cli_op_req (int32_t op)                  case GD_MGMT_CLI_DELETE_VOLUME:                  case GD_MGMT_CLI_DEFRAG_VOLUME:                  case GD_MGMT_CLI_ADD_BRICK: +                case GD_MGMT_CLI_REMOVE_BRICK:                          return _gf_true;                          break;          } diff --git a/xlators/mgmt/glusterd/src/glusterd.c b/xlators/mgmt/glusterd/src/glusterd.c index cfd07433b15..5b75c93fadd 100644 --- a/xlators/mgmt/glusterd/src/glusterd.c +++ b/xlators/mgmt/glusterd/src/glusterd.c @@ -42,6 +42,7 @@  #include "statedump.h"  #include "glusterd-sm.h"  #include "glusterd-op-sm.h" +#include "glusterd-store.h"  static uuid_t glusterd_uuid; @@ -50,17 +51,6 @@ extern struct rpcsvc_program gluster_handshake_prog;  extern struct rpc_clnt_program glusterd3_1_mgmt_prog;  extern glusterd_op_info_t opinfo; -static int -glusterd_retrieve_uuid () -{ -        return -1; -} - -static int -glusterd_store_uuid () -{ -        return 0; -}  static int  glusterd_opinfo_init () @@ -75,22 +65,28 @@ glusterd_opinfo_init ()  static int  glusterd_uuid_init ()  { -        int     ret = -1; -        char    str[50]; +        int             ret = -1; +        char            str[50] = {0,}; +        glusterd_conf_t *priv = NULL; +        priv = THIS->private;          ret = glusterd_retrieve_uuid ();          if (!ret) { +                uuid_unparse (priv->uuid, str); +                uuid_copy (glusterd_uuid, priv->uuid);                  gf_log ("glusterd", GF_LOG_NORMAL, -                                "retrieved UUID: %s", glusterd_uuid); +                                "retrieved UUID: %s", str);                  return 0;          } +          uuid_generate (glusterd_uuid);          uuid_unparse (glusterd_uuid, str);          gf_log ("glusterd", GF_LOG_NORMAL,                          "generated UUID: %s",str); +        uuid_copy (priv->uuid, glusterd_uuid);          ret = glusterd_store_uuid (); @@ -285,11 +281,14 @@ init (xlator_t *this)          if (ret < 0)                  goto out; +        ret = glusterd_restore (); +        if (ret < 0) +                goto out; +          glusterd_friend_sm_init ();          glusterd_op_sm_init ();          glusterd_opinfo_init (); -        memcpy(conf->uuid, glusterd_uuid, sizeof (uuid_t));          ret = 0;  out: diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 6446f2fc111..9f0986bb62f 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -40,7 +40,23 @@  #include "glusterd-sm.h"  #include "glusterd1-xdr.h" +#define GLUSTERD_MAX_VOLUME_NAME        1000 +struct glusterd_store_handle_ { +        char    *path; +        int     fd; +        FILE    *read; +        FILE    *write; +}; + +typedef struct glusterd_store_handle_  glusterd_store_handle_t; + +struct glusterd_store_iter_ { +        int     fd; +        FILE    *file; +}; + +typedef struct glusterd_store_iter_     glusterd_store_iter_t;  typedef struct {          struct _volfile_ctx *volfile; @@ -55,6 +71,7 @@ typedef struct {          rpc_clnt_prog_t   *mgmt;          struct list_head  volumes;          struct list_head  hostnames; +        glusterd_store_handle_t *handle;  } glusterd_conf_t;  struct glusterd_brickinfo { @@ -62,19 +79,21 @@ struct glusterd_brickinfo {          char    path[PATH_MAX];          struct list_head  brick_list;          uuid_t  uuid; +        glusterd_store_handle_t *shandle;  };  typedef struct glusterd_brickinfo glusterd_brickinfo_t;  struct glusterd_volinfo_ { -        char    volname[1024]; -        int     type; -        int     brick_count; +        char                    volname[GLUSTERD_MAX_VOLUME_NAME]; +        int                     type; +        int                     brick_count;          struct list_head        vol_list;          struct list_head        bricks;          glusterd_volume_status  status; -        int     sub_count; -        int     port; +        int                     sub_count; +        int                     port; +        glusterd_store_handle_t *shandle;  };  typedef struct glusterd_volinfo_ glusterd_volinfo_t; @@ -85,6 +104,12 @@ enum glusterd_op_ret {  #define GLUSTERD_DEFAULT_WORKDIR "/etc/glusterd"  #define GLUSTERD_DEFAULT_PORT   6969 +#define GLUSTERD_INFO_FILE      "glusterd.info" +#define GLUSTERD_VOLUME_DIR_PREFIX "vols" +#define GLUSTERD_VOLUME_INFO_FILE "info" +#define GLUSTERD_BRICK_INFO_DIR "bricks" + +#define GLUSTERD_UUID_LEN 50  typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args); @@ -92,6 +117,11 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);          snprintf (path, PATH_MAX, "%s/vols/%s", priv->workdir,\                    volinfo->volname); +#define GLUSTERD_GET_BRICK_DIR(path, volinfo, priv) \ +        snprintf (path, PATH_MAX, "%s/%s/%s/%s", priv->workdir,\ +                  GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \ +                  GLUSTERD_BRICK_INFO_DIR); +  #define GLUSTERD_GET_BRICK_PIDFILE(pidfile, volpath, hostname, count)         \          snprintf (pidfile, PATH_MAX, "%s/run/%s-%d.pid", volpath, hostname, count);  | 
