summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/src/Makefile.am2
-rw-r--r--cli/src/cli-cmd-global.c131
-rw-r--r--cli/src/cli-cmd-misc.c3
-rw-r--r--cli/src/cli-cmd-parser.c12
-rw-r--r--cli/src/cli-cmd-volume.c52
-rw-r--r--cli/src/cli-cmd.c6
-rw-r--r--cli/src/cli-cmd.h2
-rw-r--r--xlators/features/ganesha/src/ganesha.c6
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-ganesha.c248
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c23
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-store.h1
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c21
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c9
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h4
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 b163b85f95f..38b30a4fe04 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 014afad6738..c731284cdfe 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -1382,54 +1382,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)
@@ -2634,10 +2586,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 4c6521f79ea..a52fcd1ac2f 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -1653,6 +1653,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);
@@ -1679,6 +1681,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 ();
@@ -1783,6 +1797,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 a42f08c1600..24b3a0c95e4 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 "
@@ -2327,7 +2336,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 ff63cce2234..9b911e60b7c 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -989,6 +989,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,