From ce0aaba383b97dca52d11c18846a8154d529bf8a Mon Sep 17 00:00:00 2001 From: Kaushik BV Date: Tue, 16 Aug 2011 13:10:41 +0530 Subject: mgmt/Glusterd: Implementation volume set help/help-xml Change-Id: I0c54fd1c15550e5e5551e95ed32adb14d8029fab Reviewed-on: http://review.gluster.com/238 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- cli/src/cli-cmd-parser.c | 10 +- cli/src/cli-rpc-ops.c | 19 +- configure.ac | 9 + libglusterfs/src/xlator.c | 105 ++++++ libglusterfs/src/xlator.h | 8 +- xlators/cluster/afr/src/afr.c | 46 ++- xlators/cluster/dht/src/dht.c | 29 +- xlators/cluster/stripe/src/stripe.c | 52 ++- xlators/debug/io-stats/src/io-stats.c | 76 ++++- xlators/features/quota/src/quota.c | 33 +- xlators/mgmt/glusterd/src/Makefile.am | 4 +- xlators/mgmt/glusterd/src/glusterd-handler.c | 17 +- xlators/mgmt/glusterd/src/glusterd-op-sm.c | 98 ++++-- xlators/mgmt/glusterd/src/glusterd-rpc-ops.c | 10 + xlators/mgmt/glusterd/src/glusterd-volgen.c | 362 +++++++++++++++++++-- xlators/mgmt/glusterd/src/glusterd-volgen.h | 2 + xlators/nfs/server/src/nfs.c | 76 ++++- xlators/performance/io-cache/src/io-cache.c | 104 +++++- xlators/performance/io-threads/src/io-threads.c | 34 +- xlators/performance/quick-read/src/quick-read.c | 21 +- .../performance/write-behind/src/write-behind.c | 47 ++- xlators/protocol/client/src/client.c | 48 ++- xlators/protocol/server/src/server.c | 18 + 23 files changed, 1087 insertions(+), 141 deletions(-) diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index a005c8f88..346baeed8 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -570,7 +570,7 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options) if (!dict) goto out; - if (wordcount < 4) + if (wordcount < 3) goto out; volname = (char *)words[2]; @@ -582,6 +582,14 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options) if (ret) goto out; + if (!strcmp (volname, "help") && !words[3] && !words[4]) + ret = dict_set_str (dict, "help", volname); + + if (!strcmp (volname, "help-xml") && !words[3] && !words[4]) + ret = dict_set_str (dict, "help-xml", volname); + + if (ret) + goto out; for (i = 3; i < wordcount; i+=2) { diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index b15cc4b2e..61e1dcef2 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -963,6 +963,8 @@ gf_cli3_1_set_volume_cbk (struct rpc_req *req, struct iovec *iov, { gf1_cli_set_vol_rsp rsp = {0,}; int ret = 0; + dict_t *dict = NULL; + char *help_str = NULL; if (-1 == req->rpc_status) { goto out; @@ -978,9 +980,24 @@ gf_cli3_1_set_volume_cbk (struct rpc_req *req, struct iovec *iov, if (rsp.op_ret && strcmp (rsp.op_errstr, "")) cli_out ("%s", rsp.op_errstr); - else + + 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 (dict_get_str (dict, "help-str", &help_str)) cli_out ("Set volume %s", (rsp.op_ret) ? "unsuccessful": "successful"); + else + cli_out ("%s", help_str); ret = rsp.op_ret; diff --git a/configure.ac b/configure.ac index c66709908..85296ee23 100644 --- a/configure.ac +++ b/configure.ac @@ -337,6 +337,15 @@ AC_SUBST(SYNCDAEMON_COMPILE) AC_SUBST(SYNCDAEMON_SUBDIR) # end SYNCDAEMON section +#check if libxml is present if so enable HAVE_LIB_XML +echo -n "checking if libxml2 is present... " + +PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.6.19], + [echo "yes (features requiring libxml2 enabled)" AC_DEFINE(HAVE_LIB_XML, 1, [define if libxml2 is present])], + [echo "no"] ) + +AC_SUBST(LIBXML2_CFLAGS) +AC_SUBST(LIBXML2_LIBS) dnl FreeBSD > 5 has execinfo as a Ported library for giving a workaround dnl solution to GCC backtrace functionality diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 740905202..5c526acd5 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -1170,7 +1170,64 @@ xlator_set_type_virtual (xlator_t *xl, const char *type) out: return -1; } +int32_t +xlator_volopt_dynload (char *xlator_type, void **dl_handle, + volume_opt_list_t *opt_list) +{ + int ret = -1; + char *name = NULL; + void *handle = NULL; + volume_opt_list_t *vol_opt = NULL; + + GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out); + + GF_ASSERT (dl_handle); + + if (*dl_handle) + if (dlclose (*dl_handle)) + gf_log ("xlator", GF_LOG_WARNING, "Unable to close " + "previously opened handle( may be stale)." + "Ignoring the invalid handle"); + + ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type); + if (-1 == ret) { + gf_log ("xlator", GF_LOG_ERROR, "asprintf failed"); + goto out; + } + + ret = -1; + + gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name); + + handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); + if (!handle) { + gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ()); + goto out; + } + *dl_handle = handle; + + vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), + gf_common_mt_volume_opt_list_t); + + if (!vol_opt) { + goto out; + } + + if (!(vol_opt->given_opt = dlsym (handle, "options"))) { + dlerror (); + gf_log ("xlator", GF_LOG_DEBUG, + "Strict option validation not enforced -- neglecting"); + } + list_add (&vol_opt->list, &opt_list->list); + + ret = 0; + out: + if (name) + GF_FREE (name); + gf_log ("xlator", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} int32_t xlator_dynload (xlator_t *xl) @@ -1845,3 +1902,51 @@ glusterd_check_log_level (const char *value) return log_level; } + +int +xlator_get_volopt_info (struct list_head *opt_list, char *key, char **def_val, + char **descr) +{ + + int index = 0; + int ret = -1; + volume_opt_list_t *vol_list = NULL; + volume_option_t *opt = NULL; + + if (!opt_list || !key || !def_val ) { + gf_log ("", GF_LOG_WARNING, " Parameters to the function not " + "valid"); + ret = -1; + goto out; + } + + if (list_empty (opt_list)) { + gf_log ("xlator", GF_LOG_WARNING, "No elements in Volume option" + " list"); + ret = -1; + goto out; + } + + + vol_list = list_entry (opt_list->next, volume_opt_list_t, list); + + opt = vol_list->given_opt; + + for (index = 0; opt[index].key && opt[index].key[0] ; index++) { + if (strncmp (key, opt[index].key[0], strlen (key))) + continue; + + *def_val = opt[index].default_value; + if (descr) + *descr = opt[index].description; + ret = 0; + goto out; + } + + ret = -1; + +out: + gf_log ("", GF_LOG_DEBUG, "Returning %d", ret); + return ret; + +} diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 044bfff95..1ecde5d5f 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -786,6 +786,7 @@ typedef struct volume_options { char *value[ZR_OPTION_MAX_ARRAY_SIZE]; /* If specified, will check for one of the value from this array */ + char *default_value; char *description; /* about the key */ } volume_option_t; @@ -881,7 +882,8 @@ int _volume_option_value_validate_attacherr (xlator_t *xl, data_pair_t *pair, volume_option_t *opt, char **op_errstr); - - - +int32_t xlator_volopt_dynload (char *xlator_type, void **dl_handle, + volume_opt_list_t *vol_opt_handle); +int xlator_get_volopt_info (struct list_head *opt_list, char *key, + char **def_val, char **descr); #endif /* _XLATOR_H */ diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 645388d46..a662037e7 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -30,6 +30,8 @@ #endif #include "afr-common.c" +struct volume_options options[]; + int32_t notify (xlator_t *this, int32_t event, void *data, ...) @@ -377,6 +379,7 @@ init (xlator_t *this) char * strict_readdir = NULL; char * inodelk_trace = NULL; char * entrylk_trace = NULL; + char * def_val = NULL; int32_t background_count = 0; int32_t lock_server_count = 1; int32_t window_size = 0; @@ -437,16 +440,37 @@ init (xlator_t *this) } } - priv->data_self_heal_algorithm = ""; - + if (xlator_get_volopt_info (&this->volume_options, + "data-self-heal-algorithm", &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + " data-self-heal-algorithm not found"); + ret = -1; + goto out; + } else { + priv->data_self_heal_algorithm = def_val; + } dict_ret = dict_get_str (this->options, "data-self-heal-algorithm", &algo); if (dict_ret == 0) { priv->data_self_heal_algorithm = gf_strdup (algo); } - - priv->data_self_heal_window_size = 16; + if (xlator_get_volopt_info (&this->volume_options, + "data-self-heal-window-size",&def_val, + NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "data-self-heal-window-size not found"); + ret = -1; + goto out; + } else { + if (gf_string2int32 (def_val, + (int *)&priv->data_self_heal_window_size)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "data-self-heal-window-size corrupt"); + ret = -1; + goto out; + } + } dict_ret = dict_get_int32 (this->options, "data-self-heal-window-size", &window_size); @@ -808,12 +832,22 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_BOOL }, { .key = {"data-self-heal-algorithm"}, - .type = GF_OPTION_TYPE_STR + .type = GF_OPTION_TYPE_STR, + .default_value = "", + .description = "Select between \"full\", \"diff\". The " + "\"full\" algorithm copies the entire file from " + "source to sink. The \"diff\" algorithm copies to " + "sink only those blocks whose checksums don't match " + "with those of source.", + .value = { "diff", "full" } }, { .key = {"data-self-heal-window-size"}, .type = GF_OPTION_TYPE_INT, .min = 1, - .max = 1024 + .max = 1024, + .default_value = "16", + .description = "Maximum number blocks per file for which self-heal " + "process would be applied simultaneously." }, { .key = {"metadata-self-heal"}, .type = GF_OPTION_TYPE_BOOL diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c index ffdcce340..0958a8bab 100644 --- a/xlators/cluster/dht/src/dht.c +++ b/xlators/cluster/dht/src/dht.c @@ -34,7 +34,7 @@ - handle all cases in self heal layout reconstruction - complete linkfile selfheal */ - +struct volume_options options[]; void dht_layout_dump (dht_layout_t *layout, const char *prefix) @@ -359,6 +359,7 @@ init (xlator_t *this) int ret = -1; int i = 0; uint32_t temp_free_disk = 0; + char *def_val = NULL; GF_VALIDATE_OR_GOTO ("dht", this, err); @@ -401,8 +402,27 @@ init (xlator_t *this) gf_string2boolean (temp_str, &conf->use_readdirp); } - conf->disk_unit = 'p'; - conf->min_free_disk = 10; + if (xlator_get_volopt_info (&this->volume_options, "min-free-disk", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + " min-free-disk not found"); + ret = -1; + goto err; + } else { + if (gf_string2percent (def_val, &temp_free_disk) == 0) { + if (temp_free_disk > 100) { + gf_string2bytesize (temp_str, + &conf->min_free_disk); + conf->disk_unit = 'b'; + } else { + conf->min_free_disk = (uint64_t)temp_free_disk; + conf->disk_unit = 'p'; + } + } else { + gf_string2bytesize (temp_str, &conf->min_free_disk); + conf->disk_unit = 'b'; + } + } if (dict_get_str (this->options, "min-free-disk", &temp_str) == 0) { if (gf_string2percent (temp_str, &temp_free_disk) == 0) { @@ -550,6 +570,9 @@ struct volume_options options[] = { }, { .key = {"min-free-disk"}, .type = GF_OPTION_TYPE_PERCENT_OR_SIZET, + .default_value = "10%", + .description = "Percentage/Size of disk space that must be " + "kept free." }, { .key = {"unhashed-sticky-bit"}, .type = GF_OPTION_TYPE_BOOL diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 5dcf19513..81f37a572 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -37,6 +37,8 @@ #include "libxlator.h" #include "byte-order.h" +struct volume_options options[]; + void stripe_local_wipe (stripe_local_t *local) { @@ -4030,6 +4032,7 @@ init (xlator_t *this) stripe_private_t *priv = NULL; xlator_list_t *trav = NULL; data_t *data = NULL; + char *def_blk_size = NULL; int32_t count = 0; int ret = -1; @@ -4093,20 +4096,55 @@ init (xlator_t *this) goto out; } - priv->block_size = (128 * GF_UNIT_KB); + if (xlator_get_volopt_info (&this->volume_options, "block-size", + &def_blk_size, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of stripe " + "block-size corrupt"); + ret = -1; + goto out; + } else { + if (gf_string2bytesize (def_blk_size, &priv->block_size)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "stripe block-size corrupt"); + ret = -1; + goto out; + } + } + + /* option stripe-pattern *avi:1GB,*pdf:4096 */ data = dict_get (this->options, "block-size"); if (!data) { gf_log (this->name, GF_LOG_DEBUG, "No \"option block-size \" given, defaulting " - "to 128KB"); + "to %s", def_blk_size); } else { ret = set_stripe_block_size (this, priv, data->data); if (ret) goto out; } - priv->xattr_supported = 1; + if (xlator_get_volopt_info (&this->volume_options, "use-xattr", + &def_blk_size, NULL)) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "error setting(default) hard check for extended" + " attribute"); + goto out; + + } + else { + if (gf_string2boolean (def_blk_size, + &priv->xattr_supported)) { + ret = -1; + gf_log (this->name, GF_LOG_ERROR, + "error setting(default) hard check for extended" + " attribute"); + goto out; + } + } + + data = dict_get (this->options, "use-xattr"); if (data) { if (gf_string2boolean (data->data, @@ -4364,10 +4402,14 @@ struct xlator_cbks cbks = { struct volume_options options[] = { { .key = {"block-size"}, - .type = GF_OPTION_TYPE_ANY + .type = GF_OPTION_TYPE_ANY, + .default_value = "128KB", + .description = "Size of the stripe unit that would be read " + "from or written to the striped servers." }, { .key = {"use-xattr"}, - .type = GF_OPTION_TYPE_BOOL + .type = GF_OPTION_TYPE_BOOL, + .default_value = "true" }, { .key = {NULL} }, }; diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c index 170cb8c93..541ca46bc 100644 --- a/xlators/debug/io-stats/src/io-stats.c +++ b/xlators/debug/io-stats/src/io-stats.c @@ -157,6 +157,8 @@ struct ios_local { struct timeval unwind_at; }; +struct volume_options options[]; + inline static int is_fop_latency_started (call_frame_t *frame) { @@ -2302,17 +2304,34 @@ io_stats_forget (xlator_t *this, inode_t *inode) } int -iostats_configure_options (xlator_t *this, dict_t *options, +iostats_configure_options (xlator_t *this, dict_t *xl_options, struct ios_conf *conf) { int ret = 0; char *log_str = NULL; + char *def_val = NULL; + gf_boolean_t def_bool = _gf_false; + GF_ASSERT (this); - GF_ASSERT (options); + GF_ASSERT (xl_options); GF_ASSERT (conf); - ret = dict_get_str_boolean (options, "dump-fd-stats", _gf_false); + if (xlator_get_volopt_info (&this->volume_options, "dump-fd-stats", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + " dump-fd-stats not found"); + ret = -1; + goto out; + } else { + if (gf_string2boolean (def_val, &def_bool)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "dump-fd-stats corrupt"); + ret = -1; + goto out; + } + } + ret = dict_get_str_boolean (xl_options, "dump-fd-stats", def_bool); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, "'dump-fd-stats' takes only boolean arguments"); @@ -2324,7 +2343,7 @@ iostats_configure_options (xlator_t *this, dict_t *options, gf_log (this->name, GF_LOG_DEBUG, "disabling dump-fd-stats"); } - ret = dict_get_str_boolean (options, "count-fop-hits", _gf_false); + ret = dict_get_str_boolean (xl_options, "count-fop-hits", _gf_false); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, "'count-fop-hits' takes only boolean arguments"); @@ -2338,7 +2357,22 @@ iostats_configure_options (xlator_t *this, dict_t *options, "disabling count-fop-hits"); } - ret = dict_get_str_boolean (options, "latency-measurement", 0); + if (xlator_get_volopt_info (&this->volume_options, "latency-measurement", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "latency-measurement not found"); + ret = -1; + goto out; + } else { + if (gf_string2boolean (def_val, &def_bool)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "latency-measurement corrupt"); + ret = -1; + goto out; + } + } + ret = dict_get_str_boolean (xl_options, "latency-measurement", + def_bool); if (ret != -1) { if (conf->measure_latency != ret) { gf_log (this->name, GF_LOG_DEBUG, @@ -2351,7 +2385,7 @@ iostats_configure_options (xlator_t *this, dict_t *options, "'latency-measurement' takes only boolean arguments"); } - ret = dict_get_str (options, "log-level", &log_str); + ret = dict_get_str (xl_options, "log-level", &log_str); if (!ret) { if (!is_gf_log_command(this, "trusted.glusterfs.set-log-level", log_str)) { @@ -2359,7 +2393,11 @@ iostats_configure_options (xlator_t *this, dict_t *options, "changing log-level to %s", log_str); } } - return 0; + ret = 0; + out: + gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); + return ret; + } int @@ -2635,9 +2673,15 @@ struct xlator_cbks cbks = { struct volume_options options[] = { { .key = {"dump-fd-stats"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "If on stats related to file-operations would be " + "tracked inside GlusterFS data-structures." }, { .key = { "latency-measurement" }, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .description = "If on stats related to the latency of each operation " + "would be tracked inside GlusterFS data-structures. " }, { .key = {"count-fop-hits"}, .type = GF_OPTION_TYPE_BOOL, @@ -2647,5 +2691,21 @@ struct volume_options options[] = { .value = { "DEBUG", "WARNING", "ERROR", "INFO", "CRITICAL", "NONE", "TRACE"} }, - { .key = {NULL} }, + + /* These are synthetic entries to assist validation of CLI's * + * volume set command */ + { .key = {"client-log-level"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "INFO", + .description = "Changes the log-level of the clients", + .value = { "DEBUG", "WARNING", "ERROR", "CRITICAL", "NONE", "TRACE"} + }, + { .key = {"brick-log-level"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "INFO", + .description = "Changes the log-level of the bricks", + .value = { "DEBUG", "WARNING", "ERROR", "CRITICAL", "NONE", "TRACE"} + }, + { .key = {NULL} }, + }; diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index b0fe7bc5c..9a47adaed 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -23,6 +23,7 @@ int32_t quota_check_limit (call_frame_t *frame, inode_t *inode, xlator_t *this, char *name, ino_t par); +struct volume_options options[]; int quota_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) @@ -2621,7 +2622,7 @@ out: } int32_t -quota_parse_options (quota_priv_t *priv, xlator_t *this, dict_t *options) +quota_parse_options (quota_priv_t *priv, xlator_t *this, dict_t *xl_options) { int32_t ret = -1; char *str = NULL; @@ -2629,8 +2630,9 @@ quota_parse_options (quota_priv_t *priv, xlator_t *this, dict_t *options) char *path = NULL; uint64_t value = 0; limits_t *quota_lim = NULL; + char *def_val = NULL; - ret = dict_get_str (options, "limit-set", &str); + ret = dict_get_str (xl_options, "limit-set", &str); if (str) { path = strtok (str, ":"); @@ -2661,7 +2663,22 @@ quota_parse_options (quota_priv_t *priv, xlator_t *this, dict_t *options) "no \"limit-set\" option provided"); } - ret = dict_get_str (options, "timeout", &str); + if (xlator_get_volopt_info (&this->volume_options, "timeout", &def_val, + NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of timeout" + "not found"); + ret = -1; + goto err; + } else { + if (gf_string2bytesize (def_val,(uint64_t *) &priv->timeout )) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + " timeout corrupt"); + ret = -1; + goto err; + } + } + + ret = dict_get_str (xl_options, "timeout", &str); if (str) { ret = gf_string2bytesize (str, &value); if (ret < 0) { @@ -2675,10 +2692,6 @@ quota_parse_options (quota_priv_t *priv, xlator_t *this, dict_t *options) "quota timeout value = %"PRId64, priv->timeout); } - } else { - gf_log (this->name, GF_LOG_INFO, "timeout option not provided, " - "taking default as 0"); - priv->timeout = 0; } list_for_each_entry (quota_lim, &priv->limit_head, limit_list) { @@ -2789,7 +2802,11 @@ struct xlator_cbks cbks = { struct volume_options options[] = { {.key = {"limit-set"}}, - {.key = {"timeout"} + {.key = {"timeout"}, + .type = GF_OPTION_TYPE_SIZET, + .default_value = "0", + .description = "quota caches the directory sizes on client. Timeout " + "indicates the timeout for the cache to be revalidated." }, {.key = {NULL}} }; diff --git a/xlators/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index 1c89dba97..714b78e62 100644 --- a/xlators/mgmt/glusterd/src/Makefile.am +++ b/xlators/mgmt/glusterd/src/Makefile.am @@ -1,6 +1,6 @@ xlator_LTLIBRARIES = glusterd.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/mgmt -glusterd_la_LDFLAGS = -module -avoidversion +glusterd_la_LDFLAGS = -module -avoidversion $(LIBXML2_LIBS) glusterd_la_SOURCES = glusterd.c glusterd-handler.c glusterd-sm.c glusterd-op-sm.c \ glusterd-utils.c glusterd-rpc-ops.c glusterd-store.c glusterd-handshake.c \ glusterd-pmap.c glusterd-volgen.c glusterd-rebalance.c @@ -17,7 +17,7 @@ AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ -I$(rpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree -I$(top_srcdir)/rpc/xdr/src\ -I$(top_srcdir)/rpc/rpc-lib/src -I$(CONTRIBDIR)/uuid -I$(top_srcdir)/contrib/md5 -DGFS_PREFIX=\"$(prefix)\" \ -DDATADIR=\"$(localstatedir)\" -DGSYNCD_PREFIX=\"$(libexecdir)/glusterfs\"\ - -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) + -DSYNCDAEMON_COMPILE=$(SYNCDAEMON_COMPILE) $(LIBXML2_CFLAGS) CLEANFILES = diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index ec1e8ab66..6dd218cd9 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -1935,18 +1935,23 @@ glusterd_handle_set_volume (rpcsvc_request_t *req) ret = dict_get_str (dict, "key1", &key); if (ret) { - gf_log ("", GF_LOG_WARNING, "Unable to get key, while" - "handling volume set for %s",volname); - goto out; + if (strcmp (volname, "help-xml") && strcmp (volname, "help")) { + gf_log ("", GF_LOG_WARNING, "Unable to get key, while" + "handling volume set for %s",volname); + goto out; + } } ret = dict_get_str (dict, "value1", &value); if (ret) { - gf_log ("", GF_LOG_WARNING, "Unable to get value, while" - "handling volume set for %s",volname); - goto out; + if (strcmp (volname, "help-xml") && strcmp (volname, "help")) { + gf_log ("", GF_LOG_WARNING, "Unable to get value, while" + "handling volume set for %s",volname); + goto out; + } } + gf_cmd_log ("volume set", "volume-name:%s: key:%s, value:%s",volname, key, value); ret = glusterd_op_begin (req, GD_OP_SET_VOLUME, dict, _gf_true); diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index c3da4a596..5c26ca5e7 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1222,6 +1222,39 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) if (!val_dict) goto out; + ret = dict_get_int32 (dict, "count", &dict_count); + + if (ret) { + gf_log ("", GF_LOG_ERROR, "Count(dict),not set in Volume-Set"); + goto out; + } + + if ( dict_count == 0 ) { + /*No options would be specified of volume set help */ + if (dict_get (dict, "help" )) { + ret = 0; + goto out; + } + + if (dict_get (dict, "help-xml" )) { + +#if (HAVE_LIB_XML) + ret = 0; + goto out; +#else + ret = -1; + gf_log ("", GF_LOG_ERROR, "libxml not present in the" + "system"); + *op_errstr = gf_strdup ("Error: xml libraries not " + "present to produce xml-output"); + goto out; +#endif + } + gf_log ("", GF_LOG_ERROR, "No options received "); + *op_errstr = gf_strdup ("Options not specified"); + ret = -1; + goto out; + } ret = dict_get_str (dict, "volname", &volname); if (ret) { @@ -1230,7 +1263,6 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) } exists = glusterd_check_volume_exists (volname); - if (!exists) { snprintf (errstr, sizeof (errstr), "Volume %s does not exist", volname); @@ -1246,27 +1278,6 @@ glusterd_op_stage_set_volume (dict_t *dict, char **op_errstr) goto out; } - ret = dict_get_int32 (dict, "count", &dict_count); - - if (ret) { - gf_log ("", GF_LOG_ERROR, "Count(dict),not set in Volume-Set"); - goto out; - } - - if ( dict_count == 1 ) { - if (dict_get (dict, "history" )) { - ret = 0; - goto out; - } - - gf_log ("", GF_LOG_ERROR, "No options received "); - *op_errstr = gf_strdup ("Options not specified"); - ret = -1; - goto out; - } - - - for ( count = 1; ret != 1 ; count++ ) { global_opt = _gf_false; sprintf (str, "key%d", count); @@ -5357,6 +5368,25 @@ glusterd_restart_brick_servers (glusterd_volinfo_t *volinfo) return 0; } +static int +glusterd_volset_help (dict_t *dict) +{ + int ret = -1; + gf_boolean_t xml_out = _gf_false; + + if (dict_get (dict, "help" )) + xml_out = _gf_false; + else if (dict_get (dict, "help-xml" )) + xml_out = _gf_true; + else + goto out; + + ret = glusterd_get_volopt_content (xml_out); + out: + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} + static int glusterd_op_set_volume (dict_t *dict) { @@ -5372,7 +5402,8 @@ glusterd_op_set_volume (dict_t *dict) char *value = NULL; char str[50] = {0, }; gf_boolean_t global_opt = _gf_false; - glusterd_volinfo_t *voliter = NULL; + glusterd_volinfo_t *voliter = NULL; + int32_t dict_count = 0; this = THIS; GF_ASSERT (this); @@ -5380,8 +5411,21 @@ glusterd_op_set_volume (dict_t *dict) priv = this->private; GF_ASSERT (priv); - ret = dict_get_str (dict, "volname", &volname); + ret = dict_get_int32 (dict, "count", &dict_count); + if (ret) { + gf_log ("", GF_LOG_ERROR, "Count(dict),not set in Volume-Set"); + goto out; + } + + if ( dict_count == 0 ) { + ret = glusterd_volset_help (dict); + if (ret) + gf_log ("glusterd", GF_LOG_ERROR, "Volume set help" + "internal error"); + goto out; + } + ret = dict_get_str (dict, "volname", &volname); if (ret) { gf_log ("", GF_LOG_ERROR, "Unable to get volume name"); goto out; @@ -5460,7 +5504,6 @@ glusterd_op_set_volume (dict_t *dict) } } - if ( count == 1 ) { gf_log ("", GF_LOG_ERROR, "No options received "); ret = -1; @@ -5531,11 +5574,8 @@ glusterd_op_set_volume (dict_t *dict) } } - - ret = 0; - -out: + out: if (key_fixed) GF_FREE (key_fixed); gf_log ("", GF_LOG_DEBUG, "returning %d", ret); diff --git a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c index 170995d78..f6134839f 100644 --- a/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c +++ b/xlators/mgmt/glusterd/src/glusterd-rpc-ops.c @@ -191,10 +191,20 @@ glusterd_op_send_cli_response (glusterd_op_t op, int32_t op_ret, rsp.op_ret = op_ret; rsp.op_errno = op_errno; rsp.volname = ""; + ctx = op_ctx; + if (op_errstr) rsp.op_errstr = op_errstr; else rsp.op_errstr = ""; + if (ctx) { + ret = dict_allocate_and_serialize (ctx, + &rsp.dict.dict_val, + (size_t*)&rsp.dict.dict_len); + if (ret == 0) + free_ptr = rsp.dict.dict_val; + } + cli_rsp = &rsp; sfunc = gf_xdr_serialize_cli_set_vol_rsp; break; diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c index 3eceb5f44..2551d5f22 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.c +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c @@ -25,6 +25,11 @@ #include +#if (HAVE_LIB_XML) +#include +#include +#endif + #include "xlator.h" #include "glusterd.h" #include "defaults.h" @@ -121,8 +126,8 @@ static struct volopt_map_entry glusterd_volopt_map[] = { {VKEY_DIAG_LAT_MEASUREMENT, "debug/io-stats", "latency-measurement", "off", NO_DOC, 0 }, {"diagnostics.dump-fd-stats", "debug/io-stats", NULL, NULL, NO_DOC, 0 }, {VKEY_DIAG_CNT_FOP_HITS, "debug/io-stats", "count-fop-hits", "off", NO_DOC, 0 }, - {"diagnostics.brick-log-level", "debug/io-stats", "!log-level", NULL, DOC, 0}, - {"diagnostics.client-log-level", "debug/io-stats", "!log-level", NULL, DOC, 0}, + {"diagnostics.brick-log-level", "debug/io-stats", "!brick-log-level", NULL, DOC, 0}, + {"diagnostics.client-log-level", "debug/io-stats", "!client-log-level", NULL, DOC, 0}, {"performance.cache-max-file-size", "performance/io-cache", "max-file-size", NULL, DOC, 0}, {"performance.cache-min-file-size", "performance/io-cache", "min-file-size", NULL, DOC, 0}, @@ -143,8 +148,8 @@ static struct volopt_map_entry glusterd_volopt_map[] = { {"network.ping-timeout", "protocol/client", NULL, NULL, NO_DOC, 0 }, {"network.inode-lru-limit", "protocol/server", NULL, NULL, NO_DOC, 0 }, - {"auth.allow", "protocol/server", "!server-auth", "*", DOC, 0}, - {"auth.reject", "protocol/server", "!server-auth", NULL, DOC, 0}, + {"auth.allow", "protocol/server", "!auth.addr.*.allow", "*", DOC}, + {"auth.reject", "protocol/server", "!auth.addr.*.reject", NULL, DOC}, {"transport.keepalive", "protocol/server", "transport.socket.keepalive", NULL, NO_DOC, 0}, {"server.allow-insecure", "protocol/server", "rpc-auth-allow-insecure", NULL, NO_DOC, 0}, @@ -163,26 +168,26 @@ static struct volopt_map_entry glusterd_volopt_map[] = { {"nfs.export-dirs", "nfs/server", "nfs3.export-dirs", NULL, GLOBAL_DOC, 0}, {"nfs.export-volumes", "nfs/server", "nfs3.export-volumes", NULL, GLOBAL_DOC, 0}, {"nfs.addr-namelookup", "nfs/server", "rpc-auth.addr.namelookup", NULL, GLOBAL_DOC, 0}, - {"nfs.dynamic-volumes", "nfs/server", "nfs.dynamic-volumes", NULL, GLOBAL_DOC, 0}, + {"nfs.dynamic-volumes", "nfs/server", "nfs.dynamic-volumes", NULL, GLOBAL_NO_DOC, 0}, {"nfs.register-with-portmap", "nfs/server", "rpc.register-with-portmap", NULL, GLOBAL_DOC, 0}, {"nfs.port", "nfs/server", "nfs.port", NULL, GLOBAL_DOC, 0}, - {"nfs.rpc-auth-unix", "nfs/server", "!nfs.rpc-auth-auth-unix", NULL, DOC, 0}, - {"nfs.rpc-auth-null", "nfs/server", "!nfs.rpc-auth-auth-null", NULL, DOC, 0}, - {"nfs.rpc-auth-allow", "nfs/server", "!nfs.rpc-auth.addr.allow", NULL, DOC, 0}, - {"nfs.rpc-auth-reject", "nfs/server", "!nfs.rpc-auth.addr.reject", NULL, DOC, 0}, - {"nfs.ports-insecure", "nfs/server", "!nfs.auth.ports.insecure", NULL, DOC, 0}, + {"nfs.rpc-auth-unix", "nfs/server", "!rpc-auth.auth-unix.*", NULL, DOC, 0}, + {"nfs.rpc-auth-null", "nfs/server", "!rpc-auth.auth-null.*", NULL, DOC}, + {"nfs.rpc-auth-allow", "nfs/server", "!rpc-auth.addr.*.allow", NULL, DOC, 0}, + {"nfs.rpc-auth-reject", "nfs/server", "!rpc-auth.addr.*.reject", NULL, DOC, 0}, + {"nfs.ports-insecure", "nfs/server", "!rpc-auth.ports.*.insecure", NULL, DOC, 0}, {"nfs.transport-type", "nfs/server", "!nfs.transport-type", NULL, DOC, 0}, - {"nfs.trusted-sync", "nfs/server", "!nfs-trusted-sync", NULL, DOC, 0}, - {"nfs.trusted-write", "nfs/server", "!nfs-trusted-write", NULL, DOC, 0}, - {"nfs.volume-access", "nfs/server", "!nfs-volume-access", NULL, DOC, 0}, - {"nfs.export-dir", "nfs/server", "!nfs-export-dir", NULL, DOC, 0}, + {"nfs.trusted-sync", "nfs/server", "!nfs3.*.trusted-sync", NULL, DOC, 0}, + {"nfs.trusted-write", "nfs/server", "!nfs3.*.trusted-write", NULL, DOC, 0}, + {"nfs.volume-access", "nfs/server", "!nfs3.*.volume-access", NULL, DOC, 0}, + {"nfs.export-dir", "nfs/server", "!nfs3.*.export-dir", NULL, DOC, 0}, {"nfs.disable", "nfs/server", "!nfs-disable", NULL, DOC, 0}, {VKEY_FEATURES_QUOTA, "features/marker", "quota", "off", NO_DOC, OPT_FLAG_FORCE}, {VKEY_FEATURES_LIMIT_USAGE, "features/quota", "limit-set", NULL, NO_DOC, 0}, - {"features.quota-timeout", "features/quota", "timeout", "0", NO_DOC, 0}, + {"features.quota-timeout", "features/quota", "timeout", "0", DOC, 0}, {NULL, } }; @@ -1214,7 +1219,8 @@ server_auth_option_handler (volgen_graph_t *graph, int ret = 0; char *key = NULL; - if (strcmp (vme->option, "!server-auth") != 0) + if ( (strcmp (vme->option, "!auth.addr.*.allow") != 0) && + (strcmp (vme->option, "!auth.addr.*.reject") != 0)) return 0; xl = first_of (graph); @@ -1243,8 +1249,9 @@ loglevel_option_handler (volgen_graph_t *graph, char *role = param; struct volopt_map_entry vme2 = {0,}; - if (strcmp (vme->option, "!log-level") != 0 || - !strstr (vme->key, role)) + if ( (strcmp (vme->option, "!client-log-level") != 0 && + strcmp (vme->option, "!brick-log-level") != 0) + || !strstr (vme->key, role)) return 0; memcpy (&vme2, vme, sizeof (vme2)); @@ -1462,6 +1469,307 @@ perfxl_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, return -1; } +#if (HAVE_LIB_XML) +static int +end_sethelp_xml_doc (xmlTextWriterPtr writer) +{ + int ret = -1; + + ret = xmlTextWriterEndElement(writer); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not end an " + "xmlElemetnt"); + ret = -1; + goto out; + } + ret = xmlTextWriterEndDocument (writer); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not end an " + "xmlDocument"); + ret = -1; + goto out; + } + + ret = xmlTextWriterFlush (writer); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not flush an " + "xmlDocument"); + ret = -1; + goto out; + } + + + ret = 0; + out: + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + return ret; + +} + +static int +init_sethelp_xml_doc (xmlTextWriterPtr *writer, xmlBufferPtr *buf) +{ + int ret; + + *buf = xmlBufferCreateSize (16 * GF_UNIT_KB); + if (buf == NULL) { + gf_log ("glusterd", GF_LOG_ERROR, "Error creating the xml " + "buffer"); + ret = -1; + goto out; + } + + xmlBufferSetAllocationScheme (*buf,XML_BUFFER_ALLOC_DOUBLEIT); + + *writer = xmlNewTextWriterMemory(*buf, 0); + if (writer == NULL) { + gf_log ("glusterd", GF_LOG_ERROR, " Error creating the xml " + "writer"); + ret = -1; + goto out; + } + + ret = xmlTextWriterStartDocument(*writer, "1.0", "UTF-8", "yes"); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Error While starting the " + "xmlDoc"); + goto out; + } + + ret = xmlTextWriterStartElement(*writer, + (xmlChar *)"options"); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not create an " + "xmlElemetnt"); + ret = -1; + goto out; + } + + + ret = 0; + + out: + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + return ret; + +} + +static int +xml_add_volset_element (xmlTextWriterPtr writer, const char *name, + const char *def_val, const char *dscrpt) +{ + + int ret = -1; + + GF_ASSERT (name); + + ret = xmlTextWriterStartElement(writer, (xmlChar *) "option"); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not create an " + "xmlElemetnt"); + ret = -1; + goto out; + } + + ret = xmlTextWriterWriteFormatElement(writer, (xmlChar*)"defaultValue", + "%s", def_val); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not create an " + "xmlElemetnt"); + ret = -1; + goto out; + } + + ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"description", + "%s", dscrpt ); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not create an " + "xmlElemetnt"); + ret = -1; + goto out; + } + + ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *) "name", "%s", + name); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not create an " + "xmlElemetnt"); + ret = -1; + goto out; + } + + ret = xmlTextWriterEndElement(writer); + if (ret < 0) { + gf_log ("glusterd", GF_LOG_ERROR, "Could not end an " + "xmlElemetnt"); + ret = -1; + goto out; + } + + ret = 0; + out: + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + return ret; + +} + +#endif + +static int +get_key_from_volopt ( struct volopt_map_entry *vme, char **key) +{ + int ret = 0; + + GF_ASSERT (vme); + GF_ASSERT (key); + + + if (vme->option) { + if (vme->option[0] == '!') { + *key = vme->option + 1; + if (!*key[0]) + ret = -1; + } else { + *key = vme->option; + } + } else { + *key = strchr (vme->key, '.'); + if (*key) { + (*key) ++; + if (!*key[0]) + ret = -1; + } else { + ret = -1; + } + } + + if (ret) + gf_log ("glusterd", GF_LOG_ERROR, "Wrong entry found in " + "glusterd_volopt_map entry %s", vme->key); + else + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + + return ret; +} + + +int +glusterd_get_volopt_content (gf_boolean_t xml_out) +{ + + char *xlator_type = NULL; + void *dl_handle = NULL; + volume_opt_list_t vol_opt_handle; + volume_opt_list_t *vol_opt = NULL; + volume_opt_list_t *tmp = NULL; + char *key = NULL; + struct volopt_map_entry *vme = NULL; + int ret = -1; + char *def_val = NULL; + char *descr = NULL; + char output_string[8192] = {0, }; + char *output = NULL; + char tmp_str[1024] = {0, }; + dict_t *ctx = NULL; +#if (HAVE_LIB_XML) + xmlTextWriterPtr writer = NULL; + xmlBufferPtr buf = NULL; +#endif + + INIT_LIST_HEAD (&vol_opt_handle.list); + +#if (HAVE_LIB_XML) + if (xml_out) { + ret = init_sethelp_xml_doc (&writer, &buf); + if (ret) /*logging done in init_xml_lib*/ + goto out; + } +#endif + + ctx = glusterd_op_get_ctx (GD_OP_SET_VOLUME); + + if (!ctx) { + /*extract the vol-set-help output only in host glusterd*/ + ret = 0; + goto out; + } + + + for (vme = &glusterd_volopt_map[0]; vme->key; vme++) { + + if ( ( vme->type == NO_DOC) || (vme->type == GLOBAL_NO_DOC) ) + continue; + + if (get_key_from_volopt (vme, &key)) + goto out; /*Some error while getin key*/ + + if (!xlator_type || strcmp (vme->voltype, xlator_type)){ + ret = xlator_volopt_dynload (vme->voltype, + &dl_handle, + &vol_opt_handle); + if (ret) + continue; + } + + ret = xlator_get_volopt_info (&vol_opt_handle.list, key, + &def_val, &descr); + if (ret) /*Swallow Error i.e if option not found*/ + continue; + + if (xml_out) { +#if (HAVE_LIB_XML) + if (xml_add_volset_element (writer,vme->key, + def_val, descr)) + goto out; +#else + gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present"); +#endif + } else { + snprintf (tmp_str, 1024, "Option: %s\nDefault " + "Value: %s\nDescription: %s\n\n", + vme->key, def_val, descr); + strcat (output_string, tmp_str); + } + } + +#if (HAVE_LIB_XML) + if ((xml_out) && + (ret = end_sethelp_xml_doc (writer))) + goto out; +#else + if (xml_out) + gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present"); +#endif + + if (!xml_out) + output = gf_strdup (output_string); + else +#if (HAVE_LIB_XML) + output = gf_strdup ((char *)buf->content); + xmlFreeTextWriter (writer); + xmlBufferFree (buf); + +#else + gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present"); +#endif + + if (NULL == output) { + ret = -1; + goto out; + } + + ret = dict_set_dynstr (ctx, "help-str", output); + out: + list_for_each_entry_safe (vol_opt, tmp, &vol_opt_handle.list, list) { + list_del_init (&vol_opt->list); + GF_FREE (vol_opt); + } + + gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret); + return ret; + +} + static int client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, dict_t *set_dict, void *param) @@ -1650,7 +1958,7 @@ nfs_option_handler (volgen_graph_t *graph, if ( !volinfo || !volinfo->volname) return 0; - if (! strcmp (vme->option, "!nfs.rpc-auth-addr-allow")) { + if (! strcmp (vme->option, "!rpc-auth.addr.*.allow")) { ret = gf_asprintf (&aa, "rpc-auth.addr.%s.allow", volinfo->volname); @@ -1663,7 +1971,7 @@ nfs_option_handler (volgen_graph_t *graph, return -1; } - if (! strcmp (vme->option, "!nfs.rpc-auth-addr-reject")) { + if (! strcmp (vme->option, "!rpc-auth.addr.%s.reject")) { ret = gf_asprintf (&aa, "rpc-auth.addr.%s.reject", volinfo->volname); @@ -1676,7 +1984,7 @@ nfs_option_handler (volgen_graph_t *graph, return -1; } - if (! strcmp (vme->option, "!nfs.rpc-auth-auth-unix")) { + if (! strcmp (vme->option, "!rpc-auth.auth-unix.*")) { ret = gf_asprintf (&aa, "rpc-auth.auth.unix.%s", volinfo->volname); @@ -1688,7 +1996,7 @@ nfs_option_handler (volgen_graph_t *graph, if (ret) return -1; } - if (! strcmp (vme->option, "!nfs.rpc-auth-auth-null")) { + if (! strcmp (vme->option, "!rpc-auth.auth.null.*")) { ret = gf_asprintf (&aa, "rpc-auth.auth.null.%s", volinfo->volname); @@ -1701,7 +2009,7 @@ nfs_option_handler (volgen_graph_t *graph, return -1; } - if (! strcmp (vme->option, "!nfs-trusted-sync")) { + if (! strcmp (vme->option, "!nfs3.%s.trusted-sync")) { ret = gf_asprintf (&aa, "nfs3.%s.trusted-sync", volinfo->volname); @@ -1714,7 +2022,7 @@ nfs_option_handler (volgen_graph_t *graph, return -1; } - if (! strcmp (vme->option, "!nfs-trusted-write")) { + if (! strcmp (vme->option, "!nfs3.*.trusted-write")) { ret = gf_asprintf (&aa, "nfs3.%s.trusted-write", volinfo->volname); @@ -1727,7 +2035,7 @@ nfs_option_handler (volgen_graph_t *graph, return -1; } - if (! strcmp (vme->option, "!nfs-volume-access")) { + if (! strcmp (vme->option, "!nfs3.*.volume-access")) { ret = gf_asprintf (&aa, "nfs3.%s.volume-access", volinfo->volname); @@ -1740,7 +2048,7 @@ nfs_option_handler (volgen_graph_t *graph, return -1; } - if (! strcmp (vme->option, "!nfs-export-dir")) { + if (! strcmp (vme->option, "!nfs3.*.export-dir")) { ret = gf_asprintf (&aa, "nfs3.%s.export-dir", volinfo->volname); @@ -1755,7 +2063,7 @@ nfs_option_handler (volgen_graph_t *graph, - if (! strcmp (vme->option, "!nfs.ports-insecure")) { + if (! strcmp (vme->option, "!rpc-auth.ports.*.insecure")) { ret = gf_asprintf (&aa, "rpc-auth.ports.%s.insecure", volinfo->volname); diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.h b/xlators/mgmt/glusterd/src/glusterd-volgen.h index 2333be5f1..71aeecfc4 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -66,4 +66,6 @@ glusterd_check_voloption_flags (char *key, int32_t flags); int generate_brick_volfiles (glusterd_volinfo_t *volinfo); char* glusterd_get_trans_type_rb (gf_transport_type ttype); +int glusterd_get_volopt_content (gf_boolean_t xml_out); + #endif diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index fe173e26d..2495c6ecb 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -474,6 +474,7 @@ nfs_init_state (xlator_t *this) unsigned int fopspoolsize = 0; char *optstr = NULL; gf_boolean_t boolt = _gf_false; + char *def_val = NULL; if (!this) return NULL; @@ -498,7 +499,21 @@ nfs_init_state (xlator_t *this) goto free_nfs; } - nfs->memfactor = GF_NFS_DEFAULT_MEMFACTOR; + if (xlator_get_volopt_info (&this->volume_options, "nfs.mem-factor", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "nfs.mem-factor not found"); + ret = -1; + goto free_rpcsvc; + } else { + if (gf_string2uint (def_val, &nfs->memfactor)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "nfs.mem-factor corrupt"); + ret = -1; + goto free_rpcsvc; + } + } + if (dict_get (this->options, "nfs.mem-factor")) { ret = dict_get_str (this->options, "nfs.mem-factor", &optstr); @@ -544,7 +559,21 @@ nfs_init_state (xlator_t *this) nfs->dynamicvolumes = GF_NFS_DVM_ON; } - nfs->enable_ino32 = 0; + if (xlator_get_volopt_info (&this->volume_options, "nfs.enable-ino32", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "nfs.enable-ino32 not found"); + ret = -1; + goto free_foppool; + } else { + if (gf_string2boolean (def_val,(gf_boolean_t *) &nfs->enable_ino32 )) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "nfs.enable-ino32 corrupt"); + ret = -1; + goto free_foppool; + } + } + if (dict_get (this->options, "nfs.enable-ino32")) { ret = dict_get_str (this->options, "nfs.enable-ino32", &optstr); @@ -750,11 +779,13 @@ struct volume_options options[] = { { .key = {"nfs3.*.volume-access"}, .type = GF_OPTION_TYPE_STR, .value = {"read-only", "read-write"}, + .default_value = "read-write", .description = "Type of access desired for this subvolume: " " read-only, read-write(default)" }, { .key = {"nfs3.*.trusted-write"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "On an UNSTABLE write from client, return STABLE flag" " to force client to not send a COMMIT request. In " "some environments, combined with a replicated " @@ -769,15 +800,17 @@ struct volume_options options[] = { }, { .key = {"nfs3.*.trusted-sync"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "All writes and COMMIT requests are treated as async." " This implies that no write requests are guaranteed" " to be on server disks when the write reply is " - "received at the NFS client. Trusted sync includes " + "received at the NFS client. Trusted sync includes" " trusted-write behaviour. Off by default." }, { .key = {"nfs3.*.export-dir"}, .type = GF_OPTION_TYPE_STR, + .default_value = "", .description = "By default, all subvolumes of nfs are exported as " "individual exports. There are cases where a " "subdirectory or subdirectories in the volume need to " @@ -788,6 +821,7 @@ struct volume_options options[] = { }, { .key = {"nfs3.export-dirs"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "By default, all subvolumes of nfs are exported as " "individual exports. There are cases where a " "subdirectory or subdirectories in the volume need to " @@ -797,6 +831,7 @@ struct volume_options options[] = { }, { .key = {"nfs3.export-volumes"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Enable or disable exporting whole volumes, instead " "if used in conjunction with nfs3.export-dir, can " "allow setting up only subdirectories as exports. On " @@ -804,6 +839,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.auth-unix"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "", .description = "Disable or enable the AUTH_UNIX authentication type." "Must always be enabled for better interoperability." "However, can be disabled if needed. Enabled by" @@ -811,12 +847,14 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.auth-null"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "", .description = "Disable or enable the AUTH_NULL authentication type." "Must always be enabled. This option is here only to" " avoid unrecognized option warnings" }, { .key = {"rpc-auth.auth-unix.*"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Disable or enable the AUTH_UNIX authentication type " "for a particular exported volume over-riding defaults" " and general setting for AUTH_UNIX scheme. Must " @@ -826,6 +864,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.auth-null.*"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "", .description = "Disable or enable the AUTH_NULL authentication type " "for a particular exported volume over-riding defaults" " and general setting for AUTH_NULL. Must always be " @@ -834,6 +873,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.allow"}, .type = GF_OPTION_TYPE_STR, + .default_value = "", .description = "Allow a comma separated list of addresses and/or" " hostnames to connect to the server. By default, all" " connections are disallowed. This allows users to " @@ -841,13 +881,15 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.reject"}, .type = GF_OPTION_TYPE_STR, + .default_value = "", .description = "Reject a comma separated list of addresses and/or" " hostnames from connecting to the server. By default," " all connections are disallowed. This allows users to" - "define a general rule for all exported volumes." + " define a general rule for all exported volumes." }, { .key = {"rpc-auth.addr.*.allow"}, .type = GF_OPTION_TYPE_STR, + .default_value = "", .description = "Allow a comma separated list of addresses and/or" " hostnames to connect to the server. By default, all" " connections are disallowed. This allows users to " @@ -855,13 +897,15 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.*.reject"}, .type = GF_OPTION_TYPE_STR, + .default_value = "", .description = "Reject a comma separated list of addresses and/or" " hostnames from connecting to the server. By default," " all connections are disallowed. This allows users to" - "define a rule for a specific exported volume." + " define a rule for a specific exported volume." }, { .key = {"rpc-auth.ports.insecure"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "Allow client connections from unprivileged ports. By " "default only privileged ports are allowed. This is a" "global setting in case insecure ports are to be " @@ -869,6 +913,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.ports.*.insecure"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "", .description = "Allow client connections from unprivileged ports. By " "default only privileged ports are allowed. Use this" " option to set enable or disable insecure ports for " @@ -877,6 +922,7 @@ struct volume_options options[] = { }, { .key = {"rpc-auth.addr.namelookup"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "Users have the option of turning off name lookup for" " incoming client connections using this option. In some " "setups, the name server can take too long to reply to DNS " @@ -902,6 +948,7 @@ struct volume_options options[] = { }, { .key = {"nfs.enable-ino32"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", .description = "For nfs clients or apps that do not support 64-bit " "inode numbers, use this option to make NFS return " "32-bit inode numbers instead. Disabled by default so " @@ -909,6 +956,7 @@ struct volume_options options[] = { }, { .key = {"rpc.register-with-portmap"}, .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", .description = "For systems that need to run multiple nfs servers, we" "need to prevent more than one from registering with " "portmap service. Use this option to turn off portmap " @@ -916,11 +964,13 @@ struct volume_options options[] = { }, { .key = {"nfs.port"}, .type = GF_OPTION_TYPE_INT, + .default_value = "", .description = "Use this option on systems that need Gluster NFS to " "be associated with a non-default port number." }, { .key = {"nfs.mem-factor"}, .type = GF_OPTION_TYPE_INT, + .default_value = "15", .description = "Use this option to make NFS be faster on systems by " "using more memory. This option specifies a multiple " "that determines the total amount of memory used. " @@ -929,11 +979,23 @@ struct volume_options options[] = { "Please consult gluster-users list before using this " "option." }, - { .key = {"nfs.*.disable"}, + /* XXX These are synthetic options used to validate the options in * + * during volume set command and also to get visibiliity in * + * volume set help command */ + { .key = {"nfs-disable"}, .type = GF_OPTION_TYPE_BOOL, - .description = "This option is used to start or stop NFS server" + .default_value = "off", + .description = "This option is used to enable/disable NFS server " "for individual volume." }, + { + .key = {"nfs.transport-type"}, + .type = GF_OPTION_TYPE_STR, + .default_value = "", + .description = "This options is used to change the transport type of" + " NFS Server.", + }, + { .key = {NULL} }, }; diff --git a/xlators/performance/io-cache/src/io-cache.c b/xlators/performance/io-cache/src/io-cache.c index 6853558ca..230842389 100644 --- a/xlators/performance/io-cache/src/io-cache.c +++ b/xlators/performance/io-cache/src/io-cache.c @@ -40,6 +40,7 @@ ioc_get_priority (ioc_table_t *table, const char *path); uint32_t ioc_get_priority (ioc_table_t *table, const char *path); +struct volume_options options[]; inline uint32_t ioc_hashfn (void *data, int len) @@ -1719,14 +1720,15 @@ int32_t init (xlator_t *this) { ioc_table_t *table = NULL; - dict_t *options = NULL; + dict_t *xl_options = this->options; uint32_t index = 0; char *cache_size_string = NULL, *tmp = NULL; int32_t ret = -1; glusterfs_ctx_t *ctx = NULL; data_t *data = 0; + char *def_val = NULL; - options = this->options; + xl_options = this->options; if (!this->children || this->children->next) { gf_log (this->name, GF_LOG_ERROR, @@ -1750,7 +1752,22 @@ init (xlator_t *this) table->page_size = this->ctx->page_size; table->cache_size = IOC_CACHE_SIZE; - data = dict_get (options, "cache-size"); + if (xlator_get_volopt_info (&this->volume_options, "cache-size", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of cache-size " + "not found"); + ret = -1; + goto out; + } else { + if (gf_string2bytesize (def_val, &table->cache_size)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-size corrupt"); + ret = -1; + goto out; + } + } + + data = dict_get (xl_options, "cache-size"); if (data) cache_size_string = data_to_str (data); @@ -1768,9 +1785,23 @@ init (xlator_t *this) "using cache-size %"PRIu64"", table->cache_size); } - table->cache_timeout = 1; + if (xlator_get_volopt_info (&this->volume_options, "cache-timeout", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-timeout not found"); + ret = -1; + goto out; + } else { + if (gf_string2int32 (def_val, &table->cache_timeout)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-timeout corrupt"); + ret = -1; + goto out; + } + } + - data = dict_get (options, "cache-timeout"); + data = dict_get (xl_options, "cache-timeout"); if (data) { table->cache_timeout = data_to_uint32 (data); gf_log (this->name, GF_LOG_TRACE, @@ -1780,7 +1811,7 @@ init (xlator_t *this) INIT_LIST_HEAD (&table->priority_list); table->max_pri = 1; - data = dict_get (options, "priority"); + data = dict_get (xl_options, "priority"); if (data) { char *option_list = data_to_str (data); gf_log (this->name, GF_LOG_TRACE, @@ -1795,9 +1826,24 @@ init (xlator_t *this) } table->max_pri ++; - table->min_file_size = 0; + if (xlator_get_volopt_info (&this->volume_options, "min-file-size", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "min-file-size not found"); + ret = -1; + goto out; + } else { + if (gf_string2bytesize (def_val, + (uint64_t *) &table->min_file_size)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "min-file-size corrupt"); + ret = -1; + goto out; + } + } + - data = dict_get (options, "min-file-size"); + data = dict_get (xl_options, "min-file-size"); if (data) tmp = data_to_str (data); @@ -1815,9 +1861,24 @@ init (xlator_t *this) "using min-file-size %"PRIu64"", table->min_file_size); } + if (xlator_get_volopt_info (&this->volume_options, "max-file-size", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "max-file-size not found"); + ret = -1; + goto out; + } else { + if (gf_string2bytesize (def_val, + (uint64_t *) &table->max_file_size)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "max-file-size corrupt"); + ret = -1; + goto out; + } + } + tmp = NULL; - table->max_file_size = -1; - data = dict_get (options, "max-file-size"); + data = dict_get (xl_options, "max-file-size"); if (data) tmp = data_to_str (data); @@ -1954,23 +2015,40 @@ struct xlator_cbks cbks = { struct volume_options options[] = { { .key = {"priority"}, - .type = GF_OPTION_TYPE_ANY + .type = GF_OPTION_TYPE_ANY, + .default_value = "", + .description = "Assigns priority to filenames with specific " + "patterns so that when a page needs to be ejected " + "out of the cache, the page of a file whose " + "priority is the lowest will be ejected earlier" }, { .key = {"cache-timeout", "force-revalidate-timeout"}, .type = GF_OPTION_TYPE_INT, .min = 0, - .max = 60 + .max = 60, + .default_value = "1", + .description = "The cached data for a file will be retained till " + "'cache-refresh-timeout' seconds, after which data " + "re-validation is performed." }, { .key = {"cache-size"}, .type = GF_OPTION_TYPE_SIZET, .min = 4 * GF_UNIT_MB, - .max = 6 * GF_UNIT_GB + .max = 6 * GF_UNIT_GB, + .default_value = "32MB", + .description = "Size of the read cache." }, { .key = {"min-file-size"}, .type = GF_OPTION_TYPE_SIZET, + .default_value = "0", + .description = "Minimum file size which would be cached by the " + "io-cache translator." }, { .key = {"max-file-size"}, .type = GF_OPTION_TYPE_SIZET, + .default_value = "0", + .description = "Maximum file size which would be cached by the " + "io-cache translator." }, { .key = {NULL} }, }; diff --git a/xlators/performance/io-threads/src/io-threads.c b/xlators/performance/io-threads/src/io-threads.c index 83a7d40aa..a19a14f0f 100644 --- a/xlators/performance/io-threads/src/io-threads.c +++ b/xlators/performance/io-threads/src/io-threads.c @@ -36,7 +36,7 @@ void *iot_worker (void *arg); int iot_workers_scale (iot_conf_t *conf); int __iot_workers_scale (iot_conf_t *conf); - +struct volume_options options[]; call_stub_t * __iot_dequeue (iot_conf_t *conf) @@ -2157,11 +2157,12 @@ int init (xlator_t *this) { iot_conf_t *conf = NULL; - dict_t *options = this->options; + dict_t *xl_options = this->options; int thread_count = IOT_DEFAULT_THREADS; int idle_time = IOT_DEFAULT_IDLE; int ret = -1; int i = 0; + char *def_val = NULL; if (!this->children || this->children->next) { gf_log ("io-threads", GF_LOG_ERROR, @@ -2196,10 +2197,23 @@ init (xlator_t *this) set_stack_size (conf); - thread_count = IOT_DEFAULT_THREADS; + if (xlator_get_volopt_info (&this->volume_options, "thread-count", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "thread-count not found"); + ret = -1; + goto out; + } else { + if (gf_string2int32 (def_val, &conf->max_count)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "thread corrupt"); + ret = -1; + goto out; + } + } - if (dict_get (options, "thread-count")) { - thread_count = data_to_int32 (dict_get (options, + if (dict_get (xl_options, "thread-count")) { + thread_count = data_to_int32 (dict_get (xl_options, "thread-count")); if (thread_count < IOT_MIN_THREADS) { gf_log ("io-threads", GF_LOG_WARNING, @@ -2216,8 +2230,8 @@ init (xlator_t *this) } conf->max_count = thread_count; - if (dict_get (options, "idle-time")) { - idle_time = data_to_int32 (dict_get (options, + if (dict_get (xl_options, "idle-time")) { + idle_time = data_to_int32 (dict_get (xl_options, "idle-time")); if (idle_time < 0) idle_time = 1; @@ -2304,7 +2318,11 @@ struct volume_options options[] = { { .key = {"thread-count"}, .type = GF_OPTION_TYPE_INT, .min = IOT_MIN_THREADS, - .max = IOT_MAX_THREADS + .max = IOT_MAX_THREADS, + .default_value = "16", + .description = "Number of threads in IO threads translator which " + "perform concurrent IO operations" + }, {.key = {"idle-time"}, .type = GF_OPTION_TYPE_INT, diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c index d04ea4fc6..d0fbdb050 100644 --- a/xlators/performance/quick-read/src/quick-read.c +++ b/xlators/performance/quick-read/src/quick-read.c @@ -22,6 +22,8 @@ #define QR_DEFAULT_CACHE_SIZE 134217728 +struct volume_options options[]; + void qr_local_free (qr_local_t *local) { @@ -3477,6 +3479,7 @@ init (xlator_t *this) int32_t ret = -1, i = 0; qr_private_t *priv = NULL; qr_conf_t *conf = NULL; + char *def_val = NULL; if (!this->children || this->children->next) { gf_log (this->name, GF_LOG_ERROR, @@ -3526,7 +3529,21 @@ init (xlator_t *this) } } - conf->cache_size = QR_DEFAULT_CACHE_SIZE; + if (xlator_get_volopt_info (&this->volume_options, "cache-size", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-size not found"); + ret = -1; + goto out; + } else { + if (gf_string2bytesize (def_val, &conf->cache_size)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-size corrupt"); + ret = -1; + goto out; + } + } + ret = dict_get_str (this->options, "cache-size", &str); if (ret == 0) { ret = gf_string2bytesize (str, &conf->cache_size); @@ -3618,6 +3635,8 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_SIZET, .min = 0, .max = 6 * GF_UNIT_GB, + .default_value = "128MB", + .description = "Size of the read cache." }, { .key = {"cache-timeout"}, .type = GF_OPTION_TYPE_INT, diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 47911d8a1..1a8bfe7df 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -2977,6 +2977,7 @@ init (xlator_t *this) wb_conf_t *conf = NULL; char *str = NULL; int32_t ret = -1; + char *def_val = NULL; if ((this->children == NULL) || this->children->next) { @@ -3029,7 +3030,21 @@ init (xlator_t *this) conf->disable_till); /* configure 'option window-size ' */ - conf->window_size = WB_WINDOW_SIZE; + if (xlator_get_volopt_info (&this->volume_options, "cache-size", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-size not found"); + ret = -1; + goto out; + } else { + if (gf_string2bytesize (def_val, &conf->window_size)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-size corrupt"); + ret = -1; + goto out; + } + } + ret = dict_get_str (options, "cache-size", &str); if (ret == 0) { ret = gf_string2bytesize (str, &conf->window_size); @@ -3060,7 +3075,22 @@ init (xlator_t *this) } /* configure 'option flush-behind ' */ - conf->flush_behind = 1; + + if (xlator_get_volopt_info (&this->volume_options, "flush-behind", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-size not found"); + ret = -1; + goto out; + } else { + if (gf_string2boolean (def_val, &conf->flush_behind)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "cache-size corrupt"); + ret = -1; + goto out; + } + } + ret = dict_get_str (options, "flush-behind", &str); if (ret == 0) { ret = gf_string2boolean (str, &conf->flush_behind); @@ -3141,12 +3171,21 @@ struct xlator_dumpops dumpops = { struct volume_options options[] = { { .key = {"flush-behind"}, - .type = GF_OPTION_TYPE_BOOL + .type = GF_OPTION_TYPE_BOOL, + .default_value = "on", + .description = "If this option is set ON, instructs write-behind " + "translator to perform flush in background, by " + "returning success (or any errors, if any of " + "previous writes were failed) to application even " + "before flush is sent to backend filesystem. " }, { .key = {"cache-size", "window-size"}, .type = GF_OPTION_TYPE_SIZET, .min = 512 * GF_UNIT_KB, - .max = 1 * GF_UNIT_GB + .max = 1 * GF_UNIT_GB, + .default_value = "1MB", + .description = "Size of the per-file write-behind buffer. " + }, { .key = {"disable-for-first-nbytes"}, .type = GF_OPTION_TYPE_SIZET, diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 96f3ac1fa..7f8301be8 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -1953,21 +1953,33 @@ notify (xlator_t *this, int32_t event, void *data, ...) int build_client_config (xlator_t *this, clnt_conf_t *conf) { - int ret = -1; + int ret = -1; + char *def_val = NULL; if (!conf) goto out; + if (xlator_get_volopt_info (&this->volume_options, "frame-timeout", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "frame-timeout not found"); + ret = -1; + goto out; + } else { + if (gf_string2int32 (def_val, &conf->rpc_conf.rpc_timeout)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "frame-timeout corrupt"); + ret = -1; + goto out; + } + } + ret = dict_get_int32 (this->options, "frame-timeout", &conf->rpc_conf.rpc_timeout); if (ret >= 0) { gf_log (this->name, GF_LOG_INFO, "setting frame-timeout to %d", conf->rpc_conf.rpc_timeout); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "defaulting frame-timeout to 30mins"); - conf->rpc_conf.rpc_timeout = 1800; } ret = dict_get_int32 (this->options, "remote-port", @@ -1980,15 +1992,26 @@ build_client_config (xlator_t *this, clnt_conf_t *conf) "defaulting remote-port to 'auto'"); } + if (xlator_get_volopt_info (&this->volume_options, "ping-timeout", + &def_val, NULL)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "ping-timeout not found"); + ret = -1; + goto out; + } else { + if (gf_string2int32 (def_val, &conf->opt.ping_timeout)) { + gf_log (this->name, GF_LOG_ERROR, "Default value of " + "ping-timeout corrupt"); + ret = -1; + goto out; + } + } + ret = dict_get_int32 (this->options, "ping-timeout", &conf->opt.ping_timeout); if (ret >= 0) { gf_log (this->name, GF_LOG_INFO, "setting ping-timeout to %d", conf->opt.ping_timeout); - } else { - gf_log (this->name, GF_LOG_DEBUG, - "defaulting ping-timeout to 42"); - conf->opt.ping_timeout = GF_UNIVERSAL_ANSWER; } ret = dict_get_str (this->options, "remote-subvolume", @@ -2482,11 +2505,18 @@ struct volume_options options[] = { .type = GF_OPTION_TYPE_TIME, .min = 0, .max = 86400, + .default_value = "1800", + .description = "Time frame after which the (file) operation would be " + "declared as dead, if the server does not respond for " + "a particular (file) operation." }, { .key = {"ping-timeout"}, .type = GF_OPTION_TYPE_TIME, .min = 1, .max = 1013, + .default_value = "42", + .description = "Time duration for which the client waits to " + "check if the server is responsive." }, { .key = {"client-bind-insecure"}, .type = GF_OPTION_TYPE_BOOL diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 90ebed003..5ce5c3e51 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -857,5 +857,23 @@ struct volume_options options[] = { { .key = {"rpc-auth-allow-insecure"}, .type = GF_OPTION_TYPE_BOOL, }, + + /* XXX These are synthetic options which are actually recognized and * + * validated in addr.c, added here to get visibiliity in * + * volume set help/help-xml */ + + { .key = {"auth.addr.*.allow"}, + .type = GF_OPTION_TYPE_ANY, + .default_value = "*", + .description = "'IP addresses/Host name' of the clients which should" + " be allowed to access the the volume." + }, + { .key = {"auth.addr.*.reject"}, + .type = GF_OPTION_TYPE_ANY, + .default_value = "", + .description = "'IP addresses/Host name' of the clients which should" + " be denied to access the volume." + }, + { .key = {NULL} }, }; -- cgit