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,  | 
