diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src')
-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 |
4 files changed, 390 insertions, 30 deletions
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 |