summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeghana Madhusudhan <mmadhusu@redhat.com>2015-02-02 16:23:22 +0530
committerKaleb KEITHLEY <kkeithle@redhat.com>2015-03-18 04:33:13 -0700
commit38ccaaf9d1a93c4fc6d733ee3bd5c73e5457bdab (patch)
tree8856e8a6a869d6a0f1444c74e6bd05b08d950940
parent8a9c909702f4f6836bd1d0c791a7b1ae79d4ba15 (diff)
CLI : GLobal option for NFS-Ganesha
A new global CLI option has been introduced for NFS-Ganesha. gluster features.ganesha enable/disable. This option is persistent and shall be inherited by new volumes created after this option is set. gluster features.ganesha enable It carries out the following functions: 1. Disables gluster-nfs across the cluster 2. Starts NFS-Ganesha server on a subset of nodes and exports '/'. 3. Creates the HA cluster for NFS-Ganesha. 4. Writes the option into the global config file. gluster features.ganesha disable 1. Stops NFS-Ganesha server. 2. Tears down the HA cluster for NFS-Ganesha With this change the older volume set options with keys "nfs-ganesha.host" and "nfs-ganesha.enable" will no longer be supported. This commit has only has the CLI related changes. Another patch will be submitted to support this feature entirely. Change-Id: Ie4b66a16c23b33b795738654b9a68f8e2c34efe3 BUG: 1188184 Signed-off-by: Meghana Madhusudhan <mmadhusu@redhat.com> Reviewed-on: http://review.gluster.org/9538 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com>
-rw-r--r--cli/src/cli-cmd-parser.c93
-rw-r--r--cli/src/cli-cmd-volume.c54
-rw-r--r--cli/src/cli-rpc-ops.c80
-rw-r--r--cli/src/cli.h3
-rw-r--r--rpc/rpc-lib/src/protocol-common.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-ganesha.c159
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handler.c77
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c21
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-rpc-ops.c1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c22
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h9
11 files changed, 502 insertions, 18 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index aa512738784..c7fdafb32b6 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -754,6 +754,99 @@ out:
return ret;
}
+/* Parsing global option for NFS-Ganesha config
+ * gluster features.ganesha enable/disable */
+
+int32_t
+cli_cmd_ganesha_parse (struct cli_state *state,
+ const char **words, int wordcount,
+ dict_t **options, char **op_errstr)
+{
+ dict_t *dict = NULL;
+ int ret = -1;
+ int flags = 0;
+ char *key = NULL;
+ char *value = NULL;
+ int i = 0;
+ char *w = NULL;
+ char *opwords[] = { "enable", "disable" };
+ const char *question = NULL;
+ gf_answer_t answer = GF_ANSWER_NO;
+
+
+ GF_ASSERT (words);
+ GF_ASSERT (options);
+
+ dict = dict_new ();
+
+ if (!dict)
+ goto out;
+
+ if (wordcount != 2)
+ goto out;
+
+ key = (char *) words[0];
+ value = (char *) words[1];
+
+ if (!key || !value) {
+ cli_out ("Usage : features.ganesha <enable/disable>");
+ ret = -1;
+ goto out;
+ }
+
+ ret = gf_strip_whitespace (value, strlen (value));
+ if (ret == -1)
+ goto out;
+
+ if (strcmp (key, "features.ganesha")) {
+ gf_asprintf (op_errstr, "Global option: error: ' %s '"
+ "is not a valid global option.", key);
+ ret = -1;
+ goto out;
+ }
+
+ w = str_getunamb (value, opwords);
+ if (!w) {
+ cli_out ("Invalid global option \n"
+ "Usage : features.ganesha <enable/disable>");
+ ret = -1;
+ goto out;
+ }
+
+ question = "Enabling NFS-Ganesha requires Gluster-NFS to be"
+ "disabled across the trusted pool. Do you "
+ "still want to continue?";
+
+ if (strcmp (value, "enable") == 0) {
+ answer = cli_cmd_get_confirmation (state, question);
+ if (GF_ANSWER_NO == answer) {
+ gf_log ("cli", GF_LOG_ERROR, "Global operation "
+ "cancelled, exiting");
+ ret = -1;
+ goto out;
+ }
+ }
+
+ ret = dict_set_str (dict, "key", key);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "dict set on key failed");
+ goto out;
+ }
+
+ ret = dict_set_str (dict, "value", value);
+ if (ret) {
+ gf_log (THIS->name, GF_LOG_ERROR, "dict set on value failed");
+ goto out;
+ }
+
+ *options = dict;
+out:
+ if (ret)
+ dict_unref (dict);
+
+ return ret;
+}
+
int32_t
cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)
{
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index a14a772cfb7..dc223990741 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -725,7 +725,7 @@ cli_cmd_volume_set_cbk (struct cli_state *state, struct cli_cmd_word *word,
int sent = 0;
int parse_error = 0;
- int ret = -1;
+ int ret = -1;
rpc_clnt_procedure_t *proc = NULL;
call_frame_t *frame = NULL;
dict_t *options = NULL;
@@ -1248,6 +1248,54 @@ 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_quota_cbk (struct cli_state *state, struct cli_cmd_word *word,
const char **words, int wordcount)
@@ -2395,6 +2443,10 @@ 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-rpc-ops.c b/cli/src/cli-rpc-ops.c
index a02761d5e6e..00ea6633bb6 100644
--- a/cli/src/cli-rpc-ops.c
+++ b/cli/src/cli-rpc-ops.c
@@ -1698,6 +1698,61 @@ out:
return ret;
}
+int
+gf_cli_ganesha_cbk (struct rpc_req *req, struct iovec *iov,
+ int count, void *myframe)
+{
+ gf_cli_rsp rsp = {0,};
+ int ret = -1;
+ dict_t *dict = NULL;
+ char *help_str = NULL;
+ char msg[1024] = {0,};
+ char tmp_str[512] = {0,};
+
+ if (-1 == req->rpc_status) {
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gf_cli_rsp);
+ if (ret < 0) {
+ gf_log (((call_frame_t *) myframe)->this->name, GF_LOG_ERROR,
+ "Failed to decode xdr response");
+ goto out;
+ }
+
+ gf_log ("cli", GF_LOG_DEBUG, "Received resp to ganesha");
+
+ dict = dict_new ();
+
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (rsp.dict.dict_val, rsp.dict.dict_len, &dict);
+ if (ret)
+ goto out;
+
+ if (rsp.op_ret) {
+ if (strcmp (rsp.op_errstr, ""))
+ cli_err ("ganesha enable: failed: %s", rsp.op_errstr);
+ else
+ cli_err ("ganesha enable: failed");
+ }
+
+ else {
+ cli_out("ganesha enable : success ");
+ }
+
+ ret = rsp.op_ret;
+
+out:
+ if (dict)
+ dict_unref (dict);
+ cli_cmd_broadcast_response (ret);
+ return ret;
+}
+
char *
is_server_debug_xlator (void *myframe)
{
@@ -3586,6 +3641,30 @@ out:
}
int32_t
+gf_cli_ganesha (call_frame_t *frame, xlator_t *this, void *data)
+{
+ gf_cli_req req = { {0,} } ;
+ int ret = 0;
+ dict_t *dict = NULL;
+
+ if (!frame || !this || !data) {
+ ret = -1;
+ goto out;
+ }
+
+ dict = data;
+
+ ret = cli_to_glusterd (&req, frame, gf_cli_ganesha_cbk,
+ (xdrproc_t) xdr_gf_cli_req, dict,
+ GLUSTER_CLI_GANESHA, this, cli_rpc_prog,
+ NULL);
+out:
+ gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+int32_t
gf_cli_set_volume (call_frame_t *frame, xlator_t *this,
void *data)
{
@@ -9770,6 +9849,7 @@ struct rpc_clnt_procedure gluster_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_SYS_EXEC] = {"SYS_EXEC", gf_cli_sys_exec},
[GLUSTER_CLI_SNAP] = {"SNAP", gf_cli_snapshot},
[GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER VOLUME", gf_cli_barrier_volume},
+ [GLUSTER_CLI_GANESHA] = {"GANESHA", gf_cli_ganesha},
[GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", gf_cli_get_vol_opt},
};
diff --git a/cli/src/cli.h b/cli/src/cli.h
index 2e1369af944..6951555d479 100644
--- a/cli/src/cli.h
+++ b/cli/src/cli.h
@@ -239,6 +239,9 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **opt);
int32_t
cli_cmd_volume_set_parse (const char **words, int wordcount,
dict_t **options, char **op_errstr);
+int32_t
+cli_cmd_ganesha_parse (struct cli_state *state, const char **words,
+ int wordcount, dict_t **options, char **op_errstr);
int32_t
cli_cmd_volume_add_brick_parse (const char **words, int wordcount,
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h
index ee59078de42..b06b865bbb2 100644
--- a/rpc/rpc-lib/src/protocol-common.h
+++ b/rpc/rpc-lib/src/protocol-common.h
@@ -181,6 +181,7 @@ enum gluster_cli_procnum {
GLUSTER_CLI_SNAP,
GLUSTER_CLI_BARRIER_VOLUME,
GLUSTER_CLI_GET_VOL_OPT,
+ GLUSTER_CLI_GANESHA,
GLUSTER_CLI_MAXVALUE,
};
diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c
index 267e4b995cd..d8111afa423 100644
--- a/xlators/mgmt/glusterd/src/glusterd-ganesha.c
+++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c
@@ -24,7 +24,161 @@
#define MAXBUF 1024
#define DELIM "=\""
-/* Following 2 functions parses GANESHA_HA_CONF
+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;
+ GF_ASSERT (this);
+ 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 (value, "on")) && (strcmp (value, "off"))) {
+ gf_log (this->name, GF_LOG_ERROR, "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.");
+ }
+ }
+out:
+ return ret;
+}
+
+int
+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, } ;
+ int dict_count = 0;
+ int flags = 0;
+ char errstr[2048] = {0, } ;
+ glusterd_volinfo_t *volinfo = NULL;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+
+ GF_ASSERT (dict);
+ this = THIS;
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = dict_get_str (dict, "key", &key);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "invalid key");
+ 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'");
+ goto out;
+ }
+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);
+ } else {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "Error, Cannot Validate option");
+ }
+ }
+ return ret;
+}
+
+int
+glusterd_op_set_ganesha (dict_t *dict, char **errstr)
+{
+ int ret = 0;
+ int flags = 0;
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ xlator_t *this = NULL;
+ glusterd_conf_t *priv = NULL;
+ char *key = NULL;
+ char *value = NULL;
+ char str[50] = {0, };
+ int32_t dict_count = 0;
+ dict_t *vol_opts = NULL;
+ int count = 0;
+
+ this = THIS;
+ GF_ASSERT (this);
+ GF_ASSERT (dict);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+
+ ret = dict_get_str (dict, "key", &key);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Couldn't get key in global option set");
+ goto out;
+ }
+
+ ret = dict_get_str (dict, "value", &value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Couldn't get value in global option set");
+ goto out;
+ }
+
+ ret = glusterd_handle_ganesha_op (dict, errstr, key, value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Initial NFS-Ganesha set up failed");
+ ret = -1;
+ goto out;
+ }
+ ret = dict_set_str(priv->opts, "features.ganesha", value);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING, "Failed to set"
+ " features.ganesha in dict.");
+ goto out;
+ }
+
+ /* To do : Lock the global options file before writing */
+ /* into this file. Bug ID : 1200254 */
+
+ ret = glusterd_store_options (this, priv->opts);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Failed to store options");
+ goto out;
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "returning %d", ret);
+ return ret;
+}
+
+/* Following 2 functions parse GANESHA_HA_CONF
* The sample file looks like below,
* HA_NAME="ganesha-ha-360"
* HA_VOL_NAME="ha-state"
@@ -181,6 +335,7 @@ 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 */
/* Create the export file only when ganesha.enable "on" is executed */
if (strcmp (value, "on") == 0) {
@@ -253,7 +408,7 @@ stop_ganesha (char **op_errstr)
if (check_host_list ()) {
runinit (&runner);
- runner_add_args (&runner, "service nfs-ganesha", "stop", NULL);
+ runner_add_args (&runner, "service", " nfs-ganesha", "stop", NULL);
ret = runner_run (&runner);
}
out:
diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c
index 1c33f3febb3..954fa859944 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handler.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handler.c
@@ -1643,6 +1643,82 @@ glusterd_op_begin (rpcsvc_request_t *req, glusterd_op_t op, void *ctx,
}
int
+__glusterd_handle_ganesha_cmd (rpcsvc_request_t *req)
+{
+ int32_t ret = -1;
+ gf_cli_req cli_req = { {0,} } ;
+ dict_t *dict = NULL;
+ glusterd_op_t cli_op = GD_OP_GANESHA;
+ char *volname = NULL;
+ char *op_errstr = NULL;
+ gf_boolean_t help = _gf_false;
+ char err_str[2048] = {0,};
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ GF_ASSERT (req);
+
+ ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req);
+ if (ret < 0) {
+ snprintf (err_str, sizeof (err_str), "Failed to decode "
+ "request received from cli");
+ gf_log (this->name, GF_LOG_ERROR, "%s", err_str);
+ req->rpc_err = GARBAGE_ARGS;
+ goto out;
+ }
+
+ if (cli_req.dict.dict_len) {
+ /* Unserialize the dictionary */
+ dict = dict_new ();
+ if (!dict) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = dict_unserialize (cli_req.dict.dict_val,
+ cli_req.dict.dict_len,
+ &dict);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to "
+ "unserialize req-buffer to dictionary");
+ snprintf (err_str, sizeof (err_str), "Unable to decode "
+ "the command");
+ goto out;
+ } else {
+ dict->extra_stdfree = cli_req.dict.dict_val;
+ }
+ }
+
+ gf_log (this->name, GF_LOG_TRACE, "Received global option request");
+
+ ret = glusterd_op_begin_synctask (req, GD_OP_GANESHA, dict);
+out:
+ if (ret) {
+ if (err_str[0] == '\0')
+ snprintf (err_str, sizeof (err_str),
+ "Operation failed");
+ ret = glusterd_op_send_cli_response (cli_op, ret, 0, req,
+ dict, err_str);
+ }
+ if (op_errstr)
+ GF_FREE (op_errstr);
+ if (dict)
+ dict_unref(dict);
+
+ return ret;
+}
+
+
+int
+glusterd_handle_ganesha_cmd (rpcsvc_request_t *req)
+{
+ return glusterd_big_locked_handler (req, __glusterd_handle_ganesha_cmd);
+}
+
+int
__glusterd_handle_reset_volume (rpcsvc_request_t *req)
{
int32_t ret = -1;
@@ -4763,6 +4839,7 @@ rpcsvc_actor_t gd_svc_cli_actors[GLUSTER_CLI_MAXVALUE] = {
[GLUSTER_CLI_SYS_EXEC] = {"SYS_EXEC", GLUSTER_CLI_SYS_EXEC, glusterd_handle_sys_exec, NULL, 0, DRC_NA},
[GLUSTER_CLI_SNAP] = {"SNAP", GLUSTER_CLI_SNAP, glusterd_handle_snapshot, NULL, 0, DRC_NA},
[GLUSTER_CLI_BARRIER_VOLUME] = {"BARRIER_VOLUME", GLUSTER_CLI_BARRIER_VOLUME, glusterd_handle_barrier, NULL, 0, DRC_NA},
+ [GLUSTER_CLI_GANESHA] = { "GANESHA" , GLUSTER_CLI_GANESHA, glusterd_handle_ganesha_cmd, NULL, 0, DRC_NA},
[GLUSTER_CLI_GET_VOL_OPT] = {"GET_VOL_OPT", GLUSTER_CLI_GET_VOL_OPT, glusterd_handle_get_vol_opt, NULL, 0, DRC_NA},
};
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 2f121e49e9e..035b4528e10 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -1881,7 +1881,6 @@ glusterd_op_set_all_volume_options (xlator_t *this, dict_t *dict)
*/
goto out;
}
-
ret = -1;
dup_opt = dict_new ();
if (!dup_opt)
@@ -1938,7 +1937,7 @@ out:
}
static int
-glusterd_op_set_volume (dict_t *dict)
+glusterd_op_set_volume (dict_t *dict, char **errstr)
{
int ret = 0;
glusterd_volinfo_t *volinfo = NULL;
@@ -2055,6 +2054,9 @@ glusterd_op_set_volume (dict_t *dict)
}
}
+ ret = glusterd_check_ganesha_cmd (key, value, errstr, dict);
+ if (ret == -1)
+ goto out;
if (!is_key_glusterd_hooks_friendly (key)) {
ret = glusterd_check_option_exists (key, &key_fixed);
GF_ASSERT (ret);
@@ -3471,6 +3473,12 @@ glusterd_op_build_payload (dict_t **req, char **op_errstr, dict_t *op_ctx)
break;
}
+ case GD_OP_GANESHA:
+ {
+ dict_copy (dict, req_dict);
+ break;
+ }
+
default:
break;
}
@@ -4848,6 +4856,10 @@ glusterd_op_stage_validate (glusterd_op_t op, dict_t *dict, char **op_errstr,
ret = glusterd_op_stage_set_volume (dict, op_errstr);
break;
+ case GD_OP_GANESHA:
+ ret = glusterd_op_stage_set_ganesha (dict, op_errstr);
+ break;
+
case GD_OP_RESET_VOLUME:
ret = glusterd_op_stage_reset_volume (dict, op_errstr);
break;
@@ -4959,7 +4971,10 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,
break;
case GD_OP_SET_VOLUME:
- ret = glusterd_op_set_volume (dict);
+ ret = glusterd_op_set_volume (dict, op_errstr);
+ break;
+ case GD_OP_GANESHA:
+ ret = glusterd_op_set_ganesha (dict, op_errstr);
break;
case GD_OP_RESET_VOLUME:
diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
index 6025a0748a0..353c757ba92 100644
--- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c
@@ -135,6 +135,7 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret,
case GD_OP_REPLACE_BRICK:
case GD_OP_STATUS_VOLUME:
case GD_OP_SET_VOLUME:
+ case GD_OP_GANESHA:
case GD_OP_LIST_VOLUME:
case GD_OP_CLEARLOCKS_VOLUME:
case GD_OP_HEAL_VOLUME:
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 4d9dce47a13..467d8cb8518 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1444,16 +1444,6 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.option = "!nfs-disable",
.op_version = 1
},
- { .key = "nfs-ganesha.enable",
- .voltype = "nfs/server",
- .option = "!nfs-ganesha.enable",
- .op_version = GD_OP_VERSION_3_6_0,
- },
- { .key = "nfs-ganesha.host",
- .voltype = "nfs/server",
- .option = "!nfs-ganesha.host",
- .op_version = GD_OP_VERSION_3_6_0,
- },
{ .key = "nfs.nlm",
.voltype = "nfs/server",
.option = "nfs.nlm",
@@ -1718,6 +1708,18 @@ 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,
+ .op_version = GD_OP_VERSION_3_7_0,
+ },
+
{ .key = NULL
}
};
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 7aeed450932..7bc949c8cef 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -110,6 +110,7 @@ typedef enum glusterd_op_ {
GD_OP_GSYNC_CREATE,
GD_OP_SNAP,
GD_OP_BARRIER,
+ GD_OP_GANESHA,
GD_OP_MAX,
} glusterd_op_t;
@@ -950,7 +951,12 @@ int glusterd_op_create_volume (dict_t *dict, char **op_errstr);
int glusterd_op_start_volume (dict_t *dict, char **op_errstr);
int glusterd_op_stop_volume (dict_t *dict);
int glusterd_op_delete_volume (dict_t *dict);
-
+int glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr,
+ char *key, char *value);
+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 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,
@@ -983,7 +989,6 @@ int glusterd_op_gsync_args_get (dict_t *dict, char **op_errstr,
int glusterd_start_volume (glusterd_volinfo_t *volinfo, int flags,
gf_boolean_t wait);
-
int glusterd_stop_volume (glusterd_volinfo_t *volinfo);
/* Synctask part */