Merge PR #36823 into master

* refs/pull/36823/head:
	qa : add a test for the cmd, dump cache
	mds : add timeout to the command, dump cache, to prevent it from running too long and affecting the service

Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
This commit is contained in:
Patrick Donnelly 2021-06-18 19:47:53 -07:00
commit c4de4b3df8
No known key found for this signature in database
GPG Key ID: 3A2A7E25BEA8AADB
5 changed files with 54 additions and 12 deletions

View File

@ -310,6 +310,11 @@ class TestConfigCommands(CephFSTestCase):
out = self.fs.mds_asok(['config', 'get', test_key])
self.assertEqual(out[test_key], test_val)
def test_mds_dump_cache_asok(self):
cache_file = "cache_file"
timeout = "1"
self.fs.rank_asok(['dump', 'cache', cache_file, timeout])
def test_mds_config_tell(self):
test_key = "mds_max_purge_ops"
test_val = "123"

View File

@ -12520,21 +12520,21 @@ void MDCache::dump_tree(CInode *in, const int cur_depth, const int max_depth, Fo
f->close_section();
}
int MDCache::dump_cache(std::string_view file_name)
int MDCache::dump_cache(std::string_view file_name, double timeout)
{
return dump_cache(file_name, NULL);
return dump_cache(file_name, NULL, timeout);
}
int MDCache::dump_cache(Formatter *f)
int MDCache::dump_cache(Formatter *f, double timeout)
{
return dump_cache(std::string_view(""), f);
return dump_cache(std::string_view(""), f, timeout);
}
/**
* Dump the metadata cache, either to a Formatter, if
* provided, else to a plain text file.
*/
int MDCache::dump_cache(std::string_view fn, Formatter *f)
int MDCache::dump_cache(std::string_view fn, Formatter *f, double timeout)
{
int r = 0;
@ -12620,22 +12620,50 @@ int MDCache::dump_cache(std::string_view fn, Formatter *f)
return 1;
};
auto start = mono_clock::now();
int64_t count = 0;
for (auto &p : inode_map) {
r = dump_func(p.second);
if (r < 0)
goto out;
if (!(++count % 1000) &&
timeout > 0 &&
std::chrono::duration<double>(mono_clock::now() - start).count() > timeout) {
r = -ETIMEDOUT;
goto out;
}
}
for (auto &p : snap_inode_map) {
r = dump_func(p.second);
if (r < 0)
goto out;
if (!(++count % 1000) &&
timeout > 0 &&
std::chrono::duration<double>(mono_clock::now() - start).count() > timeout) {
r = -ETIMEDOUT;
goto out;
}
}
r = 0;
out:
if (f) {
if (r == -ETIMEDOUT)
{
f->close_section();
f->open_object_section("result");
f->dump_string("error", "the operation timeout");
}
f->close_section(); // inodes
} else {
if (r == -ETIMEDOUT)
{
CachedStackStringStream css;
*css << "error : the operation timeout" << std::endl;
auto sv = css->strv();
r = safe_write(fd, sv.data(), sv.size());
}
::close(fd);
}
return r;

View File

@ -909,9 +909,9 @@ class MDCache {
// -- mdsmap --
void handle_mdsmap(const MDSMap &mdsmap, const MDSMap &oldmap);
int dump_cache() { return dump_cache({}, nullptr); }
int dump_cache(std::string_view filename);
int dump_cache(Formatter *f);
int dump_cache() { return dump_cache({}, nullptr, 0); }
int dump_cache(std::string_view filename, double timeout);
int dump_cache(Formatter *f, double timeout);
void dump_tree(CInode *in, const int cur_depth, const int max_depth, Formatter *f);
void cache_status(Formatter *f);
@ -1112,7 +1112,7 @@ class MDCache {
void handle_dentry_link(const cref_t<MDentryLink> &m);
void handle_dentry_unlink(const cref_t<MDentryUnlink> &m);
int dump_cache(std::string_view fn, Formatter *f);
int dump_cache(std::string_view fn, Formatter *f, double timeout);
void flush_dentry_work(MDRequestRef& mdr);
/**

View File

@ -311,7 +311,9 @@ void MDSDaemon::set_up_admin_socket()
asok_hook,
"migrate a subtree to named MDS");
ceph_assert(r == 0);
r = admin_socket->register_command("dump cache name=path,type=CephString,req=false",
r = admin_socket->register_command("dump cache "
"name=path,type=CephString,req=false "
"name=timeout,type=CephInt,range=0,req=false",
asok_hook,
"dump metadata cache (optionally to a file)");
ceph_assert(r == 0);

View File

@ -2728,11 +2728,18 @@ void MDSRankDispatcher::handle_asok_command(
command_export_dir(f, path, (mds_rank_t)rank);
} else if (command == "dump cache") {
std::lock_guard l(mds_lock);
int64_t timeout = 0;
cmd_getval(cmdmap, "timeout", timeout);
auto mds_beacon_interval = g_conf().get_val<double>("mds_beacon_interval");
if (timeout <= 0)
timeout = mds_beacon_interval / 2;
else if (timeout > mds_beacon_interval)
timeout = mds_beacon_interval;
string path;
if (!cmd_getval(cmdmap, "path", path)) {
r = mdcache->dump_cache(f);
r = mdcache->dump_cache(f, timeout);
} else {
r = mdcache->dump_cache(path);
r = mdcache->dump_cache(path, timeout);
}
} else if (command == "cache drop") {
int64_t timeout = 0;