summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd')
-rw-r--r--xlators/mgmt/glusterd/src/Makefile.am5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-ganesha.c365
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volgen.c48
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h2
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