summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Mick <dan.mick@inktank.com>2013-07-30 20:53:57 -0700
committerSage Weil <sage@inktank.com>2013-07-30 22:28:36 -0700
commit47d0d64d5c36c5b1192032438f141f88490fc26c (patch)
tree503921b60ed1648a05de0251904adb27c292b3af
parent736d6a1bde71919f7469218684c12793a9532aeb (diff)
downloadceph-47d0d64d5c36c5b1192032438f141f88490fc26c.tar.gz
Make all AdminSocket commands use argparse/cmdmap.
Fixes regression in daemon commands with arguments; also resolves reported bug with existing daemon code for arguments with embedded spaces. Fixes: #5503 Fixes: #5800 Signed-off-by: Dan Mick <dan.mick@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/client/Client.cc2
-rw-r--r--src/client/Client.h3
-rw-r--r--src/common/admin_socket.cc8
-rw-r--r--src/common/admin_socket.h3
-rw-r--r--src/common/ceph_context.cc58
-rw-r--r--src/common/ceph_context.h3
-rw-r--r--src/common/cmdparse.h3
-rw-r--r--src/mon/Monitor.cc37
-rw-r--r--src/mon/Monitor.h4
-rw-r--r--src/osd/OSD.cc111
-rw-r--r--src/osd/OSD.h2
-rw-r--r--src/osdc/Objecter.cc2
-rw-r--r--src/osdc/Objecter.h2
-rw-r--r--src/test/admin_socket.cc40
14 files changed, 159 insertions, 119 deletions
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 5a9c5fdafcc..af465cb78bc 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -102,7 +102,7 @@ Client::CommandHook::CommandHook(Client *client) :
{
}
-bool Client::CommandHook::call(std::string command, std::string args,
+bool Client::CommandHook::call(std::string command, cmdmap_t& cmdmap,
std::string format, bufferlist& out)
{
stringstream ss;
diff --git a/src/client/Client.h b/src/client/Client.h
index bc1fbc0401b..1117ff3b0af 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -45,6 +45,7 @@ using namespace __gnu_cxx;
#include "common/Finisher.h"
#include "common/compiler_extensions.h"
+#include "common/cmdparse.h"
#include "osdc/ObjectCacher.h"
@@ -196,7 +197,7 @@ class Client : public Dispatcher {
Client *m_client;
public:
CommandHook(Client *client);
- bool call(std::string command, std::string args, std::string format,
+ bool call(std::string command, cmdmap_t &cmdmap, std::string format,
bufferlist& out);
};
CommandHook m_command_hook;
diff --git a/src/common/admin_socket.cc b/src/common/admin_socket.cc
index e73f3ce0a0c..1a507e606bf 100644
--- a/src/common/admin_socket.cc
+++ b/src/common/admin_socket.cc
@@ -353,7 +353,7 @@ bool AdminSocket::do_accept()
string args;
if (match != c)
args = c.substr(match.length() + 1);
- bool success = p->second->call(match, args, format, out);
+ bool success = p->second->call(match, cmdmap, format, out);
if (!success) {
ldout(m_cct, 0) << "AdminSocket: request '" << match << "' args '" << args
<< "' to " << p->second << " failed" << dendl;
@@ -417,7 +417,7 @@ int AdminSocket::unregister_command(std::string command)
class VersionHook : public AdminSocketHook {
public:
- virtual bool call(std::string command, std::string args, std::string format,
+ virtual bool call(std::string command, cmdmap_t &cmdmap, std::string format,
bufferlist& out) {
if (command == "0") {
out.append(CEPH_ADMIN_SOCK_VERSION);
@@ -441,7 +441,7 @@ class HelpHook : public AdminSocketHook {
AdminSocket *m_as;
public:
HelpHook(AdminSocket *as) : m_as(as) {}
- bool call(string command, string args, string format, bufferlist& out) {
+ bool call(string command, cmdmap_t &cmdmap, string format, bufferlist& out) {
Formatter *f = new_formatter(format);
f->open_object_section("help");
for (map<string,string>::iterator p = m_as->m_help.begin();
@@ -463,7 +463,7 @@ class GetdescsHook : public AdminSocketHook {
AdminSocket *m_as;
public:
GetdescsHook(AdminSocket *as) : m_as(as) {}
- bool call(string command, string args, string format, bufferlist& out) {
+ bool call(string command, cmdmap_t &cmdmap, string format, bufferlist& out) {
int cmdnum = 0;
JSONFormatter jf(false);
jf.open_object_section("command_descriptions");
diff --git a/src/common/admin_socket.h b/src/common/admin_socket.h
index 30c5eb96ab8..3bc84834348 100644
--- a/src/common/admin_socket.h
+++ b/src/common/admin_socket.h
@@ -21,6 +21,7 @@
#include <string>
#include <map>
#include "include/buffer.h"
+#include "common/cmdparse.h"
class AdminSocket;
class CephContext;
@@ -29,7 +30,7 @@ class CephContext;
class AdminSocketHook {
public:
- virtual bool call(std::string command, std::string args, std::string format,
+ virtual bool call(std::string command, cmdmap_t &cmdmap, std::string format,
bufferlist& out) = 0;
virtual ~AdminSocketHook() {};
};
diff --git a/src/common/ceph_context.cc b/src/common/ceph_context.cc
index 6b227d8689e..9602fdf2e40 100644
--- a/src/common/ceph_context.cc
+++ b/src/common/ceph_context.cc
@@ -156,18 +156,25 @@ class CephContextHook : public AdminSocketHook {
public:
CephContextHook(CephContext *cct) : m_cct(cct) {}
- bool call(std::string command, std::string args, std::string format,
+ bool call(std::string command, cmdmap_t& cmdmap, std::string format,
bufferlist& out) {
- m_cct->do_command(command, args, format, &out);
+ m_cct->do_command(command, cmdmap, format, &out);
return true;
}
};
-void CephContext::do_command(std::string command, std::string args,
+void CephContext::do_command(std::string command, cmdmap_t& cmdmap,
std::string format, bufferlist *out)
{
Formatter *f = new_formatter(format);
- lgeneric_dout(this, 1) << "do_command '" << command << "' '" << args << "'" << dendl;
+ stringstream ss;
+ for (cmdmap_t::iterator it = cmdmap.begin(); it != cmdmap.end(); ++it) {
+ if (it->first != "prefix") {
+ ss << it->first << ":" << cmd_vartype_stringify(it->second) << " ";
+ }
+ }
+ lgeneric_dout(this, 1) << "do_command '" << command << "' '"
+ << ss.str() << dendl;
if (command == "perfcounters_dump" || command == "1" ||
command == "perf dump") {
_perf_counters_collection->dump_formatted(f, false);
@@ -182,14 +189,17 @@ void CephContext::do_command(std::string command, std::string args,
_conf->show_config(f);
}
else if (command == "config set") {
- std::string var = args;
- size_t pos = var.find(' ');
- if (pos == string::npos) {
+ std::string var;
+ std::vector<std::string> val;
+
+ if (!(cmd_getval(this, cmdmap, "var", var)) ||
+ !(cmd_getval(this, cmdmap, "val", val))) {
f->dump_string("error", "syntax error: 'config set <var> <value>'");
} else {
- std::string val = var.substr(pos+1);
- var.resize(pos);
- int r = _conf->set_val(var.c_str(), val.c_str());
+ // val may be multiple words
+ ostringstream argss;
+ std::copy(val.begin(), val.end(), ostream_iterator<string>(argss, " "));
+ int r = _conf->set_val(var.c_str(), argss.str().c_str());
if (r < 0) {
f->dump_stream("error") << "error setting '" << var << "' to '" << val << "': " << cpp_strerror(r);
} else {
@@ -199,15 +209,20 @@ void CephContext::do_command(std::string command, std::string args,
}
}
} else if (command == "config get") {
- char buf[4096];
- memset(buf, 0, sizeof(buf));
- char *tmp = buf;
- int r = _conf->get_val(args.c_str(), &tmp, sizeof(buf));
- if (r < 0) {
- f->dump_stream("error") << "error getting '" << args << "': " << cpp_strerror(r);
- } else {
- f->dump_string(args.c_str(), buf);
- }
+ std::string var;
+ if (!cmd_getval(this, cmdmap, "var", var)) {
+ f->dump_string("error", "syntax error: 'config get <var>'");
+ } else {
+ char buf[4096];
+ memset(buf, 0, sizeof(buf));
+ char *tmp = buf;
+ int r = _conf->get_val(var.c_str(), &tmp, sizeof(buf));
+ if (r < 0) {
+ f->dump_stream("error") << "error getting '" << var << "': " << cpp_strerror(r);
+ } else {
+ f->dump_string(var.c_str(), buf);
+ }
+ }
} else if (command == "log flush") {
_log->flush();
}
@@ -224,7 +239,8 @@ void CephContext::do_command(std::string command, std::string args,
}
f->flush(*out);
delete f;
- lgeneric_dout(this, 1) << "do_command '" << command << "' '" << args << "' result is " << out->length() << " bytes" << dendl;
+ lgeneric_dout(this, 1) << "do_command '" << command << "' '" << ss.str()
+ << "result is " << out->length() << " bytes" << dendl;
};
@@ -262,7 +278,7 @@ CephContext::CephContext(uint32_t module_type_)
_admin_socket->register_command("2", "2", _admin_hook, "");
_admin_socket->register_command("perf schema", "perf schema", _admin_hook, "dump perfcounters schema");
_admin_socket->register_command("config show", "config show", _admin_hook, "dump current config settings");
- _admin_socket->register_command("config set", "config set name=var,type=CephString name=val,type=CephString", _admin_hook, "config set <field> <val>: set a config variable");
+ _admin_socket->register_command("config set", "config set name=var,type=CephString name=val,type=CephString,n=N", _admin_hook, "config set <field> <val> [<val> ...]: set a config variable");
_admin_socket->register_command("config get", "config get name=var,type=CephString", _admin_hook, "config get <field>: get the config value");
_admin_socket->register_command("log flush", "log flush", _admin_hook, "flush log entries to log file");
_admin_socket->register_command("log dump", "log dump", _admin_hook, "dump recent log entries to log file");
diff --git a/src/common/ceph_context.h b/src/common/ceph_context.h
index 85618e35219..08efeceaa67 100644
--- a/src/common/ceph_context.h
+++ b/src/common/ceph_context.h
@@ -20,6 +20,7 @@
#include "include/buffer.h"
#include "include/atomic.h"
+#include "common/cmdparse.h"
class AdminSocket;
class CephContextServiceThread;
@@ -97,7 +98,7 @@ public:
/**
* process an admin socket command
*/
- void do_command(std::string command, std::string args, std::string foramt,
+ void do_command(std::string command, cmdmap_t& cmdmap, std::string format,
bufferlist *out);
/**
diff --git a/src/common/cmdparse.h b/src/common/cmdparse.h
index f258969fb68..58c66b46052 100644
--- a/src/common/cmdparse.h
+++ b/src/common/cmdparse.h
@@ -11,7 +11,8 @@
#include <stdexcept>
#include "common/Formatter.h"
#include "common/BackTrace.h"
-#include "common/ceph_context.h"
+
+class CephContext;
/* this is handy; can't believe it's not standard */
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc
index 2c21e6eac69..118cf6f4a1e 100644
--- a/src/mon/Monitor.cc
+++ b/src/mon/Monitor.cc
@@ -225,16 +225,16 @@ class AdminHook : public AdminSocketHook {
Monitor *mon;
public:
AdminHook(Monitor *m) : mon(m) {}
- bool call(std::string command, std::string args, std::string format,
+ bool call(std::string command, cmdmap_t& cmdmap, std::string format,
bufferlist& out) {
stringstream ss;
- mon->do_admin_command(command, args, format, ss);
+ mon->do_admin_command(command, cmdmap, format, ss);
out.append(ss);
return true;
}
};
-void Monitor::do_admin_command(string command, string args, string format,
+void Monitor::do_admin_command(string command, cmdmap_t& cmdmap, string format,
ostream& ss)
{
Mutex::Locker l(lock);
@@ -246,7 +246,9 @@ void Monitor::do_admin_command(string command, string args, string format,
else if (command == "quorum_status")
_quorum_status(f.get(), ss);
else if (command == "sync_force") {
- if (args != "--yes-i-really-mean-it") {
+ string validate;
+ if ((!cmd_getval(g_ceph_context, cmdmap, "validate", validate)) ||
+ (validate != "--yes-i-really-mean-it")) {
ss << "are you SURE? this will mean the monitor store will be erased "
"the next time the monitor is restarted. pass "
"'--yes-i-really-mean-it' if you really do.";
@@ -254,7 +256,7 @@ void Monitor::do_admin_command(string command, string args, string format,
}
sync_force(f.get(), ss);
} else if (command.find("add_bootstrap_peer_hint") == 0)
- _add_bootstrap_peer_hint(command, args, ss);
+ _add_bootstrap_peer_hint(command, cmdmap, ss);
else
assert(0 == "bad AdminSocket command binding");
}
@@ -485,10 +487,19 @@ int Monitor::preinit()
r = admin_socket->register_command("quorum_status", "quorum_status",
admin_hook, "show current quorum status");
assert(r == 0);
+ r = admin_socket->register_command("sync_force",
+ "sync_force name=validate,"
+ "type=CephChoices,"
+ "strings=--yes-i-really-mean-it",
+ admin_hook,
+ "force sync of and clear monitor store");
+ assert(r == 0);
r = admin_socket->register_command("add_bootstrap_peer_hint",
- "add_bootstrap_peer_hint name=addr,type=CephIPAddr",
+ "add_bootstrap_peer_hint name=addr,"
+ "type=CephIPAddr",
admin_hook,
- "add peer address as potential bootstrap peer for cluster bringup");
+ "add peer address as potential bootstrap"
+ " peer for cluster bringup");
assert(r == 0);
lock.Lock();
@@ -577,6 +588,7 @@ void Monitor::shutdown()
AdminSocket* admin_socket = cct->get_admin_socket();
admin_socket->unregister_command("mon_status");
admin_socket->unregister_command("quorum_status");
+ admin_socket->unregister_command("sync_force");
admin_socket->unregister_command("add_bootstrap_peer_hint");
delete admin_hook;
admin_hook = NULL;
@@ -684,14 +696,17 @@ void Monitor::bootstrap()
}
}
-void Monitor::_add_bootstrap_peer_hint(string cmd, string args, ostream& ss)
+void Monitor::_add_bootstrap_peer_hint(string cmd, cmdmap_t& cmdmap, ostream& ss)
{
- dout(10) << "_add_bootstrap_peer_hint '" << cmd << "' '" << args << "'" << dendl;
+ string addrstr;
+ cmd_getval(g_ceph_context, cmdmap, "addr", addrstr);
+ dout(10) << "_add_bootstrap_peer_hint '" << cmd << "' '"
+ << addrstr << "'" << dendl;
entity_addr_t addr;
const char *end = 0;
- if (!addr.parse(args.c_str(), &end)) {
- ss << "failed to parse addr '" << args << "'; syntax is 'add_bootstrap_peer_hint ip[:port]'";
+ if (!addr.parse(addrstr.c_str(), &end)) {
+ ss << "failed to parse addr '" << addrstr << "'; syntax is 'add_bootstrap_peer_hint ip[:port]'";
return;
}
diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h
index 69dfefe144a..cb1f4138a25 100644
--- a/src/mon/Monitor.h
+++ b/src/mon/Monitor.h
@@ -586,7 +586,7 @@ public:
bool _allowed_command(MonSession *s, map<std::string, cmd_vartype>& cmd);
void _mon_status(Formatter *f, ostream& ss);
void _quorum_status(Formatter *f, ostream& ss);
- void _add_bootstrap_peer_hint(string cmd, string args, ostream& ss);
+ void _add_bootstrap_peer_hint(string cmd, cmdmap_t& cmdmap, ostream& ss);
void handle_command(class MMonCommand *m);
void handle_route(MRoute *m);
@@ -750,7 +750,7 @@ public:
int write_fsid();
int write_fsid(MonitorDBStore::Transaction &t);
- void do_admin_command(std::string command, std::string args,
+ void do_admin_command(std::string command, cmdmap_t& cmdmap,
std::string format, ostream& ss);
private:
diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc
index 89aa1db34eb..69c181862cc 100644
--- a/src/osd/OSD.cc
+++ b/src/osd/OSD.cc
@@ -997,16 +997,17 @@ class OSDSocketHook : public AdminSocketHook {
OSD *osd;
public:
OSDSocketHook(OSD *o) : osd(o) {}
- bool call(std::string command, std::string args, std::string format,
+ bool call(std::string command, cmdmap_t& cmdmap, std::string format,
bufferlist& out) {
stringstream ss;
- bool r = osd->asok_command(command, args, format, ss);
+ bool r = osd->asok_command(command, cmdmap, format, ss);
out.append(ss);
return r;
}
};
-bool OSD::asok_command(string command, string args, string format, ostream& ss)
+bool OSD::asok_command(string command, cmdmap_t& cmdmap, string format,
+ ostream& ss)
{
if (format == "")
format = "json-pretty";
@@ -1089,15 +1090,15 @@ class TestOpsSocketHook : public AdminSocketHook {
ObjectStore *store;
public:
TestOpsSocketHook(OSDService *s, ObjectStore *st) : service(s), store(st) {}
- bool call(std::string command, std::string args, std::string format,
+ bool call(std::string command, cmdmap_t& cmdmap, std::string format,
bufferlist& out) {
stringstream ss;
- test_ops(service, store, command, args, ss);
+ test_ops(service, store, command, cmdmap, ss);
out.append(ss);
return true;
}
void test_ops(OSDService *service, ObjectStore *store, std::string command,
- std::string args, ostream &ss);
+ cmdmap_t& cmdmap, ostream &ss);
};
@@ -1249,10 +1250,12 @@ int OSD::init()
assert(r == 0);
test_ops_hook = new TestOpsSocketHook(&(this->service), this->store);
+ // Note: pools are CephString instead of CephPoolname because
+ // these commands traditionally support both pool names and numbers
r = admin_socket->register_command(
"setomapval",
"setomapval " \
- "name=pool,type=CephPoolname " \
+ "name=pool,type=CephString " \
"name=objname,type=CephObjectname " \
"name=key,type=CephString "\
"name=val,type=CephString",
@@ -1262,7 +1265,7 @@ int OSD::init()
r = admin_socket->register_command(
"rmomapkey",
"rmomapkey " \
- "name=pool,type=CephPoolname " \
+ "name=pool,type=CephString " \
"name=objname,type=CephObjectname " \
"name=key,type=CephString",
test_ops_hook,
@@ -1271,7 +1274,7 @@ int OSD::init()
r = admin_socket->register_command(
"setomapheader",
"setomapheader " \
- "name=pool,type=CephPoolname " \
+ "name=pool,type=CephString " \
"name=objname,type=CephObjectname " \
"name=header,type=CephString",
test_ops_hook,
@@ -1281,7 +1284,7 @@ int OSD::init()
r = admin_socket->register_command(
"getomap",
"getomap " \
- "name=pool,type=CephPoolname " \
+ "name=pool,type=CephString " \
"name=objname,type=CephObjectname",
test_ops_hook,
"output entire object map");
@@ -1290,7 +1293,7 @@ int OSD::init()
r = admin_socket->register_command(
"truncobj",
"truncobj " \
- "name=pool,type=CephPoolname " \
+ "name=pool,type=CephString " \
"name=objname,type=CephObjectname " \
"name=len,type=CephInt",
test_ops_hook,
@@ -1300,7 +1303,7 @@ int OSD::init()
r = admin_socket->register_command(
"injectdataerr",
"injectdataerr " \
- "name=pool,type=CephPoolname " \
+ "name=pool,type=CephString " \
"name=objname,type=CephObjectname",
test_ops_hook,
"inject data error into omap");
@@ -1309,7 +1312,7 @@ int OSD::init()
r = admin_socket->register_command(
"injectmdataerr",
"injectmdataerr " \
- "name=pool,type=CephPoolname " \
+ "name=pool,type=CephString " \
"name=objname,type=CephObjectname",
test_ops_hook,
"inject metadata error");
@@ -3111,7 +3114,7 @@ void OSD::check_ops_in_flight()
// injectmdataerr [namespace/]<obj-name>
// injectdataerr [namespace/]<obj-name>
void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
- std::string command, std::string args, ostream &ss)
+ std::string command, cmdmap_t& cmdmap, ostream &ss)
{
//Test support
//Support changing the omap on a single osd by using the Admin Socket to
@@ -3121,40 +3124,36 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
command == "truncobj" || command == "injectmdataerr" ||
command == "injectdataerr"
) {
- std::vector<std::string> argv;
pg_t rawpg, pgid;
int64_t pool;
OSDMapRef curmap = service->get_osdmap();
int r;
- argv.push_back(command);
- string_to_vec(argv, args);
- int argc = argv.size();
+ string poolstr;
- if (argc < 3) {
- ss << "Illegal request";
+ cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
+ pool = curmap->const_lookup_pg_pool_name(poolstr.c_str());
+ //If we can't find it by name then maybe id specified
+ if (pool < 0 && isdigit(poolstr[0]))
+ pool = atoll(poolstr.c_str());
+ if (pool < 0) {
+ ss << "Invalid pool" << poolstr;
return;
}
-
- pool = curmap->const_lookup_pg_pool_name(argv[1].c_str());
- //If we can't find it my name then maybe id specified
- if (pool < 0 && isdigit(argv[1].c_str()[0]))
- pool = atoll(argv[1].c_str());
r = -1;
string objname, nspace;
- objname = string(argv[2]);
- if (pool >= 0) {
- std::size_t found = argv[2].find_first_of('/');
- if (found != string::npos) {
- nspace = argv[2].substr(0, found);
- objname = argv[2].substr(found+1);
- }
- object_locator_t oloc(pool, nspace);
- r = curmap->object_locator_to_pg(object_t(objname), oloc, rawpg);
+ cmd_getval(g_ceph_context, cmdmap, "objname", objname);
+ std::size_t found = objname.find_first_of('/');
+ if (found != string::npos) {
+ nspace = objname.substr(0, found);
+ objname = objname.substr(found+1);
}
+ object_locator_t oloc(pool, nspace);
+ r = curmap->object_locator_to_pg(object_t(objname), oloc, rawpg);
+
if (r < 0) {
- ss << "Invalid pool " << argv[1];
- return;
+ ss << "Invalid namespace/objname";
+ return;
}
pgid = curmap->raw_pg_to_pg(rawpg);
@@ -3162,15 +3161,13 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
ObjectStore::Transaction t;
if (command == "setomapval") {
- if (argc != 5) {
- ss << "usage: setomapval <pool> [namespace/]<obj-name> <key> <val>";
- return;
- }
map<string, bufferlist> newattrs;
bufferlist val;
- string key(argv[3]);
-
- val.append(argv[4]);
+ string key, valstr;
+ cmd_getval(g_ceph_context, cmdmap, "key", key);
+ cmd_getval(g_ceph_context, cmdmap, "val", valstr);
+
+ val.append(valstr);
newattrs[key] = val;
t.omap_setkeys(coll_t(pgid), obj, newattrs);
r = store->apply_transaction(t);
@@ -3179,13 +3176,11 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
else
ss << "ok";
} else if (command == "rmomapkey") {
- if (argc != 4) {
- ss << "usage: rmomapkey <pool> [namespace/]<obj-name> <key>";
- return;
- }
+ string key;
set<string> keys;
+ cmd_getval(g_ceph_context, cmdmap, "key", key);
- keys.insert(string(argv[3]));
+ keys.insert(key);
t.omap_rmkeys(coll_t(pgid), obj, keys);
r = store->apply_transaction(t);
if (r < 0)
@@ -3193,13 +3188,11 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
else
ss << "ok";
} else if (command == "setomapheader") {
- if (argc != 4) {
- ss << "usage: setomapheader <pool> [namespace/]<obj-name> <header>";
- return;
- }
bufferlist newheader;
+ string headerstr;
- newheader.append(argv[3]);
+ cmd_getval(g_ceph_context, cmdmap, "header", headerstr);
+ newheader.append(headerstr);
t.omap_setheader(coll_t(pgid), obj, newheader);
r = store->apply_transaction(t);
if (r < 0)
@@ -3207,10 +3200,6 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
else
ss << "ok";
} else if (command == "getomap") {
- if (argc != 3) {
- ss << "usage: getomap <pool> [namespace/]<obj-name>";
- return;
- }
//Debug: Output entire omap
bufferlist hdrbl;
map<string, bufferlist> keyvals;
@@ -3225,11 +3214,9 @@ void TestOpsSocketHook::test_ops(OSDService *service, ObjectStore *store,
ss << "error=" << r;
}
} else if (command == "truncobj") {
- if (argc != 4) {
- ss << "usage: truncobj <pool> [namespace/]<obj-name> <val>";
- return;
- }
- t.truncate(coll_t(pgid), obj, atoi(argv[3].c_str()));
+ int64_t trunclen;
+ cmd_getval(g_ceph_context, cmdmap, "len", trunclen);
+ t.truncate(coll_t(pgid), obj, trunclen);
r = store->apply_transaction(t);
if (r < 0)
ss << "error=" << r;
diff --git a/src/osd/OSD.h b/src/osd/OSD.h
index 478f766d145..5196a1dc1f3 100644
--- a/src/osd/OSD.h
+++ b/src/osd/OSD.h
@@ -622,7 +622,7 @@ protected:
// asok
friend class OSDSocketHook;
class OSDSocketHook *asok_hook;
- bool asok_command(string command, string args, string format, ostream& ss);
+ bool asok_command(string command, cmdmap_t& cmdmap, string format, ostream& ss);
public:
ClassHandler *class_handler;
diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc
index 8ec1374ec4f..b7530200298 100644
--- a/src/osdc/Objecter.cc
+++ b/src/osdc/Objecter.cc
@@ -2335,7 +2335,7 @@ Objecter::RequestStateHook::RequestStateHook(Objecter *objecter) :
{
}
-bool Objecter::RequestStateHook::call(std::string command, std::string args,
+bool Objecter::RequestStateHook::call(std::string command, cmdmap_t& cmdmap,
std::string format, bufferlist& out)
{
stringstream ss;
diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h
index aa4a20d8b0b..26485bc665f 100644
--- a/src/osdc/Objecter.h
+++ b/src/osdc/Objecter.h
@@ -726,7 +726,7 @@ class Objecter {
Objecter *m_objecter;
public:
RequestStateHook(Objecter *objecter);
- bool call(std::string command, std::string args, std::string format,
+ bool call(std::string command, cmdmap_t& cmdmap, std::string format,
bufferlist& out);
};
diff --git a/src/test/admin_socket.cc b/src/test/admin_socket.cc
index 8f67918e644..6f2a215b565 100644
--- a/src/test/admin_socket.cc
+++ b/src/test/admin_socket.cc
@@ -70,10 +70,19 @@ TEST(AdminSocket, SendNoOp) {
}
class MyTest : public AdminSocketHook {
- bool call(std::string command, std::string args, std::string format, bufferlist& result) {
+ bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& result) {
+ std::vector<std::string> args;
+ cmd_getval(g_ceph_context, cmdmap, "args", args);
result.append(command);
result.append("|");
- result.append(args);
+ string resultstr;
+ for (std::vector<std::string>::iterator it = args.begin();
+ it != args.end(); ++it) {
+ if (it != args.begin())
+ resultstr += ' ';
+ resultstr += *it;
+ }
+ result.append(resultstr);
return true;
}
};
@@ -93,10 +102,19 @@ TEST(AdminSocket, RegisterCommand) {
}
class MyTest2 : public AdminSocketHook {
- bool call(std::string command, std::string args, std::string format, bufferlist& result) {
+ bool call(std::string command, cmdmap_t& cmdmap, std::string format, bufferlist& result) {
+ std::vector<std::string> args;
+ cmd_getval(g_ceph_context, cmdmap, "args", args);
result.append(command);
result.append("|");
- result.append(args);
+ string resultstr;
+ for (std::vector<std::string>::iterator it = args.begin();
+ it != args.end(); ++it) {
+ if (it != args.begin())
+ resultstr += ' ';
+ resultstr += *it;
+ }
+ result.append(resultstr);
return true;
}
};
@@ -108,23 +126,23 @@ TEST(AdminSocket, RegisterCommandPrefixes) {
ASSERT_EQ(true, asoct.shutdown());
ASSERT_EQ(true, asoct.init(get_rand_socket_path()));
AdminSocketClient client(get_rand_socket_path());
- ASSERT_EQ(0, asoct.m_asokc->register_command("test", "test", new MyTest(), ""));
- ASSERT_EQ(0, asoct.m_asokc->register_command("test command", "test command", new MyTest2(), ""));
+ ASSERT_EQ(0, asoct.m_asokc->register_command("test", "test name=args,type=CephString,n=N", new MyTest(), ""));
+ ASSERT_EQ(0, asoct.m_asokc->register_command("test command", "test command name=args,type=CephString,n=N", new MyTest2(), ""));
string result;
ASSERT_EQ("", client.do_request("{\"prefix\":\"test\"}", &result));
ASSERT_EQ("test|", result);
ASSERT_EQ("", client.do_request("{\"prefix\":\"test command\"}", &result));
ASSERT_EQ("test command|", result);
- ASSERT_EQ("", client.do_request("{\"prefix\":\"test command post\"}", &result));
+ ASSERT_EQ("", client.do_request("{\"prefix\":\"test command\",\"args\":[\"post\"]}", &result));
ASSERT_EQ("test command|post", result);
- ASSERT_EQ("", client.do_request("{\"prefix\":\"test command post\"}", &result));
+ ASSERT_EQ("", client.do_request("{\"prefix\":\"test command\",\"args\":[\" post\"]}", &result));
ASSERT_EQ("test command| post", result);
- ASSERT_EQ("", client.do_request("{\"prefix\":\"test this thing\"}", &result));
+ ASSERT_EQ("", client.do_request("{\"prefix\":\"test\",\"args\":[\"this thing\"]}", &result));
ASSERT_EQ("test|this thing", result);
- ASSERT_EQ("", client.do_request("{\"prefix\":\"test command post\"}", &result));
+ ASSERT_EQ("", client.do_request("{\"prefix\":\"test\",\"args\":[\" command post\"]}", &result));
ASSERT_EQ("test| command post", result);
- ASSERT_EQ("", client.do_request("{\"prefix\":\"test this thing\"}", &result));
+ ASSERT_EQ("", client.do_request("{\"prefix\":\"test\",\"args\":[\" this thing\"]}", &result));
ASSERT_EQ("test| this thing", result);
ASSERT_EQ(true, asoct.shutdown());
}