From: Patrick Donnelly Date: Wed, 19 Nov 2025 23:15:51 +0000 (-0500) Subject: mon: add time_added to mon_info_t X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c5b43e9b2765ff98419c649a5ae53ec16601975d;p=ceph.git mon: add time_added to mon_info_t So we know when the Monitor was added to the map. Signed-off-by: Patrick Donnelly --- diff --git a/src/mon/MonMap.cc b/src/mon/MonMap.cc index 214e9197984..f97f6ce5a2f 100644 --- a/src/mon/MonMap.cc +++ b/src/mon/MonMap.cc @@ -50,7 +50,7 @@ namespace { void mon_info_t::encode(ceph::buffer::list& bl, uint64_t features) const { - uint8_t v = 5; + uint8_t v = 6; uint8_t min_v = 1; if (!crush_loc.empty()) { // we added crush_loc in version 5, but need to let old clients decode it @@ -82,12 +82,13 @@ void mon_info_t::encode(ceph::buffer::list& bl, uint64_t features) const encode(priority, bl); encode(weight, bl); encode(crush_loc, bl); + encode(time_added, bl); ENCODE_FINISH(bl); } void mon_info_t::decode(ceph::buffer::list::const_iterator& p) { - DECODE_START(5, p); + DECODE_START(6, p); decode(name, p); decode(public_addrs, p); if (struct_v >= 2) { @@ -99,24 +100,32 @@ void mon_info_t::decode(ceph::buffer::list::const_iterator& p) if (struct_v >= 5) { decode(crush_loc, p); } + if (struct_v >= 6) { + decode(time_added, p); + } DECODE_FINISH(p); } void mon_info_t::print(ostream& out) const { out << "mon." << name - << " addrs " << public_addrs + << "(addrs " << public_addrs << " priority " << priority << " weight " << weight - << " crush location " << crush_loc; + << " crush_location " << crush_loc + << " added " << time_added + << ")"; } void mon_info_t::dump(ceph::Formatter *f) const { f->dump_string("name", name); - f->dump_stream("addr") << public_addrs; + f->dump_object("public_addrs", public_addrs); + f->dump_stream("addr") << public_addrs; /* sigh: backwards compat */ + f->dump_string("public_addr", public_addrs.get_legacy_str()); /* sighhhhh */ f->dump_int("priority", priority); f->dump_float("weight", weight); + f->dump_string("time_added", fmt::format("{}", time_added)); encode_json("crush_location", crush_loc, f); } @@ -131,6 +140,7 @@ list mon_info_t::generate_test_instances() ls.back().weight = 1.0; ls.back().crush_loc.emplace("root", "default"); ls.back().crush_loc.emplace("host", "foo"); + ls.back().time_added = ceph::real_clock::from_time_t(1); return ls; } namespace { @@ -328,24 +338,36 @@ void MonMap::decode(ceph::buffer::list::const_iterator& p) list MonMap::generate_test_instances() { list o; - o.emplace_back(); - o.emplace_back(); - o.back().epoch = 1; - o.back().last_changed = utime_t(123, 456); - o.back().created = utime_t(789, 101112); - o.back().add("one", entity_addrvec_t()); - - MonMap m; + + o.emplace_back(); /* empty */ + + { + auto& map = o.emplace_back(); + map.epoch = 1; + map.last_changed = utime_t(123, 456); + map.created = utime_t(789, 101112); + auto& info = map.add("one", entity_addrvec_t()); + info.time_added = ceph::real_clock::from_time_t(2468); + } + { + MonMap m; m.epoch = 1; m.last_changed = utime_t(123, 456); - entity_addrvec_t empty_addr_one = entity_addrvec_t(entity_addr_t()); - empty_addr_one.v[0].set_nonce(1); - m.add("empty_addr_one", empty_addr_one); - entity_addrvec_t empty_addr_two = entity_addrvec_t(entity_addr_t()); - empty_addr_two.v[0].set_nonce(2); - m.add("empty_addr_two", empty_addr_two); + { + entity_addrvec_t empty_addr_one = entity_addrvec_t(entity_addr_t()); + empty_addr_one.v[0].set_nonce(1); + auto& info = m.add("empty_addr_one", empty_addr_one); + info.time_added = ceph::real_clock::from_time_t(123456); + } + + { + entity_addrvec_t empty_addr_two = entity_addrvec_t(entity_addr_t()); + empty_addr_two.v[0].set_nonce(2); + auto& info = m.add("empty_addr_two", empty_addr_two); + info.time_added = ceph::real_clock::from_time_t(100000); + } const char *local_pub_addr_s = "127.0.1.2"; @@ -353,11 +375,17 @@ list MonMap::generate_test_instances() entity_addrvec_t local_pub_addr; local_pub_addr.parse(local_pub_addr_s, &end_p); - m.add(mon_info_t("filled_pub_addr", entity_addrvec_t(local_pub_addr), 1, 1)); + { + auto& info = m.add(mon_info_t("filled_pub_addr", entity_addrvec_t(local_pub_addr), 1, 1)); + info.time_added = ceph::real_clock::from_time_t(1); + } - m.add("empty_addr_zero", entity_addrvec_t()); + { + auto& info = m.add("empty_addr_zero", entity_addrvec_t()); + info.time_added = ceph::real_clock::from_time_t(1); + } + o.push_back(std::move(m)); } - o.push_back(std::move(m)); return o; } @@ -383,6 +411,25 @@ int MonMap::read(const char *fn) return 0; } +mon_info_t& MonMap::add(mon_info_t&& m) +{ + ceph_assert(mon_info.count(m.name) == 0); + for (auto& a : m.public_addrs.v) { + ceph_assert(addr_mons.count(a) == 0); + } + m.time_added = ceph::real_clock::now(); + auto& info = mon_info[m.name]; + info = std::move(m); + if (get_required_features().contains_all(ceph::features::mon::FEATURE_NAUTILUS)) { + ranks.push_back(info.name); + ceph_assert(ranks.size() == mon_info.size()); + } else { + calc_legacy_ranks(); + } + calc_addr_mons(); + return info; +} + void MonMap::print_summary(ostream& out) const { out << "e" << epoch << ": " @@ -419,13 +466,11 @@ void MonMap::print(ostream& out) const !disallowed_leaders.empty()) { out << "disallowed_leaders " << disallowed_leaders << "\n"; } - unsigned i = 0; - for (auto p = ranks.begin(); p != ranks.end(); ++p) { - const auto &mi = mon_info.find(*p); - ceph_assert(mi != mon_info.end()); - out << i++ << ": " << mi->second.public_addrs << " mon." << *p; - if (!mi->second.crush_loc.empty()) { - out << "; crush_location " << mi->second.crush_loc; + for (unsigned rank = 0; auto& name : ranks) { + auto& info = get(name); + out << rank++ << ": " << info.public_addrs << " mon." << name; + if (!info.crush_loc.empty()) { + out << "; crush_location " << info.crush_loc; } out << "\n"; } @@ -449,20 +494,11 @@ void MonMap::dump(Formatter *f) const optional_features.dump(f, "optional"); f->close_section(); f->open_array_section("mons"); - int i = 0; - for (auto p = ranks.begin(); p != ranks.end(); ++p, ++i) { + for (unsigned rank = 0; auto& name : ranks) { + auto const& info = get(name); f->open_object_section("mon"); - f->dump_int("rank", i); - f->dump_string("name", *p); - f->dump_object("public_addrs", get_addrs(*p)); - // compat: make these look like pre-nautilus entity_addr_t - f->dump_stream("addr") << get_addrs(*p).get_legacy_str(); - f->dump_stream("public_addr") << get_addrs(*p).get_legacy_str(); - f->dump_unsigned("priority", get_priority(*p)); - f->dump_unsigned("weight", get_weight(*p)); - const auto &mi = mon_info.find(*p); - // we don't need to assert this validity as all the get_* functions did - f->dump_stream("crush_location") << mi->second.crush_loc; + f->dump_int("rank", rank++); + info.dump(f); f->close_section(); } f->close_section(); diff --git a/src/mon/MonMap.h b/src/mon/MonMap.h index 79ceaed2843..4585a6f265b 100644 --- a/src/mon/MonMap.h +++ b/src/mon/MonMap.h @@ -65,6 +65,8 @@ struct mon_info_t { uint16_t priority{0}; uint16_t weight{0}; + ceph::real_clock::time_point time_added = ceph::real_clock::zero(); + /** * The location of the monitor, in CRUSH hierarchy terms */ @@ -210,26 +212,16 @@ public: } } + mon_info_t const& get(std::string const& name) const { + return mon_info.at(name); + } + /** * Add new monitor to the monmap * * @param m monitor info of the new monitor */ - void add(const mon_info_t& m) { - ceph_assert(mon_info.count(m.name) == 0); - for (auto& a : m.public_addrs.v) { - ceph_assert(addr_mons.count(a) == 0); - } - mon_info[m.name] = m; - if (get_required_features().contains_all( - ceph::features::mon::FEATURE_NAUTILUS)) { - ranks.push_back(m.name); - ceph_assert(ranks.size() == mon_info.size()); - } else { - calc_legacy_ranks(); - } - calc_addr_mons(); - } + mon_info_t& add(mon_info_t&& m); /** * Add new monitor to the monmap @@ -237,9 +229,9 @@ public: * @param name Monitor name (i.e., 'foo' in 'mon.foo') * @param addr Monitor's public address */ - void add(const std::string &name, const entity_addrvec_t &addrv, + mon_info_t& add(const std::string &name, const entity_addrvec_t &addrv, uint16_t priority=0, uint16_t weight=0) { - add(mon_info_t(name, addrv, priority, weight)); + return add(mon_info_t(name, addrv, priority, weight)); } /** diff --git a/src/mon/MonmapMonitor.cc b/src/mon/MonmapMonitor.cc index 9cbc26cc802..a918803b4cc 100644 --- a/src/mon/MonmapMonitor.cc +++ b/src/mon/MonmapMonitor.cc @@ -692,10 +692,10 @@ bool MonmapMonitor::prepare_command(MonOpRequestRef op) * we can simply go ahead and add the monitor. */ - pending_map.add(name, addrs); - pending_map.mon_info[name].crush_loc = loc; + auto& info = pending_map.add(name, addrs); + info.crush_loc = loc; pending_map.last_changed = ceph_clock_now(); - ss << "adding mon." << name << " at " << addrs; + ss << "adding " << info; dout(0) << __func__ << " proposing new mon." << name << dendl; } else if (prefix == "mon remove" || @@ -1423,8 +1423,8 @@ bool MonmapMonitor::prepare_join(MonOpRequestRef op) } if (pending_map.contains(join->name)) pending_map.remove(join->name); - pending_map.add(join->name, join->addrs); - pending_map.mon_info[join->name].crush_loc = + auto& mon_info = pending_map.add(join->name, join->addrs); + mon_info.crush_loc = ((join->force_loc || existing_loc.empty()) ? join->crush_loc : existing_loc); pending_map.last_changed = ceph_clock_now();