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;
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;
// -- 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);
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);
/**
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);
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;