From 1d0cb953bb117689fb8381d65932ead486d13b05 Mon Sep 17 00:00:00 2001 From: Kaushik BV Date: Tue, 12 Jul 2011 05:33:29 +0000 Subject: mgmt/Glusterd: Implementation volume set help/help-xml Signed-off-by: Kaushik BV Signed-off-by: Anand Avati BUG: 2041 (volume set help option) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2041 --- cli/src/cli-cmd-parser.c | 8 +- cli/src/cli-rpc-ops.c | 19 +- configure.ac | 10 + libglusterfs/src/xlator.c | 105 +++++++++ libglusterfs/src/xlator.h | 8 +- 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 | 331 +++++++++++++++++++++++++-- xlators/mgmt/glusterd/src/glusterd-volgen.h | 1 + 11 files changed, 545 insertions(+), 66 deletions(-) diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 2c1897550ec..a8aebaeb03c 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -657,7 +657,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]; @@ -666,6 +666,12 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options) ret = dict_set_str (dict, "volname", volname); + 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; diff --git a/cli/src/cli-rpc-ops.c b/cli/src/cli-rpc-ops.c index 5b1f7f62993..92e5a32cc44 100644 --- a/cli/src/cli-rpc-ops.c +++ b/cli/src/cli-rpc-ops.c @@ -984,6 +984,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; @@ -999,9 +1001,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 (help_str); ret = rsp.op_ret; diff --git a/configure.ac b/configure.ac index 8e2fbb1dffa..a0112e0e985 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,5 @@ dnl Copyright (c) 2006-2010 Gluster, Inc. + dnl This file is part of GlusterFS. dnl dnl GlusterFS is free software; you can redistribute it and/or modify @@ -323,6 +324,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 9b91729ecae..ccc32b71118 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -1178,7 +1178,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; + + INIT_LIST_HEAD (&opt_list->list); + + 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_tail (&vol_opt->list, &opt_list->list); + + ret = 0; + out: + gf_log ("xlator", GF_LOG_DEBUG, "Returning %d", ret); + return ret; + +} int32_t xlator_dynload (xlator_t *xl) @@ -1853,3 +1910,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 60fd777614a..23fb3192ab1 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/mgmt/glusterd/src/Makefile.am b/xlators/mgmt/glusterd/src/Makefile.am index 1c89dba9776..714b78e6244 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 5f2460d5ee9..8acd85cc378 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -1938,18 +1938,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 831e6bbdc40..83f64bf9d26 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -1345,6 +1345,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) { @@ -1353,7 +1386,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); @@ -1369,27 +1401,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); @@ -5608,6 +5619,25 @@ glusterd_op_log_level (dict_t *dict) return ret; } +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) { @@ -5623,7 +5653,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); @@ -5631,8 +5662,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; @@ -5711,7 +5755,6 @@ glusterd_op_set_volume (dict_t *dict) } } - if ( count == 1 ) { gf_log ("", GF_LOG_ERROR, "No options received "); ret = -1; @@ -5782,11 +5825,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 6dc6be593ff..b7d800ffcdc 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 fc4ffa8c31b..ad8b610cc59 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" @@ -122,8 +127,9 @@ 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}, {"diagnostics.brick-sys-log-level", "debug/io-stats", "!sys-log-level", NULL, DOC, 0}, {"diagnostics.client-sys-log-level", "debug/io-stats", "!sys-log-level", NULL, DOC, 0}, @@ -166,26 +172,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, 0}, + {"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, } }; @@ -1225,8 +1231,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)); @@ -1532,6 +1539,282 @@ 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 = 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 (8192); + 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 *)"volumeOptionsDefaults"); + 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 *) "volumeOption"); + 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; + 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; + + 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); +#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: + 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) @@ -1762,7 +2045,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); @@ -1775,7 +2058,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); @@ -1788,7 +2071,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); @@ -1800,7 +2083,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); @@ -1813,7 +2096,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); @@ -1826,7 +2109,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); @@ -1839,7 +2122,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); @@ -1852,7 +2135,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); @@ -1867,7 +2150,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 b98b399dfff..f06655312b7 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volgen.h +++ b/xlators/mgmt/glusterd/src/glusterd-volgen.h @@ -65,5 +65,6 @@ glusterd_check_voloption_flags (char *key, int32_t flags); gf_boolean_t glusterd_is_valid_volfpath (char *volname, char *brick); int generate_brick_volfiles (glusterd_volinfo_t *volinfo); +int glusterd_get_volopt_content (gf_boolean_t xml_out); #endif -- cgit