#include <unistd.h>
#include "include/compat.h"
-#include "global/signal_handler.h"
-
#include "include/types.h"
#include "include/str_list.h"
-#include "common/entity_name.h"
+
#include "common/Clock.h"
-#include "common/signal.h"
+#include "common/HeartbeatMap.h"
+#include "common/Timer.h"
+#include "common/backport14.h"
#include "common/ceph_argparse.h"
+#include "common/config.h"
+#include "common/entity_name.h"
#include "common/errno.h"
+#include "common/perf_counters.h"
+#include "common/signal.h"
+#include "common/version.h"
+
+#include "global/signal_handler.h"
#include "msg/Messenger.h"
#include "mon/MonClient.h"
#include "SnapServer.h"
#include "SnapClient.h"
-#include "common/HeartbeatMap.h"
-
-#include "common/perf_counters.h"
-
-#include "common/Timer.h"
-
#include "events/ESession.h"
#include "events/ESubtreeMap.h"
#include "auth/RotatingKeyRing.h"
#include "auth/KeyRing.h"
-#include "common/config.h"
-
#include "perfglue/cpu_profiler.h"
#include "perfglue/heap_profiler.h"
explicit C_MDS_Tick(MDSDaemon *m) : mds_daemon(m) {}
void finish(int r) override {
assert(mds_daemon->mds_lock.is_locked_by_me());
-
- mds_daemon->tick_event = 0;
mds_daemon->tick();
}
};
void MDSDaemon::tick()
{
- tick_event = 0;
-
// reschedule
reset_tick();
"name=injected_args,type=CephString,n=N",
"inject configuration arguments into running MDS",
"mds", "*", "cli,rest")
+COMMAND("config set " \
+ "name=key,type=CephString name=value,type=CephString",
+ "Set a configuration option at runtime (not persistent)",
+ "mds", "*", "cli,rest")
COMMAND("exit",
"Terminate this MDS",
"mds", "*", "cli,rest")
"List detected metadata damage", "mds", "r", "cli,rest")
COMMAND("damage rm name=damage_id,type=CephInt",
"Remove a damage table entry", "mds", "rw", "cli,rest")
+COMMAND("version", "report version of MDS", "mds", "r", "cli,rest")
COMMAND("heap " \
"name=heapcmd,type=CephChoices,strings=dump|start_profiler|stop_profiler|release|stats", \
"show heap usage info (available only if compiled with tcmalloc)", \
std::stringstream ds;
std::stringstream ss;
std::string prefix;
+ std::string format;
+ std::unique_ptr<Formatter> f(Formatter::create(format));
cmd_getval(cct, cmdmap, "prefix", prefix);
int r = 0;
if (prefix == "get_command_descriptions") {
int cmdnum = 0;
- JSONFormatter *f = new JSONFormatter();
+ std::unique_ptr<JSONFormatter> f(ceph::make_unique<JSONFormatter>());
f->open_object_section("command_descriptions");
for (MDSCommand *cp = mds_commands;
cp < &mds_commands[ARRAY_SIZE(mds_commands)]; cp++) {
ostringstream secname;
secname << "cmd" << setfill('0') << std::setw(3) << cmdnum;
- dump_cmddesc_to_json(f, secname.str(), cp->cmdstring, cp->helpstring,
+ dump_cmddesc_to_json(f.get(), secname.str(), cp->cmdstring, cp->helpstring,
cp->module, cp->perm, cp->availability, 0);
cmdnum++;
}
f->close_section(); // command_descriptions
f->flush(ds);
- delete f;
+ goto out;
+ }
+
+ cmd_getval(cct, cmdmap, "format", format);
+ if (prefix == "version") {
+ if (f) {
+ f->open_object_section("version");
+ f->dump_string("version", pretty_version_to_str());
+ f->close_section();
+ f->flush(ds);
+ } else {
+ ds << pretty_version_to_str();
+ }
} else if (prefix == "injectargs") {
vector<string> argsvec;
cmd_getval(cct, cmdmap, "injected_args", argsvec);
for (vector<string>::iterator a = ++argsvec.begin(); a != argsvec.end(); ++a)
args += " " + *a;
r = cct->_conf->injectargs(args, &ss);
+ } else if (prefix == "config set") {
+ std::string key;
+ cmd_getval(cct, cmdmap, "key", key);
+ std::string val;
+ cmd_getval(cct, cmdmap, "value", val);
+ r = cct->_conf->set_val(key, val, true, &ss);
} else if (prefix == "exit") {
// We will send response before executing
ss << "Exiting...";
*run_later = new SuicideLater(this);
- }
- else if (prefix == "respawn") {
+ } else if (prefix == "respawn") {
// We will send response before executing
ss << "Respawning...";
*run_later = new RespawnLater(this);
// see who i am
addr = messenger->get_myaddr();
- dout(10) << "map says i am " << addr << " mds." << whoami << "." << incarnation
+ dout(10) << "map says I am " << addr << " mds." << whoami << "." << incarnation
<< " state " << ceph_mds_state_name(new_state) << dendl;
if (whoami == MDS_RANK_NONE) {
if (mds_rank != NULL) {
+ const auto myid = monc->get_global_id();
// We have entered a rank-holding state, we shouldn't be back
// here!
if (g_conf->mds_enforce_unique_name) {
if (mds_gid_t existing = mdsmap->find_mds_gid_by_name(name)) {
const MDSMap::mds_info_t& i = mdsmap->get_info_gid(existing);
- if (i.global_id > monc->get_global_id()) {
- dout(1) << "handle_mds_map i (" << addr
- << ") dne in the mdsmap, new instance has larger gid " << i.global_id
- << ", suicide" << dendl;
+ if (i.global_id > myid) {
+ dout(1) << "map replaced me with another mds." << whoami
+ << " with gid (" << i.global_id << ") larger than myself ("
+ << myid << "); quitting!" << dendl;
// Call suicide() rather than respawn() because if someone else
// has taken our ID, we don't want to keep restarting and
// fighting them for the ID.
}
}
- dout(1) << "handle_mds_map i (" << addr
- << ") dne in the mdsmap, respawning myself" << dendl;
+ dout(1) << "map removed me (mds." << whoami << " gid:"
+ << myid << ") from cluster due to lost contact; respawning" << dendl;
respawn();
}
// MDSRank not active: process the map here to see if we have
EntityName name;
uint64_t global_id;
- is_valid = authorize_handler->verify_authorizer(
- cct, monc->rotating_secrets.get(),
- authorizer_data, authorizer_reply, name, global_id, caps_info, session_key);
+ RotatingKeyRing *keys = monc->rotating_secrets.get();
+ if (keys) {
+ is_valid = authorize_handler->verify_authorizer(
+ cct, keys,
+ authorizer_data, authorizer_reply, name, global_id, caps_info,
+ session_key);
+ } else {
+ dout(10) << __func__ << " no rotating_keys (yet), denied" << dendl;
+ is_valid = false;
+ }
if (is_valid) {
entity_name_t n(con->get_peer_type(), global_id);