diff options
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | xlators/features/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/features/ganesha/Makefile.am | 3 | ||||
| -rw-r--r-- | xlators/features/ganesha/src/Makefile.am | 18 | ||||
| -rw-r--r-- | xlators/features/ganesha/src/ganesha-mem-types.h | 21 | ||||
| -rw-r--r-- | xlators/features/ganesha/src/ganesha.c | 85 | ||||
| -rw-r--r-- | xlators/features/ganesha/src/ganesha.h | 23 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/Makefile.am | 5 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-ganesha.c | 365 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volgen.c | 48 | ||||
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 2 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs.c | 11 | 
12 files changed, 543 insertions, 42 deletions
diff --git a/configure.ac b/configure.ac index ffa71c9f1fa..84eb0f40d45 100644 --- a/configure.ac +++ b/configure.ac @@ -139,6 +139,8 @@ AC_CONFIG_FILES([Makefile                  xlators/features/quiesce/src/Makefile                  xlators/features/barrier/Makefile                  xlators/features/barrier/src/Makefile +                xlators/features/ganesha/Makefile +                xlators/features/ganesha/src/Makefile                  xlators/features/index/Makefile                  xlators/features/index/src/Makefile                  xlators/features/protect/Makefile diff --git a/xlators/features/Makefile.am b/xlators/features/Makefile.am index 096f0e04bb2..4a332555ffc 100644 --- a/xlators/features/Makefile.am +++ b/xlators/features/Makefile.am @@ -1,5 +1,5 @@  SUBDIRS = locks quota read-only mac-compat quiesce marker index barrier \ -          protect compress changelog gfid-access $(GLUPY_SUBDIR) qemu-block \ +          protect compress changelog ganesha gfid-access $(GLUPY_SUBDIR) qemu-block \            upcall snapview-client snapview-server trash # path-converter # filter  CLEANFILES = diff --git a/xlators/features/ganesha/Makefile.am b/xlators/features/ganesha/Makefile.am new file mode 100644 index 00000000000..a985f42a877 --- /dev/null +++ b/xlators/features/ganesha/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = src + +CLEANFILES = diff --git a/xlators/features/ganesha/src/Makefile.am b/xlators/features/ganesha/src/Makefile.am new file mode 100644 index 00000000000..d42b68f8440 --- /dev/null +++ b/xlators/features/ganesha/src/Makefile.am @@ -0,0 +1,18 @@ +xlator_LTLIBRARIES = ganesha.la + +xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/features + +noinst_HEADERS = ganesha.h ganesha-mem-types.h + +ganesha_la_LDFLAGS = -module -avoid-version + +ganesha_la_SOURCES = ganesha.c + +AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \ +        -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -D$(GF_HOST_OS)\ +        -DGANESHA_DIR=\"$(sysconfdir)/ganesha\" \ +        -DGYSNCD_PREFIX=\"$(libexecdir)/glusterfs\" + +AM_CFLAGS = -Wall $(GF_CFLAGS) + +CLEANFILES = diff --git a/xlators/features/ganesha/src/ganesha-mem-types.h b/xlators/features/ganesha/src/ganesha-mem-types.h new file mode 100644 index 00000000000..c4976c01afc --- /dev/null +++ b/xlators/features/ganesha/src/ganesha-mem-types.h @@ -0,0 +1,21 @@ +/* +   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> +   This file is part of GlusterFS. + +   This file is licensed to you under your choice of the GNU Lesser +   General Public License, version 3 or any later version (LGPLv3 or +   later), or the GNU General Public License, version 2 (GPLv2), in all +   cases as published by the Free Software Foundation. +*/ +#ifndef __GANESHA_MEM_TYPES_H__ +#define __GANESHA_MEM_TYPES_H__ + + +#include "mem-types.h" + +enum gf_ganesha_mem_types_ { +     gf_ganesha_mt_priv_t = gf_common_mt_end + 1, +     gf_ganesha_mt_end +}; + +#endif diff --git a/xlators/features/ganesha/src/ganesha.c b/xlators/features/ganesha/src/ganesha.c new file mode 100644 index 00000000000..f034fc00d46 --- /dev/null +++ b/xlators/features/ganesha/src/ganesha.c @@ -0,0 +1,85 @@ +/* +   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> +   This file is part of GlusterFS. + +   This file is licensed to you under your choice of the GNU Lesser +   General Public License, version 3 or any later version (LGPLv3 or +   later), or the GNU General Public License, version 2 (GPLv2), in all +   cases as published by the Free Software Foundation. +*/ + + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "ganesha.h" +#include "ganesha-mem-types.h" + + + +int32_t +init (xlator_t *this) +{ +        int        ret         = -1; +        ganesha_priv_t   *priv = NULL; + +        if (!this->children || this->children->next) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Need subvolume == 1"); +                goto err; +        } + +        if (!this->parents) { +                gf_log (this->name, GF_LOG_WARNING, +                        "Dangling volume. Check volfile"); +                goto err; +        } + +        priv = GF_CALLOC (1, sizeof (*priv), gf_ganesha_mt_priv_t); +        if (!priv) +                goto err; + +        this->private = priv; +        ret = 0; + +err: +        return ret; +} + + +void +fini (xlator_t *this) +{ +        ganesha_priv_t *priv = this->private; + +        this->private = NULL; +        if (priv) +                GF_FREE (priv); + +        return; +} + +struct xlator_fops fops = { +}; + +struct xlator_cbks cbks = { +}; + +struct volume_options options[] = { +        { +         .key = {"features.ganesha"}, +         .default_value = "disable", +         .type =  GF_OPTION_TYPE_BOOL, +         .description = "enable translator" + +        }, +        { .key  = {"ganesha.enable"}, +          .default_value = "off", +          .type =  GF_OPTION_TYPE_BOOL, +          .description = "export volume via NFS-Ganesha" +        }, +        { .key  = {NULL} +        }, +}; diff --git a/xlators/features/ganesha/src/ganesha.h b/xlators/features/ganesha/src/ganesha.h new file mode 100644 index 00000000000..f30723da46d --- /dev/null +++ b/xlators/features/ganesha/src/ganesha.h @@ -0,0 +1,23 @@ +/* +   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> +   This file is part of GlusterFS. + +   This file is licensed to you under your choice of the GNU Lesser +   General Public License, version 3 or any later version (LGPLv3 or +   later), or the GNU General Public License, version 2 (GPLv2), in all +   cases as published by the Free Software Foundation. +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "xlator.h" +#include "ganesha-mem-types.h" + +typedef struct { +        char *host_name; +} ganesha_priv_t; + + diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index a3217c35574..f95fc02d4fd 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -5,7 +5,7 @@ glusterd_la_LDFLAGS = -module -avoid-version  glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c \  	glusterd-op-sm.c glusterd-utils.c glusterd-rpc-ops.c \  	glusterd-store.c glusterd-handshake.c glusterd-pmap.c \ -	glusterd-volgen.c glusterd-rebalance.c glusterd-quota.c \ +	glusterd-volgen.c glusterd-rebalance.c glusterd-ganesha.c glusterd-quota.c \  	glusterd-geo-rep.c glusterd-replace-brick.c glusterd-log-ops.c \  	glusterd-volume-ops.c glusterd-brick-ops.c glusterd-mountbroker.c \  	glusterd-syncop.c glusterd-hooks.c glusterd-volume-set.c \ @@ -44,8 +44,11 @@ AM_CPPFLAGS = $(GF_CPPFLAGS) -I$(top_srcdir)/libglusterfs/src \  	-I$(CONTRIBDIR)/userspace-rcu \  	-DSBIN_DIR=\"$(sbindir)\" -DDATADIR=\"$(localstatedir)\" \  	-DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\" \ +	-DCONFDIR=\"$(sysconfdir)/ganesha\" \ +	-DGANESHA_PREFIX=\"$(libexecdir)/ganesha\" \  	-DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(XML_CPPFLAGS) +  AM_CFLAGS = -Wall $(GF_CFLAGS) $(URCU_CFLAGS) $(URCU_CDS_CFLAGS)  AM_LDFLAGS = -L$(xlatordir) $(URCU_LIBS) $(URCU_CDS_LIBS) diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c new file mode 100644 index 00000000000..267e4b995cd --- /dev/null +++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c @@ -0,0 +1,365 @@ +/* +   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com> +   This file is part of GlusterFS. + +   This file is licensed to you under your choice of the GNU Lesser +   General Public License, version 3 or any later version (LGPLv3 or +   later), or the GNU General Public License, version 2 (GPLv2), in all +   cases as published by the Free Software Foundation. +*/ + + + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "common-utils.h" +#include "glusterd.h" +#include "glusterd-op-sm.h" +#include "glusterd-store.h" +#include "glusterd-utils.h" +#include "glusterd-nfs-svc.h" +#define MAXBUF 1024 +#define DELIM "=\"" + +/* Following 2 functions parses GANESHA_HA_CONF + * The sample file looks like below, + * HA_NAME="ganesha-ha-360" + * HA_VOL_NAME="ha-state" + * HA_VOL_MNT="/mount-point" + * HA_VOL_SERVER="server1" + * HA_CLUSTER_NODES="server1,server2" + * VIP_rhs_1="10.x.x.x" + * VIP_rhs_2="10.x.x.x." */ + +gf_boolean_t +is_ganesha_host (void) +{ +        char    *host_from_file          = NULL; +        FILE    *fp; +        char    line[MAXBUF]; +        gf_boolean_t    ret              = _gf_false; +        int     i                        = 1; +        xlator_t        *this            = NULL; + +        this = THIS; + +        fp = fopen (GANESHA_HA_CONF, "r"); + +        if (fp == NULL) { +                gf_log (this->name, GF_LOG_INFO, "couldn't open the file %s", +                        GANESHA_HA_CONF); +                return _gf_false; +        } + +         while (fgets (line, sizeof(line), fp) != NULL) { +                /* Read GANESHA_HA_CONFIG till we find the HA VOL server */ +                host_from_file = strstr ((char *)line, "HA_VOL_SERVER"); +                if (host_from_file != NULL) { +                        host_from_file = strstr (host_from_file, DELIM); +                        host_from_file = host_from_file + strlen(DELIM); +                        i = strlen(host_from_file); +                        host_from_file[i - 2] = '\0'; +                        break; +                } +        } + +        ret = gf_is_local_addr (host_from_file); +        if (ret) { +                gf_log (this->name, GF_LOG_INFO, "ganesha host found " +                        "Hostname is %s", host_from_file); +        } + +        fclose (fp); +        return ret; +} + +/* Check if the localhost is listed as one of nfs-ganesha nodes */ +gf_boolean_t +check_host_list (void) +{ + +        char    *host_from_file          = NULL; +        glusterd_conf_t     *priv        = NULL; +        char    *hostname                = NULL; +        FILE    *fp; +        char    line[MAXBUF]; +        int     ret                      = _gf_false; +        int     i                        = 1; +        xlator_t        *this            = NULL; + +        this = THIS; +        priv =  THIS->private; +        GF_ASSERT (priv); + +        fp = fopen (GANESHA_HA_CONF, "r"); + +        if (fp == NULL) { +                gf_log (this->name, GF_LOG_INFO, "couldn't open the file %s", +                        GANESHA_HA_CONF); +                return 0; +        } + +       while (fgets (line, sizeof(line), fp) != NULL) { +        /* Read GANESHA_HA_CONFIG till we find the list of HA_CLUSTER_NODES */ +                hostname = strstr ((char *)line, "HA_CLUSTER_NODES"); +                if (hostname != NULL) { +                        hostname = strstr (hostname, DELIM); +                        hostname = hostname + strlen(DELIM); +                        i = strlen (hostname); +                        hostname[i - 2] = '\0'; +                        break; +                } +        } + +        /* Hostname is a comma separated list now */ +        hostname = strtok (hostname, ","); +        while (hostname != NULL) { +                ret = gf_is_local_addr (hostname); +                if (ret) { +                        gf_log (this->name, GF_LOG_INFO, "ganesha host found " +                                "Hostname is %s", hostname); +                        break; +                } +                hostname = strtok (NULL, ","); +        } + +        fclose (fp); +        return ret; + +} + +int +create_export_config (char *volname, char **op_errstr) +{ +        runner_t                runner                     = {0,}; +        int                     ret                        = -1; + +        GF_ASSERT(volname); +        runinit (&runner); +        runner_add_args (&runner, "sh", +                        GANESHA_PREFIX"/create-export-ganesha.sh", +                        CONFDIR, volname, NULL); +        ret = runner_run(&runner); + +        if (ret) +                gf_asprintf (op_errstr, "Failed to create" +                            " NFS-Ganesha export config file."); + +        return ret; +} + +int +ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) +{ +        runner_t                 runner = {0,}; +        int                      ret = -1; +        char                     str[1024]; +        glusterd_volinfo_t      *volinfo = NULL; +        char                    *volname = NULL; +        xlator_t                *this    = NULL; +        int                     i = 1; + +        runinit (&runner); +        this =  THIS; + +        GF_ASSERT (value); +        GF_ASSERT (dict); + +        ret = dict_get_str (dict, "volname", &volname); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Unable to get volume name"); +                goto out; +        } + +        ret = glusterd_volinfo_find (volname, &volinfo); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, +                        FMTSTR_CHECK_VOL_EXISTS, volname); +                goto out; +        } + +        /* Create the export file only when ganesha.enable "on" is executed */ +         if (strcmp (value, "on") == 0) { +                ret  =  create_export_config (volname, op_errstr); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, "Failed to create" +                                "export file for NFS-Ganesha\n"); +                        goto out; +                } +        } + +        if (check_host_list()) { +                runner_add_args (&runner, "sh", GANESHA_PREFIX"/dbus-send.sh", +                         CONFDIR, value, volname, NULL); +                ret = runner_run (&runner); +                if (ret) +                        gf_asprintf(op_errstr, "Dynamic export" +                                    " addition/deletion failed." +                                    "Please see log file for details"); +        } +out: +        return ret; +} + +int +tear_down_cluster(void) +{ +        int     ret     =       0; +        runner_t runner =       {0,}; + +        if (is_ganesha_host()) { +                runinit (&runner); +                runner_add_args (&runner, "sh", CONFDIR, +                                GANESHA_PREFIX"/ganesha-ha.sh", "teardown", +                                CONFDIR, NULL); +                ret = runner_run(&runner); +        } +        return ret; +} + + +int +setup_cluster(void) +{ +        int ret         = 0; +        runner_t runner = {0,}; + +        if (is_ganesha_host()) { +                runinit (&runner); +                runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", +                                 "setup", CONFDIR,  NULL); +                ret =  runner_run (&runner); +        } +        return ret; +} + + +int +stop_ganesha (char **op_errstr) +{ +        runner_t                runner                     = {0,}; +        int                     ret                        = 1; + +        ret = tear_down_cluster(); +        if (ret == -1) { +                gf_asprintf (op_errstr, "Cleanup of NFS-Ganesha" +                             "HA config failed."); +                goto out; +        } + +        if (check_host_list ()) { +                runinit (&runner); +                runner_add_args (&runner, "service nfs-ganesha", "stop", NULL); +                ret =  runner_run (&runner); +        } +out: +        return ret; +} + +int +start_ganesha (char **op_errstr) +{ + +        runner_t                runner                     = {0,}; +        int                     ret                        = -1; +        char                    key[1024]                  = {0,}; +        char                    *hostname                  = NULL; +        dict_t *vol_opts                                   = NULL; +        glusterd_volinfo_t *volinfo                        = NULL; +        int count                                          = 0; +        char *volname                                      = NULL; +        glusterd_conf_t *priv                              = NULL; + +        priv =  THIS->private; +        GF_ASSERT (priv); + +        cds_list_for_each_entry (volinfo, &priv->volumes, vol_list) { +                vol_opts = volinfo->dict; +                /* Gluster-nfs has to be disabled across the trusted pool */ +                /* before attempting to start nfs-ganesha */ +                ret = dict_set_str (vol_opts, "nfs.disable", "on"); +                if (ret) +                        goto out; +        } + +        ret = priv->nfs_svc.stop (&(priv->nfs_svc), SIGKILL); +        if (ret) { +                ret = -1; +                gf_asprintf (op_errstr, "Gluster-NFS service could" +                             "not be stopped, exiting."); +                goto out; +        } + +        if (check_host_list()) { +                runinit(&runner); +                runner_add_args (&runner, "service", +                                 "nfs-ganesha", "start", NULL); + +                ret =  runner_run (&runner); +                if (ret) { +                        gf_asprintf (op_errstr, "NFS-Ganesha failed to start." +                        "Please see log file for details"); +                        goto out; +                } + +                ret = setup_cluster(); +                if (ret == -1) { +                        gf_asprintf (op_errstr, "Failed to set up HA " +                                     "config for NFS-Ganesha." +                                     "Please check the log file for details"); +                        goto out; +                } +        } + +out: +        return ret; +} + +int +glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, +                            char *key, char *value) +{ + +        int32_t                 ret          = -1; +        char                   *volname      = NULL; +        xlator_t               *this         = NULL; +        static int             export_id     = 1; +        glusterd_volinfo_t     *volinfo      = NULL; +        char *option                         = NULL; + +        GF_ASSERT (dict); +        GF_ASSERT (op_errstr); +        GF_ASSERT (key); +        GF_ASSERT (value); + +        /* TODO: enable only if global option is set */ +        /* BUG ID : 1200265 */ + +        if (strcmp (key, "ganesha.enable") == 0) { +                ret =  ganesha_manage_export(dict, value, op_errstr); +                if (ret < 0) +                        goto out; +        } + +        if (strcmp (key, "features.ganesha") == 0) { +                if (strcmp (value, "enable") == 0) { +                        ret = start_ganesha(op_errstr); +                        if (ret < 0) +                                goto out; +                } + +        else if (strcmp (value, "disable") == 0) { +                ret = stop_ganesha (op_errstr); +                if (ret < 0) +                        goto out; +                } +        } + +out: +        return ret; +} + diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index f20490423f6..c140e680261 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -3318,6 +3318,25 @@ client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,                  }          } +        ret = dict_get_str_boolean (set_dict, "ganesha.enable", _gf_false); + +        if (ret == -1) { +                gf_log (this->name, GF_LOG_WARNING, "setting ganesha.enable" +                        "option failed."); +                goto out; +        } + +        if (ret) { +                xl = volgen_graph_add (graph, "features/ganesha", volname); + +                if (!xl) { +                        gf_log (this->name, GF_LOG_ERROR, "failed to add" +                               "add features/ganesha to graph"); +                        ret = -1; +                        goto out; +                } +        } +          /* add debug translators depending on the options */          ret = check_and_add_debug_xl (graph, set_dict, volname,                                        "client"); @@ -3535,35 +3554,8 @@ nfs_option_handler (volgen_graph_t *graph,                          return -1;          } -          if (! strcmp (vme->option, "!nfs-ganesha.enable")) { -                ret = gf_asprintf (&aa, "nfs-ganesha.%s.enable", -                                        volinfo->volname); - -                if (ret != -1) { -                        ret = xlator_set_option (xl, aa, vme->value); -                        GF_FREE (aa); -                } - -                if (ret) -                        return -1; -        } - -         if (! strcmp (vme->option, "!nfs-ganesha.host")) { -                ret = gf_asprintf (&aa, "nfs-ganesha.%s.host", -                                        volinfo->volname); - -                if (ret != -1) { -                        ret = xlator_set_option (xl, aa, vme->value); -                        GF_FREE (aa); -                } - -                if (ret) -                        return -1; -        } - - -        if ( (strcmp (vme->voltype, "nfs/server") == 0) && +      if ((strcmp (vme->voltype, "nfs/server") == 0) &&               (vme->option && vme->option[0]!='!') ) {                 ret = xlator_set_option (xl, vme->option, vme->value);                  if (ret) diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index 98019f81d4c..7aeed450932 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -52,7 +52,7 @@  #define GLUSTERD_CREATE_HOOK_SCRIPT     "/hooks/1/gsync-create/post/" \                                          "S56glusterd-geo-rep-create-post.sh" - +#define GANESHA_HA_CONF  CONFDIR "/ganesha-ha.conf"  #define GLUSTERD_SNAPS_MAX_HARD_LIMIT 256  #define GLUSTERD_SNAPS_DEF_SOFT_LIMIT_PERCENT 90  #define GLUSTERD_SNAPS_MAX_SOFT_LIMIT_PERCENT 100 diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index 3940533ff3e..4de81769fff 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -1832,17 +1832,6 @@ struct volume_options options[] = {            .description = "This option is used to start or stop the NFS server "                           "for individual volumes."          }, -        { .key  = {"nfs-ganesha.*.host"}, -          .type = GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, -          .default_value = "none", -          .description = "Set nfs-ganesha host IP" -        }, -        { .key  = {"nfs-ganesha.*.enable"}, -          .type = GF_OPTION_TYPE_BOOL, -          .default_value = "off", -          .description = "This option, if set to 'on', enables exports via nfs-ganesha " -        }, -          { .key  = {"nfs.nlm"},            .type = GF_OPTION_TYPE_BOOL,            .default_value = "on",  | 
