mirror of
https://github.com/ceph/ceph
synced 2025-01-03 09:32:43 +00:00
mds: add dirfrag split/merge asok commands
Analogous to those from the old-style mds tell. Also add an 'ls' that gives you the frags in the same format that frag_t::parse expects them, so that it's a bit less obscure to use. Signed-off-by: John Spray <john.spray@redhat.com>
This commit is contained in:
parent
ac4477926f
commit
fb71bd9d1e
176
src/mds/MDS.cc
176
src/mds/MDS.cc
@ -359,6 +359,15 @@ bool MDS::asok_command(string command, cmdmap_t& cmdmap, string format,
|
|||||||
mds_lock.Lock();
|
mds_lock.Lock();
|
||||||
mdcache->force_readonly();
|
mdcache->force_readonly();
|
||||||
mds_lock.Unlock();
|
mds_lock.Unlock();
|
||||||
|
} else if (command == "dirfrag split") {
|
||||||
|
Mutex::Locker l(mds_lock);
|
||||||
|
command_dirfrag_split(cmdmap, ss);
|
||||||
|
} else if (command == "dirfrag merge") {
|
||||||
|
Mutex::Locker l(mds_lock);
|
||||||
|
command_dirfrag_merge(cmdmap, ss);
|
||||||
|
} else if (command == "dirfrag ls") {
|
||||||
|
Mutex::Locker l(mds_lock);
|
||||||
|
command_dirfrag_ls(cmdmap, ss, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f->flush(ss);
|
f->flush(ss);
|
||||||
@ -591,6 +600,150 @@ int MDS::_command_export_dir(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CDir *MDS::_command_dirfrag_get(
|
||||||
|
const cmdmap_t &cmdmap,
|
||||||
|
std::ostream &ss)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
bool got = cmd_getval(g_ceph_context, cmdmap, "path", path);
|
||||||
|
if (!got) {
|
||||||
|
ss << "missing path argument";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string frag_str;
|
||||||
|
if (!cmd_getval(g_ceph_context, cmdmap, "frag", frag_str)) {
|
||||||
|
ss << "missing frag argument";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInode *in = mdcache->cache_traverse(filepath(path.c_str()));
|
||||||
|
if (!in) {
|
||||||
|
// TODO really we should load something in if it's not in cache,
|
||||||
|
// but the infrastructure is harder, and we might still be unable
|
||||||
|
// to act on it if someone else is auth.
|
||||||
|
ss << "directory inode not in cache";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_t fg;
|
||||||
|
|
||||||
|
if (!fg.parse(frag_str.c_str())) {
|
||||||
|
ss << "frag " << frag_str << " failed to parse";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDir *dir = in->get_dirfrag(fg);
|
||||||
|
if (!dir) {
|
||||||
|
ss << "frag 0x" << std::hex << in->ino() << "/" << fg << " not found";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dir->is_auth()) {
|
||||||
|
ss << "frag " << dir->dirfrag() << " not auth (auth = "
|
||||||
|
<< dir->authority() << ")";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MDS::command_dirfrag_split(
|
||||||
|
cmdmap_t cmdmap,
|
||||||
|
std::ostream &ss)
|
||||||
|
{
|
||||||
|
int64_t by = 0;
|
||||||
|
if (!cmd_getval(g_ceph_context, cmdmap, "bits", by)) {
|
||||||
|
ss << "missing bits argument";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (by <= 0) {
|
||||||
|
ss << "must split by >0 bits";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDir *dir = _command_dirfrag_get(cmdmap, ss);
|
||||||
|
if (!dir) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdcache->split_dir(dir, by);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MDS::command_dirfrag_merge(
|
||||||
|
cmdmap_t cmdmap,
|
||||||
|
std::ostream &ss)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
bool got = cmd_getval(g_ceph_context, cmdmap, "path", path);
|
||||||
|
if (!got) {
|
||||||
|
ss << "missing path argument";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string frag_str;
|
||||||
|
if (!cmd_getval(g_ceph_context, cmdmap, "frag", frag_str)) {
|
||||||
|
ss << "missing frag argument";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInode *in = mdcache->cache_traverse(filepath(path.c_str()));
|
||||||
|
if (!in) {
|
||||||
|
ss << "directory inode not in cache";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_t fg;
|
||||||
|
if (!fg.parse(frag_str.c_str())) {
|
||||||
|
ss << "frag " << frag_str << " failed to parse";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdcache->merge_dir(in, fg);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MDS::command_dirfrag_ls(
|
||||||
|
cmdmap_t cmdmap,
|
||||||
|
std::ostream &ss,
|
||||||
|
Formatter *f)
|
||||||
|
{
|
||||||
|
std::string path;
|
||||||
|
bool got = cmd_getval(g_ceph_context, cmdmap, "path", path);
|
||||||
|
if (!got) {
|
||||||
|
ss << "missing path argument";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CInode *in = mdcache->cache_traverse(filepath(path.c_str()));
|
||||||
|
if (!in) {
|
||||||
|
ss << "directory inode not in cache";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->open_array_section("frags");
|
||||||
|
std::list<frag_t> frags;
|
||||||
|
// NB using get_leaves_under instead of get_dirfrags to give
|
||||||
|
// you the list of what dirfrags may exist, not which are in cache
|
||||||
|
in->dirfragtree.get_leaves_under(frag_t(), frags);
|
||||||
|
for (std::list<frag_t>::iterator i = frags.begin();
|
||||||
|
i != frags.end(); ++i) {
|
||||||
|
f->open_object_section("frag");
|
||||||
|
f->dump_int("value", i->value());
|
||||||
|
f->dump_int("bits", i->bits());
|
||||||
|
std::ostringstream frag_str;
|
||||||
|
frag_str << std::hex << i->value() << "/" << std::dec << i->bits();
|
||||||
|
f->dump_string("str", frag_str.str());
|
||||||
|
f->close_section();
|
||||||
|
}
|
||||||
|
f->close_section();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void MDS::set_up_admin_socket()
|
void MDS::set_up_admin_socket()
|
||||||
{
|
{
|
||||||
@ -664,6 +817,27 @@ void MDS::set_up_admin_socket()
|
|||||||
asok_hook,
|
asok_hook,
|
||||||
"Return the subtree map");
|
"Return the subtree map");
|
||||||
assert(r == 0);
|
assert(r == 0);
|
||||||
|
r = admin_socket->register_command("dirfrag split",
|
||||||
|
"dirfrag split "
|
||||||
|
"name=path,type=CephString,req=true "
|
||||||
|
"name=frag,type=CephString,req=true "
|
||||||
|
"name=bits,type=CephInt,req=true ",
|
||||||
|
asok_hook,
|
||||||
|
"Fragment directory by path");
|
||||||
|
assert(r == 0);
|
||||||
|
r = admin_socket->register_command("dirfrag merge",
|
||||||
|
"dirfrag merge "
|
||||||
|
"name=path,type=CephString,req=true "
|
||||||
|
"name=frag,type=CephString,req=true",
|
||||||
|
asok_hook,
|
||||||
|
"De-fragment directory by path");
|
||||||
|
assert(r == 0);
|
||||||
|
r = admin_socket->register_command("dirfrag ls",
|
||||||
|
"dirfrag ls "
|
||||||
|
"name=path,type=CephString,req=true",
|
||||||
|
asok_hook,
|
||||||
|
"List fragments in directory");
|
||||||
|
assert(r == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MDS::clean_up_admin_socket()
|
void MDS::clean_up_admin_socket()
|
||||||
@ -1257,7 +1431,7 @@ COMMAND("heap " \
|
|||||||
"mds", "*", "cli,rest")
|
"mds", "*", "cli,rest")
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: reinstate issue_caps, try_eval, fragment_dir, merge_dir
|
// FIXME: reinstate issue_caps, try_eval,
|
||||||
// *if* it makes sense to do so (or should these be admin socket things?)
|
// *if* it makes sense to do so (or should these be admin socket things?)
|
||||||
|
|
||||||
/* This function DOES put the passed message before returning*/
|
/* This function DOES put the passed message before returning*/
|
||||||
|
@ -382,9 +382,22 @@ private:
|
|||||||
void command_get_subtrees(Formatter *f);
|
void command_get_subtrees(Formatter *f);
|
||||||
void command_export_dir(Formatter *f,
|
void command_export_dir(Formatter *f,
|
||||||
const std::string &path, mds_rank_t dest);
|
const std::string &path, mds_rank_t dest);
|
||||||
|
bool command_dirfrag_split(
|
||||||
|
cmdmap_t cmdmap,
|
||||||
|
std::ostream &ss);
|
||||||
|
bool command_dirfrag_merge(
|
||||||
|
cmdmap_t cmdmap,
|
||||||
|
std::ostream &ss);
|
||||||
|
bool command_dirfrag_ls(
|
||||||
|
cmdmap_t cmdmap,
|
||||||
|
std::ostream &ss,
|
||||||
|
Formatter *f);
|
||||||
private:
|
private:
|
||||||
int _command_export_dir(const std::string &path, mds_rank_t dest);
|
int _command_export_dir(const std::string &path, mds_rank_t dest);
|
||||||
int _command_flush_journal(std::stringstream *ss);
|
int _command_flush_journal(std::stringstream *ss);
|
||||||
|
CDir *_command_dirfrag_get(
|
||||||
|
const cmdmap_t &cmdmap,
|
||||||
|
std::ostream &ss);
|
||||||
public:
|
public:
|
||||||
// config observer bits
|
// config observer bits
|
||||||
virtual const char** get_tracked_conf_keys() const;
|
virtual const char** get_tracked_conf_keys() const;
|
||||||
|
Loading…
Reference in New Issue
Block a user