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 <dan.mick@inktank.com>
This commit is contained in:
Dan Mick 2013-05-30 16:32:30 -07:00
parent 73a1b21692
commit 065b29cdd9
4 changed files with 76 additions and 0 deletions

View File

@ -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
*

View File

@ -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);

View File

@ -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<const char*> args;
for (int i=0; i<argc; i++)
args.push_back(argv[i]);
int ret = conf->parse_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;

View File

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