From: Dan Mick Date: Thu, 30 May 2013 23:32:30 +0000 (-0700) Subject: librados, rados.py: add conf_parse_argv_remainder() X-Git-Tag: v0.65~136^2^2~38 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=065b29cdd90bc8e07601e39d57aa4cba2ce3447c;p=ceph.git librados, rados.py: add conf_parse_argv_remainder() New parsing function to extract any known arguments from a vector and return any unknowns; useful for ceph CLI to allow librados first dibs on arguments so it doesn't have to reproduce the argument recognition Signed-off-by: Dan Mick --- diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index c0d8f9f6c2d..d22f3a13ff8 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -298,6 +298,22 @@ int rados_conf_read_file(rados_t cluster, const char *path); */ int rados_conf_parse_argv(rados_t cluster, int argc, const char **argv); + +/** + * Configure the cluster handle with command line arguments, returning + * any remainders. Same rados_conf_parse_argv, except for extra + * remargv argument to hold returns unrecognized arguments. + * + * @pre rados_connect() has not been called on the cluster handle + * + * @param cluster cluster handle to configure + * @param argc number of arguments in argv + * @param argv arguments to parse + * @param remargv char* array for returned unrecognized arguments + * @returns 0 on success, negative error code on failure + */ +int rados_conf_parse_argv_remainder(rados_t cluster, int argc, + const char **argv, const char **remargv); /** * Configure the cluster handle based on an environment variable * diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index af14a183b49..fc837c6c15f 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -655,6 +655,8 @@ namespace librados void shutdown(); int conf_read_file(const char * const path) const; int conf_parse_argv(int argc, const char ** argv) const; + int conf_parse_argv_remainder(int argc, const char ** argv, + const char ** remargv) const; int conf_parse_env(const char *env) const; int conf_set(const char *option, const char *value); int conf_get(const char *option, std::string &val); diff --git a/src/librados/librados.cc b/src/librados/librados.cc index c8b768bc271..6a100761d95 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -1244,6 +1244,12 @@ int librados::Rados::conf_parse_argv(int argc, const char ** argv) const return rados_conf_parse_argv((rados_t)client, argc, argv); } +int librados::Rados::conf_parse_argv_remainder(int argc, const char ** argv, + const char ** remargv) const +{ + return rados_conf_parse_argv_remainder((rados_t)client, argc, argv, remargv); +} + int librados::Rados::conf_parse_env(const char *name) const { return rados_conf_parse_env((rados_t)client, name); @@ -1546,6 +1552,35 @@ extern "C" int rados_conf_parse_argv(rados_t cluster, int argc, const char **arg return 0; } +// like above, but return the remainder of argv to contain remaining +// unparsed args. Must be allocated to at least argc by caller. +// remargv will contain n <= argc pointers to original argv[], the end +// of which may be NULL + +extern "C" int rados_conf_parse_argv_remainder(rados_t cluster, int argc, + const char **argv, + const char **remargv) +{ + librados::RadosClient *client = (librados::RadosClient *)cluster; + md_config_t *conf = client->cct->_conf; + vector args; + for (int i=0; iparse_argv(args); + if (ret) + return ret; + conf->apply_changes(NULL); + assert(args.size() <= (unsigned int)argc); + unsigned int i; + for (i = 0; i < argc; ++i) { + if (i < args.size()) + remargv[i] = args[i]; + else + remargv[i] = (const char *)NULL; + } + return 0; +} + extern "C" int rados_conf_parse_env(rados_t cluster, const char *env) { librados::RadosClient *client = (librados::RadosClient *)cluster; diff --git a/src/pybind/rados.py b/src/pybind/rados.py index 6b23fd208e4..7602aebb474 100644 --- a/src/pybind/rados.py +++ b/src/pybind/rados.py @@ -252,6 +252,29 @@ Rados object in state %s." % (self.state)) if (ret != 0): raise make_ex(ret, "error calling conf_read_file") + def conf_parse_argv(self, args): + """ + Parse known arguments from args, and remove; returned + args contain only those unknown to ceph + """ + self.require_state("configuring", "connected") + if not args: + return + # create instances of arrays of c_char_p's, both len(args) long + # cretargs will always be a subset of cargs (perhaps identical) + cargs = (c_char_p * len(args))(*args) + cretargs = (c_char_p * len(args))() + ret = run_in_thread(self.librados.rados_conf_parse_argv_remainder, + (self.cluster, len(args), cargs, cretargs)) + if ret: + raise make_ex("error calling conf_parse_argv_remainder") + + # cretargs was allocated with fixed length; collapse return + # list to eliminate any missing args + + retargs = [a for a in cretargs if a is not None] + return retargs + def conf_get(self, option): """ Get the value of a configuration option