diff options
author | Meghana Madhusudhan <mmadhusu@redhat.com> | 2015-03-18 11:33:50 +0530 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2015-03-18 01:53:22 -0700 |
commit | 368dfd695928e8fc40988b8f2de86c3b469172d2 (patch) | |
tree | 47beddb1ad9ad51c79e54d77e55a262d5998b81f | |
parent | 260a6943849f99227248a8fc852a8c8fc3d1e289 (diff) |
NFS-Ganesha: Volume set option for managing NFS-Ganesha exports.
A dummy translator has been introduced as a place
holder for functions related to managing NFS-Ganesha
exports. A volume set option is introduced to
manage volume level exports.
gluster vol set <volname> ganesha.enable ON/OFF
1. gluster volume set <volname> ganesha.enable ON
It creates the export config file with a unique export ID.
Sends a DBus signal to export this volume dynamically.
2. gluster vol set <volname> ganesha.enable OFF
Unexports the specific volume. Deletes the specfic
config file related to the volume.
This change also removes the handling of the older
keys "nfs-ganesha.enable" and "nfs-ganesha.host"
Change-Id: I8d4a0b542326a6a0c8e4711600b106274d666587
BUG: 1188184
Signed-off-by: Meghana Madhusudhan <mmadhusu@redhat.com>
Reviewed-on: http://review.gluster.org/9585
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
-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", |