diff options
-rw-r--r-- | cli/src/Makefile.am | 2 | ||||
-rw-r--r-- | cli/src/cli-cmd-global.c | 131 | ||||
-rw-r--r-- | cli/src/cli-cmd-misc.c | 3 | ||||
-rw-r--r-- | cli/src/cli-cmd-parser.c | 12 | ||||
-rw-r--r-- | cli/src/cli-cmd-volume.c | 52 | ||||
-rw-r--r-- | cli/src/cli-cmd.c | 6 | ||||
-rw-r--r-- | cli/src/cli-cmd.h | 2 | ||||
-rw-r--r-- | xlators/features/ganesha/src/ganesha.c | 6 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-ganesha.c | 248 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-op-sm.c | 23 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-store.h | 1 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-ops.c | 21 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-volume-set.c | 9 | ||||
-rw-r--r-- | xlators/mgmt/glusterd/src/glusterd.h | 4 |
14 files changed, 385 insertions, 135 deletions
diff --git a/cli/src/Makefile.am b/cli/src/Makefile.am index db1d089b8f9..92cf35a581c 100644 --- a/cli/src/Makefile.am +++ b/cli/src/Makefile.am @@ -1,6 +1,6 @@ sbin_PROGRAMS = gluster -gluster_SOURCES = cli.c registry.c input.c cli-cmd.c cli-rl.c \ +gluster_SOURCES = cli.c registry.c input.c cli-cmd.c cli-rl.c cli-cmd-global.c \ cli-cmd-volume.c cli-cmd-peer.c cli-rpc-ops.c cli-cmd-parser.c\ cli-cmd-system.c cli-cmd-misc.c cli-xml-output.c cli-quotad-client.c cli-cmd-snapshot.c diff --git a/cli/src/cli-cmd-global.c b/cli/src/cli-cmd-global.c new file mode 100644 index 00000000000..9b71821b00c --- /dev/null +++ b/cli/src/cli-cmd-global.c @@ -0,0 +1,131 @@ +/* + 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. +*/ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <pthread.h> + +#include <sys/socket.h> +#include <netdb.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <netinet/in.h> + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include "cli.h" +#include "cli-cmd.h" +#include "cli-mem-types.h" +#include "cli1-xdr.h" +#include "run.h" +#include "syscall.h" +#include "common-utils.h" + +extern rpc_clnt_prog_t *cli_rpc_prog; + +int +cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, + const char **words, int wordcount); +int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word, + const char **words, int wordcount); + + +struct cli_cmd global_cmds[] = { + { "global help", + cli_cmd_global_help_cbk, + "list global commands", + }, + { "nfs-ganesha {enable| disable} ", + cli_cmd_ganesha_cbk, + "Enable/disable NFS-Ganesha support", + }, + {NULL, NULL, NULL} +}; + +int +cli_cmd_global_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, + const char **words, int wordcount) +{ + struct cli_cmd *cmd = NULL; + + for (cmd = global_cmds; cmd->pattern; cmd++) + if (_gf_false == cmd->disable) + cli_out ("%s - %s", cmd->pattern, cmd->desc); + + return 0; +} + +int +cli_cmd_global_register (struct cli_state *state) +{ + int ret = 0; + struct cli_cmd *cmd = NULL; + for (cmd = global_cmds; cmd->pattern; cmd++) { + ret = cli_cmd_register (&state->tree, cmd); + if (ret) + goto out; + } +out: + return ret; + +} + +int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word, + const char **words, int wordcount) + +{ + int sent = 0; + int parse_error = 0; + int ret = -1; + rpc_clnt_procedure_t *proc = NULL; + call_frame_t *frame = NULL; + dict_t *options = NULL; + cli_local_t *local = NULL; + char *op_errstr = NULL; + + proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GANESHA]; + + frame = create_frame (THIS, THIS->ctx->pool); + if (!frame) + goto out; + + ret = cli_cmd_ganesha_parse (state, words, wordcount, + &options, &op_errstr); + if (ret) { + if (op_errstr) { + cli_err ("%s", op_errstr); + GF_FREE (op_errstr); + } else + cli_usage_out (word->pattern); + parse_error = 1; + goto out; + } + + CLI_LOCAL_INIT (local, words, frame, options); + + if (proc->fn) { + ret = proc->fn (frame, THIS, options); + } + +out: + if (ret) { + cli_cmd_sent_status_get (&sent); + if ((sent == 0) && (parse_error == 0)) + cli_out ("Setting global option failed"); + } + + CLI_STACK_DESTROY (frame); + return ret; +} + diff --git a/cli/src/cli-cmd-misc.c b/cli/src/cli-cmd-misc.c index 566d7c978d9..ccfeb6d87f1 100644 --- a/cli/src/cli-cmd-misc.c +++ b/cli/src/cli-cmd-misc.c @@ -33,6 +33,7 @@ extern struct cli_cmd cli_log_cmds[]; extern struct cli_cmd cli_system_cmds[]; extern struct cli_cmd cli_bd_cmds[]; extern struct cli_cmd snapshot_cmds[]; +extern struct cli_cmd global_cmds[]; struct cli_cmd cli_misc_cmds[]; int @@ -48,7 +49,7 @@ cli_cmd_display_help (struct cli_state *state, struct cli_cmd_word *in_word, { struct cli_cmd *cmd[] = {volume_cmds, cli_probe_cmds, cli_misc_cmds, snapshot_cmds, - NULL}; + global_cmds, NULL}; struct cli_cmd *cmd_ind = NULL; int i = 0; diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index bb0af2fc383..b30306b2584 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -819,7 +819,7 @@ out: } /* Parsing global option for NFS-Ganesha config - * gluster features.ganesha enable/disable */ + * gluster nfs-ganesha enable/disable */ int32_t cli_cmd_ganesha_parse (struct cli_state *state, @@ -833,7 +833,7 @@ cli_cmd_ganesha_parse (struct cli_state *state, char *value = NULL; int i = 0; char *w = NULL; - char *opwords[] = { "enable", "disable" }; + char *opwords[] = { "enable", "disable", NULL }; const char *question = NULL; gf_answer_t answer = GF_ANSWER_NO; @@ -853,7 +853,7 @@ cli_cmd_ganesha_parse (struct cli_state *state, value = (char *) words[1]; if (!key || !value) { - cli_out ("Usage : features.ganesha <enable/disable>"); + cli_out ("Usage : nfs-ganesha <enable/disable>"); ret = -1; goto out; } @@ -862,7 +862,7 @@ cli_cmd_ganesha_parse (struct cli_state *state, if (ret == -1) goto out; - if (strcmp (key, "features.ganesha")) { + if (strcmp (key, "nfs-ganesha")) { gf_asprintf (op_errstr, "Global option: error: ' %s '" "is not a valid global option.", key); ret = -1; @@ -872,13 +872,13 @@ cli_cmd_ganesha_parse (struct cli_state *state, w = str_getunamb (value, opwords); if (!w) { cli_out ("Invalid global option \n" - "Usage : features.ganesha <enable/disable>"); + "Usage : nfs-ganesha <enable/disable>"); ret = -1; goto out; } question = "Enabling NFS-Ganesha requires Gluster-NFS to be" - "disabled across the trusted pool. Do you " + " disabled across the trusted pool. Do you " "still want to continue?"; if (strcmp (value, "enable") == 0) { diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c index 30df22ff199..b5d5920bebc 100644 --- a/cli/src/cli-cmd-volume.c +++ b/cli/src/cli-cmd-volume.c @@ -1372,54 +1372,6 @@ out: return ret; } -int cli_cmd_ganesha_cbk (struct cli_state *state, struct cli_cmd_word *word, - const char **words, int wordcount) - -{ - int sent = 0; - int parse_error = 0; - int ret = -1; - rpc_clnt_procedure_t *proc = NULL; - call_frame_t *frame = NULL; - dict_t *options = NULL; - cli_local_t *local = NULL; - char *op_errstr = NULL; - - proc = &cli_rpc_prog->proctable[GLUSTER_CLI_GANESHA]; - - frame = create_frame (THIS, THIS->ctx->pool); - if (!frame) - goto out; - - ret = cli_cmd_ganesha_parse (state, words, wordcount, - &options, &op_errstr); - if (ret) { - if (op_errstr) { - cli_err ("%s", op_errstr); - GF_FREE (op_errstr); - } else - cli_usage_out (word->pattern); - parse_error = 1; - goto out; - } - - CLI_LOCAL_INIT (local, words, frame, options); - - if (proc->fn) { - ret = proc->fn (frame, THIS, options); - } - -out: - if (ret) { - cli_cmd_sent_status_get (&sent); - if ((sent == 0) && (parse_error == 0)) - cli_out ("Setting global option failed"); - } - - CLI_STACK_DESTROY (frame); - return ret; -} - int cli_cmd_bitrot_cbk (struct cli_state *state, struct cli_cmd_word *word, const char **words, int wordcount) @@ -2625,10 +2577,6 @@ struct cli_cmd volume_cmds[] = { cli_cmd_quota_cbk, "quota translator specific operations"}, - { "features.ganesha { enable| disable } ", - cli_cmd_ganesha_cbk, - "global ganesha operations" }, - { "volume top <VOLNAME> {open|read|write|opendir|readdir|clear} [nfs|brick <brick>] [list-cnt <value>] |\n" "volume top <VOLNAME> {read-perf|write-perf} [bs <size> count <count>] [brick <brick>] [list-cnt <value>]", cli_cmd_volume_top_cbk, diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c index cc9072246d3..5ea1edc9cac 100644 --- a/cli/src/cli-cmd.c +++ b/cli/src/cli-cmd.c @@ -234,6 +234,9 @@ cli_cmds_register (struct cli_state *state) ret = cli_cmd_snapshot_register (state); if (ret) goto out; + ret = cli_cmd_global_register (state); + if (ret) + goto out; out: return ret; } @@ -371,7 +374,8 @@ cli_cmd_submit (struct rpc_clnt* rpc, void *req, call_frame_t *frame, unsigned timeout = 0; if ((GLUSTER_CLI_PROFILE_VOLUME == procnum) || - (GLUSTER_CLI_HEAL_VOLUME == procnum)) + (GLUSTER_CLI_HEAL_VOLUME == procnum) || + (GLUSTER_CLI_GANESHA == procnum)) timeout = CLI_TEN_MINUTES_TIMEOUT; else timeout = CLI_DEFAULT_CMD_TIMEOUT; diff --git a/cli/src/cli-cmd.h b/cli/src/cli-cmd.h index cf036928ddf..d39c8b38f7f 100644 --- a/cli/src/cli-cmd.h +++ b/cli/src/cli-cmd.h @@ -84,6 +84,8 @@ int cli_cmd_system_register (struct cli_state *state); int cli_cmd_snapshot_register (struct cli_state *state); +int cli_cmd_global_register (struct cli_state *state); + int cli_cmd_misc_register (struct cli_state *state); struct cli_cmd_word *cli_cmd_nextword (struct cli_cmd_word *word, diff --git a/xlators/features/ganesha/src/ganesha.c b/xlators/features/ganesha/src/ganesha.c index a3d392e3ecf..fe9f14864b1 100644 --- a/xlators/features/ganesha/src/ganesha.c +++ b/xlators/features/ganesha/src/ganesha.c @@ -84,13 +84,7 @@ 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, diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c index fe67be187f2..b4375aa26c2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c +++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c @@ -20,8 +20,13 @@ #include "glusterd-store.h" #include "glusterd-utils.h" #include "glusterd-nfs-svc.h" +#include "glusterd-volgen.h" #define MAXBUF 1024 #define DELIM "=\"" +#define SHARED_STORAGE_MNT "/var/run/gluster/shared_storage/nfs-ganesha" + +int start_ganesha (char **op_errstr); + typedef struct service_command { char *binary; @@ -91,12 +96,31 @@ manage_service (char *action) " not recognized.", action); return ret; } +/* Check if ganesha.enable is set to 'on', that checks if + * a particular volume is exported via NFS-Ganesha */ +gf_boolean_t +glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo) { + + char *value = NULL; + gf_boolean_t is_exported = _gf_false; + int ret = 0; + + ret = glusterd_volinfo_get (volinfo, "ganesha.enable", &value); + if ((ret == 0) && value) { + if (strcmp (value, "on") == 0) { + gf_log (THIS->name, GF_LOG_DEBUG, "ganesha.enable set" + " to %s", value); + is_exported = _gf_true; + } + } + return is_exported; +} + int glusterd_check_ganesha_cmd (char *key, char *value, char **errstr, dict_t *dict) { int ret = 0; - gf_boolean_t b = _gf_false; xlator_t *this = NULL; this = THIS; @@ -104,24 +128,17 @@ glusterd_check_ganesha_cmd (char *key, char *value, char **errstr, dict_t *dict) GF_ASSERT (key); GF_ASSERT (value); - if ((strcmp (key, "ganesha.enable") == 0) || - (strcmp (key, "features.ganesha") == 0)) { - ret = gf_string2boolean (value, &b); - if (ret < 0) { - gf_log (this->name, GF_LOG_ERROR, "Failed to parse bool" - "string"); - goto out; - } + if ((strcmp (key, "ganesha.enable") == 0)) { if ((strcmp (value, "on")) && (strcmp (value, "off"))) { - gf_log (this->name, GF_LOG_ERROR, "Invalid value" - "for volume set command. Use on/off only"); + gf_asprintf (errstr, "Invalid value" + " for volume set command. Use on/off only."); ret = -1; goto out; } ret = glusterd_handle_ganesha_op (dict, errstr, key, value); if (ret) { - gf_log (this->name, GF_LOG_ERROR, "Handling NFS-Ganesha op" - "failed."); + gf_log (this->name, GF_LOG_ERROR, "Handling NFS-Ganesha" + " op failed."); } } out: @@ -134,9 +151,9 @@ glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr) int ret = -1; char *volname = NULL; int exists = 0; - char *key = NULL; - char *value = NULL; - char str[100] = {0, } ; + gf_boolean_t value = _gf_false; + gf_boolean_t option = _gf_false; + char *str = NULL; int dict_count = 0; int flags = 0; char errstr[2048] = {0, } ; @@ -150,27 +167,46 @@ glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr) priv = this->private; GF_ASSERT (priv); - ret = dict_get_str (dict, "key", &key); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "invalid key"); + value = dict_get_str_boolean (dict, "value", _gf_false); + if (value == -1) { + gf_log (this->name, GF_LOG_ERROR, + "value not present."); goto out; } - - ret = dict_get_str (dict, "value", &value); - if (ret) { - gf_log (this->name, GF_LOG_ERROR, - "invalid key,value pair in 'global vol set'"); + /* This dict_get will fail if the user had never set the key before */ + /*Ignoring the ret value and proceeding */ + ret = dict_get_str (priv->opts, GLUSTERD_STORE_KEY_GANESHA_GLOBAL, &str); + if (ret == -1) { + gf_log (this->name, GF_LOG_WARNING, "Global dict not present."); + ret = 0; goto out; } + /* Validity of the value is already checked */ + ret = gf_string2boolean (str, &option); + /* Check if the feature is already enabled, fail in that case */ + if (value == option) { + gf_asprintf (op_errstr, "nfs-ganesha is already %sd.", str); + ret = -1; + goto out; + } + + if (value) { + ret = start_ganesha (op_errstr); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, + "Could not start NFS-Ganesha"); + + } + } + out: if (ret) { if (!(*op_errstr)) { *op_errstr = gf_strdup ("Error, Validation Failed"); gf_log (this->name, GF_LOG_DEBUG, - "Error, Cannot Validate option :%s %s", - key, value); + "Error, Cannot Validate option :%s", + GLUSTERD_STORE_KEY_GANESHA_GLOBAL); } else { gf_log (this->name, GF_LOG_DEBUG, "Error, Cannot Validate option"); @@ -194,7 +230,6 @@ glusterd_op_set_ganesha (dict_t *dict, char **errstr) int32_t dict_count = 0; dict_t *vol_opts = NULL; int count = 0; - char *dup = NULL; this = THIS; GF_ASSERT (this); @@ -218,12 +253,6 @@ glusterd_op_set_ganesha (dict_t *dict, char **errstr) goto out; } - dup = gf_strdup (value); - if (!dup) { - ret = -1; - goto out; - } - ret = glusterd_handle_ganesha_op (dict, errstr, key, value); if (ret) { gf_log (this->name, GF_LOG_ERROR, @@ -231,10 +260,12 @@ glusterd_op_set_ganesha (dict_t *dict, char **errstr) ret = -1; goto out; } - ret = dict_set_str(priv->opts, "features.ganesha", value); + ret = dict_set_dynstr_with_alloc (priv->opts, + GLUSTERD_STORE_KEY_GANESHA_GLOBAL, + value); if (ret) { gf_log (this->name, GF_LOG_WARNING, "Failed to set" - " features.ganesha in dict."); + " nfs-ganesha in dict."); goto out; } @@ -380,6 +411,7 @@ create_export_config (char *volname, char **op_errstr) return ret; } +/* Exports and unexports a particular volume via NFS-Ganesha */ int ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) { @@ -389,13 +421,18 @@ ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) glusterd_volinfo_t *volinfo = NULL; char *volname = NULL; xlator_t *this = NULL; + glusterd_conf_t *priv = NULL; + gf_boolean_t option = _gf_false; int i = 1; runinit (&runner); this = THIS; + GF_ASSERT (this); + priv = this->private; GF_ASSERT (value); GF_ASSERT (dict); + GF_ASSERT (priv); ret = dict_get_str (dict, "volname", &volname); if (ret) { @@ -403,6 +440,11 @@ ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) "Unable to get volume name"); goto out; } + ret = gf_string2boolean (value, &option); + if (ret == -1) { + gf_log (this->name, GF_LOG_ERROR, "invalid value."); + goto out; + } ret = glusterd_volinfo_find (volname, &volinfo); if (ret) { @@ -410,10 +452,42 @@ ganesha_manage_export (dict_t *dict, char *value, char **op_errstr) FMTSTR_CHECK_VOL_EXISTS, volname); goto out; } - /* Todo : check if global option is enabled, proceed only then */ + + ret = glusterd_check_ganesha_export (volinfo); + if (ret && option) { + gf_asprintf (op_errstr, "ganesha.enable " + "is already 'on'."); + ret = -1; + goto out; + + } else if (!option && !ret) { + gf_asprintf (op_errstr, "ganesha.enable " + "is already 'off'."); + ret = -1; + goto out; + } + + /* Check if global option is enabled, proceed only then */ + ret = dict_get_str_boolean (priv->opts, + GLUSTERD_STORE_KEY_GANESHA_GLOBAL, _gf_false); + if (ret == -1) { + gf_log (this->name, GF_LOG_DEBUG, "Failed to get " + "global option dict."); + gf_asprintf (op_errstr, "The option " + "nfs-ganesha should be " + "enabled before setting ganesha.enable."); + goto out; + } + if (!ret) { + gf_asprintf (op_errstr, "The option " + "nfs-ganesha should be " + "enabled before setting ganesha.enable."); + ret = -1; + goto out; + } /* Create the export file only when ganesha.enable "on" is executed */ - if (strcmp (value, "on") == 0) { + if (option) { ret = create_export_config (volname, op_errstr); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Failed to create" @@ -468,11 +542,16 @@ setup_cluster(void) } -int -stop_ganesha (char **op_errstr) +static int +teardown (char **op_errstr) { runner_t runner = {0,}; int ret = 1; + glusterd_volinfo_t *volinfo = NULL; + glusterd_conf_t *priv = NULL; + dict_t *vol_opts = NULL; + + priv = THIS->private; ret = tear_down_cluster(); if (ret == -1) { @@ -480,6 +559,37 @@ stop_ganesha (char **op_errstr) " HA config failed."); goto out; } + ret = stop_ganesha (op_errstr); + if (ret) { + gf_asprintf (op_errstr, "Could not stop NFS-Ganesha."); + goto out; + } + + runinit (&runner); + runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh", + "cleanup", CONFDIR, NULL); + ret = runner_run (&runner); + if (ret) + gf_log (THIS->name, GF_LOG_DEBUG, "Could not clean up" + " NFS-Ganesha related config"); + + cds_list_for_each_entry (volinfo, &priv->volumes, vol_list) { + vol_opts = volinfo->dict; + /* All the volumes exported via NFS-Ganesha will be + unexported, hence setting the appropriate key */ + ret = dict_set_str (vol_opts, "ganesha.enable", "off"); + if (ret) + gf_log (THIS->name, GF_LOG_WARNING, + "Could not set ganesha.enable to off"); + } +out: + return ret; +} + +int +stop_ganesha (char **op_errstr) { + + int ret = 0; if (check_host_list ()) { ret = manage_service ("stop"); @@ -487,8 +597,8 @@ stop_ganesha (char **op_errstr) gf_asprintf (op_errstr, "NFS-Ganesha service could not" "be stopped."); } -out: return ret; + } int @@ -525,19 +635,34 @@ start_ganesha (char **op_errstr) if (check_host_list()) { ret = manage_service ("start"); - if (ret) { + if (ret) gf_asprintf (op_errstr, "NFS-Ganesha failed to start." "Please see log file for details"); - goto out; - } + } +out: + return ret; +} + +static int +pre_setup (char **op_errstr) +{ + int ret = 0; + + ret = mkdir (SHARED_STORAGE_MNT, 0775); + + if ((-1 == ret) && (EEXIST != errno)) { + gf_log ("THIS->name", GF_LOG_ERROR, "mkdir() failed on path %s," + "errno: %s", SHARED_STORAGE_MNT, strerror (errno)); + goto out; + } + + if (check_host_list()) { ret = setup_cluster(); - if (ret == -1) { + 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: @@ -552,35 +677,38 @@ glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr, int32_t ret = -1; char *volname = NULL; xlator_t *this = NULL; + gf_boolean_t option = _gf_false; 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); + 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); + /* It is possible that the key might not be set */ + ret = gf_string2boolean (value, &option); + if (ret == -1) { + gf_asprintf (op_errstr, "Invalid value in key-value pair."); + goto out; + } + + if (strcmp (key, GLUSTERD_STORE_KEY_GANESHA_GLOBAL) == 0) { + if (option) { + ret = pre_setup (op_errstr); + if (ret < 0) + goto out; + } else { + ret = teardown (op_errstr); if (ret < 0) goto out; - } - - else if (strcmp (value, "disable") == 0) { - ret = stop_ganesha (op_errstr); - if (ret < 0) - goto out; } } diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index 42477ebf6cd..aac393078b5 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1658,6 +1658,8 @@ glusterd_op_reset_all_volume_options (xlator_t *this, dict_t *dict) gf_boolean_t all = _gf_false; char *next_version = NULL; gf_boolean_t quorum_action = _gf_false; + gf_boolean_t option = _gf_false; + char *op_errstr = NULL; conf = this->private; ret = dict_get_str (dict, "key", &key); @@ -1684,6 +1686,18 @@ glusterd_op_reset_all_volume_options (xlator_t *this, dict_t *dict) if (key_fixed) key = key_fixed; + option = dict_get_str_boolean (conf->opts, GLUSTERD_STORE_KEY_GANESHA_GLOBAL, + _gf_false); + if (option) { + ret = tear_down_cluster(); + if (ret == -1) + gf_log (THIS->name, GF_LOG_WARNING, + "Could not tear down NFS-Ganesha cluster"); + ret = stop_ganesha (&op_errstr); + if (ret) + gf_log (THIS->name, GF_LOG_WARNING, + "Could not stop NFS-Ganesha service"); + } ret = -1; dup_opt = dict_new (); @@ -1788,6 +1802,15 @@ glusterd_op_reset_volume (dict_t *dict, char **op_rspstr) if (glusterd_is_quorum_changed (volinfo->dict, key, NULL)) quorum_action = _gf_true; + ret = glusterd_check_ganesha_export (volinfo); + if (ret) { + ret = ganesha_manage_export (dict, "off", op_rspstr); + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, + "Could not reset ganesha.enable key"); + ret = 0; + } + } ret = glusterd_options_reset (volinfo, key, &is_force); if (ret == -1) { diff --git a/xlators/mgmt/glusterd/src/glusterd-store.h b/xlators/mgmt/glusterd/src/glusterd-store.h index 72fdd851d23..7dbd811803a 100644 --- a/xlators/mgmt/glusterd/src/glusterd-store.h +++ b/xlators/mgmt/glusterd/src/glusterd-store.h @@ -83,6 +83,7 @@ typedef enum glusterd_store_ver_ac_{ #define GLUSTERD_STORE_KEY_SNAP_MAX_SOFT_LIMIT "snap-max-soft-limit" #define GLUSTERD_STORE_KEY_SNAPD_PORT "snapd-port" #define GLUSTERD_STORE_KEY_SNAP_ACTIVATE "snap-activate-on-create" +#define GLUSTERD_STORE_KEY_GANESHA_GLOBAL "nfs-ganesha" #define GLUSTERD_STORE_KEY_BRICK_HOSTNAME "hostname" #define GLUSTERD_STORE_KEY_BRICK_PATH "path" diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c index de3045ffde3..3c3e6e01d8e 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c @@ -1506,6 +1506,15 @@ glusterd_op_stage_stop_volume (dict_t *dict, char **op_errstr) ret = -1; goto out; } + ret = glusterd_check_ganesha_export (volinfo); + if (ret) { + ret = ganesha_manage_export(dict, "off", op_errstr); + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, "Could not" + "unexport volume via NFS-Ganesha"); + ret = 0; + } + } if (glusterd_is_rb_ongoing (volinfo)) { snprintf (msg, sizeof (msg), "Replace brick is in progress on " @@ -2331,7 +2340,17 @@ glusterd_op_start_volume (dict_t *dict, char **op_errstr) if (ret) goto out; } - + /* Check if the volume is exported via NFS-Ganesha, if yes + * export it as part of starting the volume */ + ret = glusterd_check_ganesha_export (volinfo); + if (ret) { + ret = ganesha_manage_export (dict, "on", op_errstr); + if (ret) { + gf_log ("", GF_LOG_WARNING, "NFS-Ganesha couldn't" + "export the volume. %s", *op_errstr); + ret = 0; + } + } ret = glusterd_svcs_manager (volinfo); out: diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 2194c429657..17f34e6f86d 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -1756,15 +1756,10 @@ struct volopt_map_entry glusterd_volopt_map[] = { .op_version = GD_OP_VERSION_3_7_0, .flags = OPT_FLAG_CLIENT_OPT }, - { .key = "features.ganesha", - .voltype = "features/ganesha", - .option = "!ganesha", - .type = GLOBAL_NO_DOC, - .op_version = GD_OP_VERSION_3_7_0, - }, { .key = "ganesha.enable", .voltype = "features/ganesha", - .type = NO_DOC, + .value = "off", + .option = "ganesha.enable", .op_version = GD_OP_VERSION_3_7_0, }, { .key = "features.shard", diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h index e70276d0506..f2a9be15c9f 100644 --- a/xlators/mgmt/glusterd/src/glusterd.h +++ b/xlators/mgmt/glusterd/src/glusterd.h @@ -998,6 +998,10 @@ int glusterd_check_ganesha_cmd (char *key, char *value, char **errstr, dict_t *dict); int glusterd_op_stage_set_ganesha (dict_t *dict, char **op_errstr); int glusterd_op_set_ganesha (dict_t *dict, char **errstr); +int ganesha_manage_export (dict_t *dict, char *value, char **op_errstr); +gf_boolean_t glusterd_check_ganesha_export (glusterd_volinfo_t *volinfo); +int stop_ganesha (char **op_errstr); +int tear_down_cluster (void); int glusterd_op_add_brick (dict_t *dict, char **op_errstr); int glusterd_op_remove_brick (dict_t *dict, char **op_errstr); int glusterd_op_stage_add_brick (dict_t *dict, char **op_errstr, |