mon/OSDMonitor: "osd pool application ls" support

It would be a pain if we have to call 'ceph osd dump --format=json-pretty'
to find out these each time...

Demo output:
(1) ceph osd pool application get
{
    "cephfs_data_b": {
        "cephfs": {}
    },
    "cephfs_metadata_a": {
        "cephfs": {}
    },
    "test_pool": {
        "rbd": {
            "test": "me"
        }
    }
}

(2) ceph osd pool application get test_pool
{
    "rbd": {
        "test": "me"
    }
}

(3) ceph osd pool application get test_pool rbd
{
    "test": "me"
}

(4) ceph osd pool application get test_pool rbd test
me

Fixes: http://tracker.ceph.com/issues/20976
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
This commit is contained in:
xie xingguo 2017-08-09 21:24:49 +08:00
parent c8c837f665
commit 46586b2288
3 changed files with 90 additions and 0 deletions

View File

@ -2385,6 +2385,9 @@ function test_mon_pool_application()
ceph osd pool application set app_for_test rbd key1 value1
ceph osd pool application set app_for_test rbd key2 value2
ceph osd pool application set app_for_test rgw key1 value1
ceph osd pool application get app_for_test rbd key1 | grep 'value1'
ceph osd pool application get app_for_test rbd key2 | grep 'value2'
ceph osd pool application get app_for_test rgw key1 | grep 'value1'
ceph osd pool ls detail --format=json | grep '"application_metadata":{"rbd":{"key1":"value1","key2":"value2"},"rgw":{"key1":"value1"}}'

View File

@ -967,6 +967,12 @@ COMMAND("osd pool application rm " \
"name=key,type=CephString",
"removes application <app> metadata key <key> on pool <poolname>",
"osd", "rw", "cli,rest")
COMMAND("osd pool application get " \
"name=pool,type=CephPoolname,req=fasle " \
"name=app,type=CephString,req=false " \
"name=key,type=CephString,req=false",
"get value of key <key> of application <app> on pool <poolname>",
"osd", "r", "cli,rest")
COMMAND("osd utilization",
"get basic pg distribution stats",
"osd", "r", "cli,rest")

View File

@ -5113,6 +5113,87 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
rs << "\n";
rdata.append(rs.str());
}
} else if (prefix == "osd pool application get") {
boost::scoped_ptr<Formatter> f(Formatter::create(format, "json-pretty",
"json-pretty"));
string pool_name;
cmd_getval(g_ceph_context, cmdmap, "pool", pool_name);
string app;
cmd_getval(g_ceph_context, cmdmap, "app", app);
string key;
cmd_getval(g_ceph_context, cmdmap, "key", key);
if (pool_name.empty()) {
// all
f->open_object_section("pools");
for (const auto &pool : osdmap.pools) {
std::string name("<unknown>");
const auto &pni = osdmap.pool_name.find(pool.first);
if (pni != osdmap.pool_name.end())
name = pni->second;
f->open_object_section(name.c_str());
for (auto &app_pair : pool.second.application_metadata) {
f->open_object_section(app_pair.first.c_str());
for (auto &kv_pair : app_pair.second) {
f->dump_string(kv_pair.first.c_str(), kv_pair.second);
}
f->close_section();
}
f->close_section(); // name
}
f->close_section(); // pools
f->flush(rdata);
} else {
int64_t pool = osdmap.lookup_pg_pool_name(pool_name.c_str());
if (pool < 0) {
ss << "unrecognized pool '" << pool_name << "'";
r = -ENOENT;
goto reply;
}
auto p = osdmap.get_pg_pool(pool);
// filter by pool
if (app.empty()) {
f->open_object_section(pool_name.c_str());
for (auto &app_pair : p->application_metadata) {
f->open_object_section(app_pair.first.c_str());
for (auto &kv_pair : app_pair.second) {
f->dump_string(kv_pair.first.c_str(), kv_pair.second);
}
f->close_section(); // application
}
f->close_section(); // pool_name
f->flush(rdata);
goto reply;
}
auto app_it = p->application_metadata.find(app);
if (app_it == p->application_metadata.end()) {
ss << "pool '" << pool_name << "' has no application '" << app << "'";
r = -ENOENT;
goto reply;
}
// filter by pool + app
if (key.empty()) {
f->open_object_section(app_it->first.c_str());
for (auto &kv_pair : app_it->second) {
f->dump_string(kv_pair.first.c_str(), kv_pair.second);
}
f->close_section(); // application
f->flush(rdata);
goto reply;
}
// filter by pool + app + key
auto key_it = app_it->second.find(key);
if (key_it == app_it->second.end()) {
ss << "application '" << app << "' on pool '" << pool_name
<< "' does not have key '" << key << "'";
r = -ENOENT;
goto reply;
}
ss << key_it->second << "\n";
rdata.append(ss.str());
ss.str("");
}
} else {
// try prepare update
return false;