]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
MDSMonitor: clean up use of pending fsmap in uncommitted ops 23013/head
authorPatrick Donnelly <pdonnell@redhat.com>
Mon, 7 May 2018 02:06:47 +0000 (19:06 -0700)
committerPatrick Donnelly <pdonnell@redhat.com>
Fri, 13 Jul 2018 00:12:20 +0000 (17:12 -0700)
Gist of this commit is to eliminate use of PaxosFSMap::get_working_fsmap which
allowed looking at the pending FSMap depending if it's the leader. Instead,
pass the FSMap being worked on to helper functions.

Also, ensure that we are only looking at the committed (i.e. current) FSMap
in the preprocess_* service methods.

Fixes: http://tracker.ceph.com/issues/23768
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
(cherry picked from commit dd68c2386cff7857c4466216db80cfdb4f0353b5)

Conflicts:
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h
src/mds/FSMap.h

src/mds/FSMap.h
src/mon/FSCommands.cc
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h
src/mon/PaxosFSMap.h

index 2e4613dcf34a78fcf41aabc835450029dc66f9d2..639a5d87ae4219a3f4ccc0d854735d6b622d7020 100644 (file)
@@ -407,6 +407,7 @@ public:
 
   size_t filesystem_count() const {return filesystems.size();}
   bool filesystem_exists(fs_cluster_id_t fscid) const {return filesystems.count(fscid) > 0;}
+  const std::shared_ptr<Filesystem> &get_filesystem(fs_cluster_id_t fscid) {return filesystems.at(fscid);}
   std::shared_ptr<const Filesystem> get_filesystem(fs_cluster_id_t fscid) const {return std::const_pointer_cast<const Filesystem>(filesystems.at(fscid));}
   std::shared_ptr<const Filesystem> get_filesystem(void) const {return std::const_pointer_cast<const Filesystem>(filesystems.begin()->second);}
   std::shared_ptr<const Filesystem> get_filesystem(boost::string_view name) const
index 54869d8b51e12e8db4da6f1474df5627e3bf63c3..3ce6f5565f00e320517ab1bf1a3d6241d54cb4ee 100644 (file)
@@ -631,7 +631,7 @@ class RemoveFilesystemHandler : public FileSystemCommandHandler
     for (const auto &gid : to_fail) {
       // Standby replays don't write, so it isn't important to
       // wait for an osdmap propose here: ignore return value.
-      mon->mdsmon()->fail_mds_gid(gid);
+      mon->mdsmon()->fail_mds_gid(fsmap, gid);
     }
 
     fsmap.erase_filesystem(fs->fscid);
index e2441be75b2c5486581e0c6bd6a07f0a3bb1d0d2..9bfe9dac5e2aa98f8775df7b5ab8f9b313b2238d 100644 (file)
@@ -189,7 +189,7 @@ void MDSMonitor::encode_pending(MonitorDBStore::TransactionRef t)
     t->erase(MDS_HEALTH_PREFIX, stringify(*i));
   }
   pending_daemon_health_rm.clear();
-  remove_from_metadata(t);
+  remove_from_metadata(pending, t);
 
   // health
   health_check_map_t new_checks;
@@ -341,7 +341,7 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
   MDSMap::mds_info_t info;
   epoch_t effective_epoch = 0;
 
-  const auto &fsmap = get_working_fsmap();
+  const auto &fsmap = get_fsmap();
 
   // check privileges, ignore if fails
   MonSession *session = m->get_session();
@@ -384,6 +384,10 @@ bool MDSMonitor::preprocess_beacon(MonOpRequestRef op)
       dout(7) << "mds_beacon " << *m << " is not in fsmap (state "
               << ceph_mds_state_name(state) << ")" << dendl;
 
+      /* We can't send an MDSMap this MDS was a part of because we no longer
+       * know which FS it was part of. Nor does this matter. Sending an empty
+       * MDSMap is sufficient for getting the MDS to respawn.
+       */
       MDSMap null_map;
       null_map.epoch = fsmap.epoch;
       null_map.compat = fsmap.compat;
@@ -479,25 +483,26 @@ bool MDSMonitor::preprocess_offload_targets(MonOpRequestRef op)
   MMDSLoadTargets *m = static_cast<MMDSLoadTargets*>(op->get_req());
   dout(10) << "preprocess_offload_targets " << *m << " from " << m->get_orig_source() << dendl;
 
-  auto &fsmap = get_working_fsmap();
+  const auto &fsmap = get_fsmap();
   
   // check privileges, ignore message if fails
   MonSession *session = m->get_session();
   if (!session)
-    goto done;
+    goto ignore;
   if (!session->is_capable("mds", MON_CAP_X)) {
     dout(0) << "preprocess_offload_targets got MMDSLoadTargets from entity with insufficient caps "
            << session->caps << dendl;
-    goto done;
+    goto ignore;
   }
 
   if (fsmap.gid_exists(m->global_id) &&
       m->targets == fsmap.get_info_gid(m->global_id).export_targets)
-    goto done;
+    goto ignore;
 
   return false;
 
- done:
+ ignore:
+  mon->no_reply(op);
   return true;
 }
 
@@ -588,7 +593,7 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
         const MDSMap::mds_info_t &existing_info =
           pending.get_info_gid(existing);
         mon->clog->info() << existing_info.human_name() << " restarted";
-       fail_mds_gid(existing);
+       fail_mds_gid(pending, existing);
         failed_mds = true;
       }
       if (failed_mds) {
@@ -620,7 +625,6 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
           info.standby_for_name);
       if (leaderinfo && (leaderinfo->rank >= 0)) {
         const auto &fscid = pending.mds_roles.at(leaderinfo->global_id);
-        const auto &fs = pending.get_filesystem(fscid);
 
         pending.modify_daemon(gid, [fscid, leaderinfo](
               MDSMap::mds_info_t *info) {
@@ -735,7 +739,7 @@ bool MDSMonitor::prepare_beacon(MonOpRequestRef op)
         return false;
       }
 
-      fail_mds_gid(gid);
+      fail_mds_gid(pending, gid);
       assert(mon->osdmon()->is_writeable());
       request_proposal(mon->osdmon());
 
@@ -924,7 +928,7 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
   stringstream ss, ds;
 
   map<string, cmd_vartype> cmdmap;
-  const auto &fsmap = get_working_fsmap();
+  const auto &fsmap = get_fsmap();
 
   if (!cmdmap_from_json(m->cmd, &cmdmap, ss)) {
     // ss has reason for failure
@@ -937,7 +941,7 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
   cmd_getval(g_ceph_context, cmdmap, "prefix", prefix);
   string format;
   cmd_getval(g_ceph_context, cmdmap, "format", format, string("plain"));
-  boost::scoped_ptr<Formatter> f(Formatter::create(format));
+  std::unique_ptr<Formatter> f(Formatter::create(format));
 
   MonSession *session = m->get_session();
   if (!session) {
@@ -1002,7 +1006,7 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
     int64_t epocharg;
     epoch_t epoch;
 
-    const FSMap *fsmapp = &get_fsmap();
+    const FSMap *fsmapp = &fsmap;
     FSMap dummy;
     if (cmd_getval(g_ceph_context, cmdmap, "epoch", epocharg)) {
       epoch = epocharg;
@@ -1052,7 +1056,7 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
         f->open_object_section("mds");
         f->dump_string("name", info.name);
         std::ostringstream get_err;
-        r = dump_metadata(info.name, f.get(), get_err);
+        r = dump_metadata(fsmap, info.name, f.get(), get_err);
         if (r == -EINVAL || r == -ENOENT) {
           // Drop error, list what metadata we do have
           dout(1) << get_err.str() << dendl;
@@ -1070,7 +1074,7 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
     } else {
       // Dump a single daemon's metadata
       f->open_object_section("mds_metadata");
-      r = dump_metadata(who, f.get(), ss);
+      r = dump_metadata(fsmap, who, f.get(), ss);
       f->close_section();
     }
     f->flush(ds);
@@ -1143,41 +1147,31 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
   } else if (prefix == "fs ls") {
     if (f) {
       f->open_array_section("filesystems");
-      {
-        for (const auto &p : fsmap.filesystems) {
-          const auto &fs = p.second;
-          f->open_object_section("filesystem");
-          {
-            const MDSMap &mds_map = fs->mds_map;
-            f->dump_string("name", mds_map.fs_name);
-            /* Output both the names and IDs of pools, for use by
-             * humans and machines respectively */
-            f->dump_string("metadata_pool", mon->osdmon()->osdmap.get_pool_name(
-                  mds_map.metadata_pool));
-            f->dump_int("metadata_pool_id", mds_map.metadata_pool);
-            f->open_array_section("data_pool_ids");
-            {
-              for (auto dpi = mds_map.data_pools.begin();
-                   dpi != mds_map.data_pools.end(); ++dpi) {
-                f->dump_int("data_pool_id", *dpi);
-              }
-            }
-            f->close_section();
-
-            f->open_array_section("data_pools");
-            {
-                for (auto dpi = mds_map.data_pools.begin();
-                   dpi != mds_map.data_pools.end(); ++dpi) {
-                  const auto &name = mon->osdmon()->osdmap.get_pool_name(
-                      *dpi);
-                  f->dump_string("data_pool", name);
-                }
-            }
+      for (const auto &p : fsmap.filesystems) {
+        const auto &fs = p.second;
+        f->open_object_section("filesystem");
+        {
+          const MDSMap &mds_map = fs->mds_map;
+          f->dump_string("name", mds_map.fs_name);
+          /* Output both the names and IDs of pools, for use by
+           * humans and machines respectively */
+          f->dump_string("metadata_pool", mon->osdmon()->osdmap.get_pool_name(
+                mds_map.metadata_pool));
+          f->dump_int("metadata_pool_id", mds_map.metadata_pool);
+          f->open_array_section("data_pool_ids");
+          for (const auto &id : mds_map.data_pools) {
+            f->dump_int("data_pool_id", id);
+          }
+          f->close_section();
 
-            f->close_section();
+          f->open_array_section("data_pools");
+          for (const auto &id : mds_map.data_pools) {
+            const auto &name = mon->osdmon()->osdmap.get_pool_name(id);
+            f->dump_string("data_pool", name);
           }
           f->close_section();
         }
+        f->close_section();
       }
       f->close_section();
       f->flush(ds);
@@ -1190,8 +1184,8 @@ bool MDSMonitor::preprocess_command(MonOpRequestRef op)
         
         ds << "name: " << mds_map.fs_name << ", metadata pool: "
            << md_pool_name << ", data pools: [";
-        for (auto dpi : mds_map.data_pools) {
-          const string &pool_name = mon->osdmon()->osdmap.get_pool_name(dpi);
+        for (const auto &id : mds_map.data_pools) {
+          const string &pool_name = mon->osdmon()->osdmap.get_pool_name(id);
           ds << pool_name << " ";
         }
         ds << "]" << std::endl;
@@ -1215,11 +1209,9 @@ out:
     return false;
 }
 
-bool MDSMonitor::fail_mds_gid(mds_gid_t gid)
+bool MDSMonitor::fail_mds_gid(FSMap &fsmap, mds_gid_t gid)
 {
-  auto &pending = get_pending_fsmap_writeable();
-
-  const MDSMap::mds_info_t &info = pending.get_info_gid(gid);
+  const MDSMap::mds_info_t &info = fsmap.get_info_gid(gid);
   dout(10) << "fail_mds_gid " << gid << " mds." << info.name << " role " << info.rank << dendl;
 
   epoch_t blacklist_epoch = 0;
@@ -1229,7 +1221,7 @@ bool MDSMonitor::fail_mds_gid(mds_gid_t gid)
     blacklist_epoch = mon->osdmon()->blacklist(info.addr, until);
   }
 
-  pending.erase(gid, blacklist_epoch);
+  fsmap.erase(gid, blacklist_epoch);
   last_beacon.erase(gid);
   if (pending_daemon_health.count(gid)) {
     pending_daemon_health.erase(gid);
@@ -1239,14 +1231,12 @@ bool MDSMonitor::fail_mds_gid(mds_gid_t gid)
   return blacklist_epoch != 0;
 }
 
-mds_gid_t MDSMonitor::gid_from_arg(const std::string& arg, std::ostream &ss)
+mds_gid_t MDSMonitor::gid_from_arg(const FSMap &fsmap, const std::string &arg, std::ostream &ss)
 {
-  const auto &fsmap = get_working_fsmap();
-
   // Try parsing as a role
   mds_role_t role;
   std::ostringstream ignore_err;  // Don't spam 'ss' with parse_role errors
-  int r = parse_role(arg, &role, ignore_err);
+  int r = fsmap.parse_role(arg, &role, ignore_err);
   if (r == 0) {
     // See if a GID is assigned to this role
     const auto &fs = fsmap.get_filesystem(role.fscid);
@@ -1287,12 +1277,12 @@ mds_gid_t MDSMonitor::gid_from_arg(const std::string& arg, std::ostream &ss)
   return MDS_GID_NONE;
 }
 
-int MDSMonitor::fail_mds(std::ostream &ss, const std::string &arg,
-    MDSMap::mds_info_t *failed_info)
+int MDSMonitor::fail_mds(FSMap &fsmap, std::ostream &ss,
+    const std::string &arg, MDSMap::mds_info_t *failed_info)
 {
   assert(failed_info != nullptr);
 
-  mds_gid_t gid = gid_from_arg(arg, ss);
+  mds_gid_t gid = gid_from_arg(fsmap, arg, ss);
   if (gid == MDS_GID_NONE) {
     return 0;
   }
@@ -1302,9 +1292,9 @@ int MDSMonitor::fail_mds(std::ostream &ss, const std::string &arg,
 
   // Take a copy of the info before removing the MDS from the map,
   // so that the caller knows which mds (if any) they ended up removing.
-  *failed_info = get_pending_fsmap().get_info_gid(gid);
+  *failed_info = fsmap.get_info_gid(gid);
 
-  fail_mds_gid(gid);
+  fail_mds_gid(fsmap, gid);
   ss << "failed mds gid " << gid;
   assert(mon->osdmon()->is_writeable());
   request_proposal(mon->osdmon());
@@ -1365,7 +1355,7 @@ bool MDSMonitor::prepare_command(MonOpRequestRef op)
     }
   }
 
-  r = filesystem_command(op, prefix, cmdmap, ss);
+  r = filesystem_command(pending, op, prefix, cmdmap, ss);
   if (r >= 0) {
     goto out;
   } else if (r == -EAGAIN) {
@@ -1387,7 +1377,7 @@ bool MDSMonitor::prepare_command(MonOpRequestRef op)
     goto out;
   }
 
-  r = legacy_filesystem_command(op, prefix, cmdmap, ss);
+  r = legacy_filesystem_command(pending, op, prefix, cmdmap, ss);
 
   if (r == -ENOSYS && ss.str().empty()) {
     ss << "unrecognized command";
@@ -1414,25 +1404,8 @@ out:
   }
 }
 
-
-/**
- * Given one of the following forms:
- *   <fs name>:<rank>
- *   <fs id>:<rank>
- *   <rank>
- *
- * Parse into a mds_role_t.  The rank-only form is only valid
- * if legacy_client_ns is set.
- */
-int MDSMonitor::parse_role(
-    const std::string &role_str,
-    mds_role_t *role,
-    std::ostream &ss)
-{
-  return get_working_fsmap().parse_role(role_str, role, ss);
-}
-
 int MDSMonitor::filesystem_command(
+    FSMap &fsmap,
     MonOpRequestRef op,
     std::string const &prefix,
     map<string, cmd_vartype> &cmdmap,
@@ -1444,15 +1417,14 @@ int MDSMonitor::filesystem_command(
   string whostr;
   cmd_getval(g_ceph_context, cmdmap, "who", whostr);
 
-  auto &pending = get_pending_fsmap_writeable();
   if (prefix == "mds stop" ||
       prefix == "mds deactivate") {
     mds_role_t role;
-    r = parse_role(whostr, &role, ss);
+    r = fsmap.parse_role(whostr, &role, ss);
     if (r < 0 ) {
       return r;
     }
-    const auto &fs = pending.get_filesystem(role.fscid);
+    const auto &fs = fsmap.get_filesystem(role.fscid);
 
     if (!fs->mds_map.is_active(role.rank)) {
       r = -EEXIST;
@@ -1475,9 +1447,9 @@ int MDSMonitor::filesystem_command(
       r = 0;
       mds_gid_t gid = fs->mds_map.up.at(role.rank);
       ss << "telling mds." << role << " "
-         << pending.get_info_gid(gid).addr << " to deactivate";
+         << fsmap.get_info_gid(gid).addr << " to deactivate";
 
-      pending.modify_daemon(gid, [](MDSMap::mds_info_t *info) {
+      fsmap.modify_daemon(gid, [](MDSMap::mds_info_t *info) {
         info->state = MDSMap::STATE_STOPPING;
       });
     }
@@ -1494,8 +1466,8 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["state"]) << "'";
       return -EINVAL;
     }
-    if (pending.gid_exists(gid)) {
-      pending.modify_daemon(gid, [state](MDSMap::mds_info_t *info) {
+    if (fsmap.gid_exists(gid)) {
+      fsmap.modify_daemon(gid, [state](MDSMap::mds_info_t *info) {
         info->state = state;
       });
       ss << "set mds gid " << gid << " to state " << state << " "
@@ -1507,7 +1479,7 @@ int MDSMonitor::filesystem_command(
     cmd_getval(g_ceph_context, cmdmap, "who", who);
 
     MDSMap::mds_info_t failed_info;
-    r = fail_mds(ss, who, &failed_info);
+    r = fail_mds(fsmap, ss, who, &failed_info);
     if (r < 0 && r == -EAGAIN) {
       mon->osdmon()->wait_for_writeable(op, new C_RetryMessage(this, op));
       return -EAGAIN; // don't propose yet; wait for message to be retried
@@ -1525,18 +1497,18 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["gid"]) << "'";
       return -EINVAL;
     }
-    if (!pending.gid_exists(gid)) {
+    if (!fsmap.gid_exists(gid)) {
       ss << "mds gid " << gid << " dne";
       r = 0;
     } else {
-      const auto &info = pending.get_info_gid(gid);
+      const auto &info = fsmap.get_info_gid(gid);
       MDSMap::DaemonState state = info.state;
       if (state > 0) {
         ss << "cannot remove active mds." << info.name
            << " rank " << info.rank;
         return -EBUSY;
       } else {
-        pending.erase(gid, {});
+        fsmap.erase(gid, {});
         ss << "removed mds gid " << gid;
         return 0;
       }
@@ -1553,13 +1525,13 @@ int MDSMonitor::filesystem_command(
     std::string role_str;
     cmd_getval(g_ceph_context, cmdmap, "who", role_str);
     mds_role_t role;
-    int r = parse_role(role_str, &role, ss);
+    int r = fsmap.parse_role(role_str, &role, ss);
     if (r < 0) {
       ss << "invalid role '" << role_str << "'";
       return -EINVAL;
     }
 
-    pending.modify_filesystem(
+    fsmap.modify_filesystem(
         role.fscid,
         [role](std::shared_ptr<Filesystem> fs)
     {
@@ -1575,13 +1547,13 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["feature"]) << "'";
       return -EINVAL;
     }
-    if (pending.compat.compat.contains(f)) {
+    if (fsmap.compat.compat.contains(f)) {
       ss << "removing compat feature " << f;
-      CompatSet modified = pending.compat;
+      CompatSet modified = fsmap.compat;
       modified.compat.remove(f);
-      pending.update_compat(modified);
+      fsmap.update_compat(modified);
     } else {
-      ss << "compat feature " << f << " not present in " << pending.compat;
+      ss << "compat feature " << f << " not present in " << fsmap.compat;
     }
     r = 0;
   } else if (prefix == "mds compat rm_incompat") {
@@ -1591,25 +1563,25 @@ int MDSMonitor::filesystem_command(
          << cmd_vartype_stringify(cmdmap["feature"]) << "'";
       return -EINVAL;
     }
-    if (pending.compat.incompat.contains(f)) {
+    if (fsmap.compat.incompat.contains(f)) {
       ss << "removing incompat feature " << f;
-      CompatSet modified = pending.compat;
+      CompatSet modified = fsmap.compat;
       modified.incompat.remove(f);
-      pending.update_compat(modified);
+      fsmap.update_compat(modified);
     } else {
-      ss << "incompat feature " << f << " not present in " << pending.compat;
+      ss << "incompat feature " << f << " not present in " << fsmap.compat;
     }
     r = 0;
   } else if (prefix == "mds repaired") {
     std::string role_str;
     cmd_getval(g_ceph_context, cmdmap, "rank", role_str);
     mds_role_t role;
-    r = parse_role(role_str, &role, ss);
+    r = fsmap.parse_role(role_str, &role, ss);
     if (r < 0) {
       return r;
     }
 
-    bool modified = pending.undamaged(role.fscid, role.rank);
+    bool modified = fsmap.undamaged(role.fscid, role.rank);
     if (modified) {
       dout(4) << "repaired: restoring rank " << role << dendl;
     } else {
@@ -1627,12 +1599,11 @@ int MDSMonitor::filesystem_command(
 /**
  * Helper to legacy_filesystem_command
  */
-void MDSMonitor::modify_legacy_filesystem(
+void MDSMonitor::modify_legacy_filesystem(FSMap &fsmap,
     std::function<void(std::shared_ptr<Filesystem> )> fn)
 {
-  auto &pending_fsmap = get_pending_fsmap_writeable();
-  pending_fsmap.modify_filesystem(
-    pending_fsmap.legacy_client_fscid,
+  fsmap.modify_filesystem(
+    fsmap.legacy_client_fscid,
     fn
   );
 }
@@ -1649,6 +1620,7 @@ void MDSMonitor::modify_legacy_filesystem(
  * @retval < 0      An error has occurred; **ss** may have been set.
  */
 int MDSMonitor::legacy_filesystem_command(
+    FSMap &fsmap,
     MonOpRequestRef op,
     std::string const &prefix,
     map<string, cmd_vartype> &cmdmap,
@@ -1660,9 +1632,7 @@ int MDSMonitor::legacy_filesystem_command(
   string whostr;
   cmd_getval(g_ceph_context, cmdmap, "who", whostr);
 
-  auto &pending_fsmap = get_pending_fsmap_writeable();
-
-  assert (pending_fsmap.legacy_client_fscid != FS_CLUSTER_ID_NONE);
+  assert (fsmap.legacy_client_fscid != FS_CLUSTER_ID_NONE);
 
   if (prefix == "mds set_max_mds") {
     // NOTE: deprecated by "fs set max_mds"
@@ -1672,7 +1642,7 @@ int MDSMonitor::legacy_filesystem_command(
     }
 
     const MDSMap& mdsmap =
-      pending_fsmap.filesystems.at(pending_fsmap.legacy_client_fscid)->mds_map;
+      fsmap.filesystems.at(fsmap.legacy_client_fscid)->mds_map;
       
     if (!mdsmap.allows_multimds() &&
        maxmds > mdsmap.get_max_mds() &&
@@ -1686,7 +1656,7 @@ int MDSMonitor::legacy_filesystem_command(
       return -EINVAL;
     }
 
-    modify_legacy_filesystem(
+    modify_legacy_filesystem(fsmap,
         [maxmds](std::shared_ptr<Filesystem> fs)
     {
       fs->mds_map.set_max_mds(maxmds);
@@ -1696,7 +1666,7 @@ int MDSMonitor::legacy_filesystem_command(
     ss << "max_mds = " << maxmds;
   } else if (prefix == "mds cluster_down") {
     // NOTE: deprecated by "fs set cluster_down"
-    modify_legacy_filesystem(
+    modify_legacy_filesystem(fsmap,
         [](std::shared_ptr<Filesystem> fs)
     {
       fs->mds_map.set_flag(CEPH_MDSMAP_DOWN);
@@ -1705,7 +1675,7 @@ int MDSMonitor::legacy_filesystem_command(
     r = 0;
   } else if (prefix == "mds cluster_up") {
     // NOTE: deprecated by "fs set cluster_up"
-    modify_legacy_filesystem(
+    modify_legacy_filesystem(fsmap,
         [](std::shared_ptr<Filesystem> fs)
     {
       fs->mds_map.clear_flag(CEPH_MDSMAP_DOWN);
@@ -1794,9 +1764,9 @@ void MDSMonitor::check_sub(Subscription *sub)
     if (is_mds) {
       // What (if any) namespace are you assigned to?
       auto mds_info = fsmap.get_mds_info();
-      for (const auto &i : mds_info) {
-        if (i.second.addr == sub->session->inst.addr) {
-          mds_gid = i.first;
+      for (const auto &p : mds_info) {
+        if (p.second.addr == sub->session->inst.addr) {
+          mds_gid = p.first;
           fscid = fsmap.mds_roles.at(mds_gid);
         }
       }
@@ -1894,16 +1864,15 @@ void MDSMonitor::update_metadata(mds_gid_t gid,
   paxos->trigger_propose();
 }
 
-void MDSMonitor::remove_from_metadata(MonitorDBStore::TransactionRef t)
+void MDSMonitor::remove_from_metadata(const FSMap &fsmap, MonitorDBStore::TransactionRef t)
 {
   bool update = false;
-  for (map<mds_gid_t, Metadata>::iterator i = pending_metadata.begin();
-       i != pending_metadata.end(); ) {
-    if (!get_pending_fsmap().gid_exists(i->first)) {
-      pending_metadata.erase(i++);
+  for (auto it = pending_metadata.begin(); it != pending_metadata.end(); ) {
+    if (!fsmap.gid_exists(it->first)) {
+      it = pending_metadata.erase(it);
       update = true;
     } else {
-      ++i;
+      ++it;
     }
   }
   if (!update)
@@ -1927,7 +1896,7 @@ int MDSMonitor::load_metadata(map<mds_gid_t, Metadata>& m)
   return 0;
 }
 
-void MDSMonitor::count_metadata(const string& field, map<string,int> *out)
+void MDSMonitor::count_metadata(const std::string &field, map<string,int> *out)
 {
   map<mds_gid_t,Metadata> meta;
   load_metadata(meta);
@@ -1941,7 +1910,7 @@ void MDSMonitor::count_metadata(const string& field, map<string,int> *out)
   }
 }
 
-void MDSMonitor::count_metadata(const string& field, Formatter *f)
+void MDSMonitor::count_metadata(const std::string &field, Formatter *f)
 {
   map<string,int> by_val;
   count_metadata(field, &by_val);
@@ -1952,11 +1921,12 @@ void MDSMonitor::count_metadata(const string& field, Formatter *f)
   f->close_section();
 }
 
-int MDSMonitor::dump_metadata(const std::string &who, Formatter *f, ostream& err)
+int MDSMonitor::dump_metadata(const FSMap& fsmap, const std::string &who,
+    Formatter *f, ostream& err)
 {
   assert(f);
 
-  mds_gid_t gid = gid_from_arg(who, err);
+  mds_gid_t gid = gid_from_arg(fsmap, who, err);
   if (gid == MDS_GID_NONE) {
     return -EINVAL;
   }
@@ -1981,26 +1951,27 @@ int MDSMonitor::print_nodes(Formatter *f)
 {
   assert(f);
 
+  const auto &fsmap = get_fsmap();
+
   map<mds_gid_t, Metadata> metadata;
   if (int r = load_metadata(metadata)) {
     return r;
   }
 
   map<string, list<int> > mdses; // hostname => rank
-  for (map<mds_gid_t, Metadata>::iterator it = metadata.begin();
-       it != metadata.end(); ++it) {
-    const Metadata& m = it->second;
+  for (const auto &p : metadata) {
+    const mds_gid_t& gid = p.first;
+    const Metadata& m = p.second;
     Metadata::const_iterator hostname = m.find("hostname");
     if (hostname == m.end()) {
       // not likely though
       continue;
     }
-    const mds_gid_t gid = it->first;
-    if (!get_fsmap().gid_exists(gid)) {
+    if (!fsmap.gid_exists(gid)) {
       dout(5) << __func__ << ": GID " << gid << " not existent" << dendl;
       continue;
     }
-    const MDSMap::mds_info_t& mds_info = get_fsmap().get_info_gid(gid);
+    const MDSMap::mds_info_t& mds_info = fsmap.get_info_gid(gid);
     // FIXME: include filesystem name with rank here
     mdses[hostname->second].push_back(mds_info.rank);
   }
@@ -2013,41 +1984,45 @@ int MDSMonitor::print_nodes(Formatter *f)
  * If a cluster is undersized (with respect to max_mds), then
  * attempt to find daemons to grow it.
  */
-bool MDSMonitor::maybe_expand_cluster(std::shared_ptr<Filesystem> &fs)
+bool MDSMonitor::maybe_expand_cluster(FSMap &fsmap, fs_cluster_id_t fscid)
 {
-  bool do_propose = false;
-  auto &pending = get_pending_fsmap_writeable();
+  auto fs = fsmap.get_filesystem(fscid);
+  auto &mds_map = fs->mds_map;
 
   if (fs->mds_map.test_flag(CEPH_MDSMAP_DOWN)) {
-    return do_propose;
+    return false;
   }
 
-  while (fs->mds_map.get_num_in_mds() < size_t(fs->mds_map.get_max_mds()) &&
-        !fs->mds_map.is_degraded()) {
+  int in = mds_map.get_num_in_mds();
+  int max = mds_map.get_max_mds();
+
+  dout(20) << __func__ << " in " << in << " max " << max << dendl;
+
+  if (in < max) {
     mds_rank_t mds = mds_rank_t(0);
     string name;
-    while (fs->mds_map.is_in(mds)) {
+    while (mds_map.is_in(mds)) {
       mds++;
     }
-    mds_gid_t newgid = pending.find_replacement_for({fs->fscid, mds},
+    mds_gid_t newgid = fsmap.find_replacement_for({fscid, mds},
                          name, g_conf->mon_force_standby_active);
     if (newgid == MDS_GID_NONE) {
-      break;
+      return false;
     }
 
-    const auto &new_info = pending.get_info_gid(newgid);
+    const auto &new_info = fsmap.get_info_gid(newgid);
     dout(1) << "assigned standby " << new_info.addr
             << " as mds." << mds << dendl;
 
     mon->clog->info() << new_info.human_name() << " assigned to "
-                         "filesystem " << fs->mds_map.fs_name << " as rank "
-                      << mds << " (now has " << fs->mds_map.get_num_in_mds() + 1
+                         "filesystem " << mds_map.fs_name << " as rank "
+                      << mds << " (now has " << mds_map.get_num_in_mds() + 1
                       << " ranks)";
-    pending.promote(newgid, fs, mds);
-    do_propose = true;
+    fsmap.promote(newgid, fs, mds);
+    return true;
   }
 
-  return do_propose;
+  return false;
 }
 
 
@@ -2056,14 +2031,13 @@ bool MDSMonitor::maybe_expand_cluster(std::shared_ptr<Filesystem> &fs)
  * is available, fail this daemon (remove from map) and pass its
  * role to another daemon.
  */
-void MDSMonitor::maybe_replace_gid(mds_gid_t gid, const MDSMap::mds_info_t& info,
-    bool *mds_propose, bool *osd_propose)
+void MDSMonitor::maybe_replace_gid(FSMap &fsmap, mds_gid_t gid,
+    const MDSMap::mds_info_t& info, bool *mds_propose, bool *osd_propose)
 {
   assert(mds_propose != nullptr);
   assert(osd_propose != nullptr);
 
-  auto &pending = get_pending_fsmap_writeable();
-  const auto fscid = pending.mds_roles.at(gid);
+  const auto fscid = fsmap.mds_roles.at(gid);
 
   // We will only take decisive action (replacing/removing a daemon)
   // if we have some indicating that some other daemon(s) are successfully
@@ -2084,12 +2058,12 @@ void MDSMonitor::maybe_replace_gid(mds_gid_t gid, const MDSMap::mds_info_t& info
       info.state != MDSMap::STATE_STANDBY &&
       info.state != MDSMap::STATE_STANDBY_REPLAY &&
       may_replace &&
-      !pending.get_filesystem(fscid)->mds_map.test_flag(CEPH_MDSMAP_DOWN) &&
-      (sgid = pending.find_replacement_for({fscid, info.rank}, info.name,
+      !fsmap.get_filesystem(fscid)->mds_map.test_flag(CEPH_MDSMAP_DOWN) &&
+      (sgid = fsmap.find_replacement_for({fscid, info.rank}, info.name,
                 g_conf->mon_force_standby_active)) != MDS_GID_NONE)
   {
     
-    MDSMap::mds_info_t si = pending.get_info_gid(sgid);
+    MDSMap::mds_info_t si = fsmap.get_info_gid(sgid);
     dout(10) << " replacing " << gid << " " << info.addr << " mds."
       << info.rank << "." << info.inc
       << " " << ceph_mds_state_name(info.state)
@@ -2101,14 +2075,14 @@ void MDSMonitor::maybe_replace_gid(mds_gid_t gid, const MDSMap::mds_info_t& info
                       << " with standby " << si.human_name();
 
     // Remember what NS the old one was in
-    const fs_cluster_id_t fscid = pending.mds_roles.at(gid);
+    const fs_cluster_id_t fscid = fsmap.mds_roles.at(gid);
 
     // Remove the old one
-    *osd_propose |= fail_mds_gid(gid);
+    *osd_propose |= fail_mds_gid(fsmap, gid);
 
     // Promote the replacement
-    auto fs = pending.filesystems.at(fscid);
-    pending.promote(sgid, fs, info.rank);
+    auto fs = fsmap.filesystems.at(fscid);
+    fsmap.promote(sgid, fs, info.rank);
 
     *mds_propose = true;
   } else if ((info.state == MDSMap::STATE_STANDBY_REPLAY ||
@@ -2118,25 +2092,23 @@ void MDSMonitor::maybe_replace_gid(mds_gid_t gid, const MDSMap::mds_info_t& info
       << dendl;
     mon->clog->info() << "Standby " << info.human_name() << " is not "
                          "responding, dropping it";
-    fail_mds_gid(gid);
+    fail_mds_gid(fsmap, gid);
     *mds_propose = true;
   } else if (!info.laggy()) {
       dout(10) << " marking " << gid << " " << info.addr << " mds." << info.rank << "." << info.inc
         << " " << ceph_mds_state_name(info.state)
         << " laggy" << dendl;
-      pending.modify_daemon(info.global_id, [](MDSMap::mds_info_t *info) {
+      fsmap.modify_daemon(info.global_id, [](MDSMap::mds_info_t *info) {
           info->laggy_since = ceph_clock_now();
       });
       *mds_propose = true;
   }
 }
 
-bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> &fs)
+bool MDSMonitor::maybe_promote_standby(FSMap &fsmap, std::shared_ptr<Filesystem> &fs)
 {
   assert(!fs->mds_map.test_flag(CEPH_MDSMAP_DOWN));
 
-  auto &pending = get_pending_fsmap_writeable();
-
   bool do_propose = false;
 
   // have a standby take over?
@@ -2146,17 +2118,17 @@ bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> &fs)
     set<mds_rank_t>::iterator p = failed.begin();
     while (p != failed.end()) {
       mds_rank_t f = *p++;
-      mds_gid_t sgid = pending.find_replacement_for({fs->fscid, f}, {},
+      mds_gid_t sgid = fsmap.find_replacement_for({fs->fscid, f}, {},
           g_conf->mon_force_standby_active);
       if (sgid) {
-        const MDSMap::mds_info_t si = pending.get_info_gid(sgid);
+        const MDSMap::mds_info_t si = fsmap.get_info_gid(sgid);
         dout(0) << " taking over failed mds." << f << " with " << sgid
                 << "/" << si.name << " " << si.addr << dendl;
         mon->clog->info() << "Standby " << si.human_name()
                           << " assigned to filesystem " << fs->mds_map.fs_name
                           << " as rank " << f;
 
-        pending.promote(sgid, fs, f);
+        fsmap.promote(sgid, fs, f);
        do_propose = true;
       }
     }
@@ -2168,12 +2140,12 @@ bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> &fs)
     // them while perhaps-modifying standby_daemons during the loop
     // (if we promote anyone they are removed from standby_daemons)
     std::vector<mds_gid_t> standby_gids;
-    for (const auto &j : pending.standby_daemons) {
+    for (const auto &j : fsmap.standby_daemons) {
       standby_gids.push_back(j.first);
     }
 
     for (const auto &gid : standby_gids) {
-      const auto &info = pending.standby_daemons.at(gid);
+      const auto &info = fsmap.standby_daemons.at(gid);
       assert(info.state == MDSMap::STATE_STANDBY);
 
       if (!info.standby_replay) {
@@ -2192,14 +2164,14 @@ bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> &fs)
         // the standby_for_rank refers to: lookup via legacy_client_fscid
         mds_role_t target_role = {
           info.standby_for_fscid == FS_CLUSTER_ID_NONE ?
-            pending.legacy_client_fscid : info.standby_for_fscid,
+            fsmap.legacy_client_fscid : info.standby_for_fscid,
           info.standby_for_rank};
 
         // It is possible that the map contains a standby_for_fscid
         // that doesn't correspond to an existing filesystem, especially
         // if we loaded from a version with a bug (#17466)
         if (info.standby_for_fscid != FS_CLUSTER_ID_NONE
-            && !pending.filesystem_exists(info.standby_for_fscid)) {
+            && !fsmap.filesystem_exists(info.standby_for_fscid)) {
           derr << "gid " << gid << " has invalid standby_for_fscid "
                << info.standby_for_fscid << dendl;
           continue;
@@ -2207,11 +2179,9 @@ bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> &fs)
 
         // If we managed to resolve a full target role
         if (target_role.fscid != FS_CLUSTER_ID_NONE) {
-          const auto &fs = pending.get_filesystem(target_role.fscid);
+          const auto &fs = fsmap.get_filesystem(target_role.fscid);
           if (fs->mds_map.is_followable(target_role.rank)) {
-            do_propose |= try_standby_replay(
-                info,
-                *fs,
+            do_propose |= try_standby_replay(fsmap, info, *fs,
                 fs->mds_map.get_info(target_role.rank));
           }
         }
@@ -2220,7 +2190,7 @@ bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> &fs)
       }
 
       // check everyone
-      for (const auto &p : pending.filesystems) {
+      for (const auto &p : fsmap.filesystems) {
        if (info.standby_for_fscid != FS_CLUSTER_ID_NONE &&
            info.standby_for_fscid != p.first)
          continue;
@@ -2236,7 +2206,7 @@ bool MDSMonitor::maybe_promote_standby(std::shared_ptr<Filesystem> &fs)
               continue;   // we're supposed to follow someone else
             }
 
-            if (try_standby_replay(info, *fs, cand_info)) {
+            if (try_standby_replay(fsmap, info, *fs, cand_info)) {
              assigned = true;
               break;
             }
@@ -2258,11 +2228,7 @@ void MDSMonitor::tick()
   // make sure mds's are still alive
   // ...if i am an active leader
 
-  if (!is_active()) return;
-
-  dout(10) << get_working_fsmap() << dendl;
-
-  if (!is_leader()) return;
+  if (!is_active() || !is_leader()) return;
 
   auto &pending = get_pending_fsmap_writeable();
 
@@ -2272,11 +2238,11 @@ void MDSMonitor::tick()
 
   // expand mds cluster (add new nodes to @in)?
   for (auto &p : pending.filesystems) {
-    do_propose |= maybe_expand_cluster(p.second);
+    do_propose |= maybe_expand_cluster(pending, p.second->fscid);
   }
 
   mono_time now = mono_clock::now();
-  if (mono_clock::is_zero(last_tick)) {
+  if (last_tick == decltype(last_tick)::min()) {
     last_tick = now;
   }
   chrono::duration<double> since_last = now-last_tick;
@@ -2307,7 +2273,7 @@ void MDSMonitor::tick()
   // check beacon timestamps
   bool propose_osdmap = false;
   bool osdmap_writeable = mon->osdmon()->is_writeable();
-  for (auto it = last_beacon.begin(); it != last_beacon.end(); it++) {
+  for (auto it = last_beacon.begin(); it != last_beacon.end(); ) {
     mds_gid_t gid = it->first;
     auto beacon_info = it->second;
     chrono::duration<double> since_last = now-beacon_info.stamp;
@@ -2328,9 +2294,11 @@ void MDSMonitor::tick()
       // If the OSDMap is writeable, we can blacklist things, so we can
       // try failing any laggy MDS daemons.  Consider each one for failure.
       if (osdmap_writeable) {
-        maybe_replace_gid(gid, info, &do_propose, &propose_osdmap);
+        maybe_replace_gid(pending, gid, info, &do_propose, &propose_osdmap);
       }
     }
+
+    ++it;
   }
   if (propose_osdmap) {
     request_proposal(mon->osdmon());
@@ -2339,7 +2307,7 @@ void MDSMonitor::tick()
   for (auto &p : pending.filesystems) {
     auto &fs = p.second;
     if (!fs->mds_map.test_flag(CEPH_MDSMAP_DOWN)) {
-      do_propose |= maybe_promote_standby(fs);
+      do_propose |= maybe_promote_standby(pending, fs);
     }
   }
 
@@ -2354,6 +2322,7 @@ void MDSMonitor::tick()
  * ainfo: the would-be leader
  */
 bool MDSMonitor::try_standby_replay(
+    FSMap &fsmap,
     const MDSMap::mds_info_t& finfo,
     const Filesystem &leader_fs,
     const MDSMap::mds_info_t& ainfo)
@@ -2365,7 +2334,7 @@ bool MDSMonitor::try_standby_replay(
   } else {
     // Assign the new role to the standby
     dout(10) << "  setting to follow mds rank " << ainfo.rank << dendl;
-    get_pending_fsmap_writeable().assign_standby_replay(finfo.global_id, leader_fs.fscid, ainfo.rank);
+    fsmap.assign_standby_replay(finfo.global_id, leader_fs.fscid, ainfo.rank);
     return true;
   }
 }
index ec9cd14d037cbbfb66f40082cd4d5884bbdb22fc..e83df726340653103b238de71120474f1b5f8ce6 100644 (file)
@@ -64,7 +64,7 @@ class MDSMonitor : public PaxosService, public PaxosFSMap {
   /**
    * Return true if a blacklist was done (i.e. OSD propose needed)
    */
-  bool fail_mds_gid(mds_gid_t gid);
+  bool fail_mds_gid(FSMap &fsmap, mds_gid_t gid);
 
   bool is_leader() const override { return mon->is_leader(); }
 
@@ -85,25 +85,24 @@ class MDSMonitor : public PaxosService, public PaxosFSMap {
   void get_health(list<pair<health_status_t,string> >& summary,
                  list<pair<health_status_t,string> > *detail,
                  CephContext *cct) const override;
-  int fail_mds(std::ostream &ss, const std::string &arg,
+  int fail_mds(FSMap &fsmap, std::ostream &ss,
+      const std::string &arg,
       MDSMap::mds_info_t *failed_info);
 
   bool preprocess_command(MonOpRequestRef op);
   bool prepare_command(MonOpRequestRef op);
 
-  int parse_role(
-      const std::string &role_str,
-      mds_role_t *role,
-      std::ostream &ss);
-
   void modify_legacy_filesystem(
+      FSMap &fsmap,
       std::function<void(std::shared_ptr<Filesystem> )> fn);
   int legacy_filesystem_command(
+      FSMap &fsmap,
       MonOpRequestRef op,
       std::string const &prefix,
       map<string, cmd_vartype> &cmdmap,
       std::stringstream &ss);
   int filesystem_command(
+      FSMap &fsmap,
       MonOpRequestRef op,
       std::string const &prefix,
       map<string, cmd_vartype> &cmdmap,
@@ -118,37 +117,35 @@ class MDSMonitor : public PaxosService, public PaxosFSMap {
   };
   map<mds_gid_t, beacon_info_t> last_beacon;
 
-  bool try_standby_replay(
-      const MDSMap::mds_info_t& finfo,
-      const Filesystem &leader_fs,
-      const MDSMap::mds_info_t& ainfo);
+  bool try_standby_replay(FSMap &fsmap, const MDSMap::mds_info_t& finfo,
+      const Filesystem &leader_fs, const MDSMap::mds_info_t& ainfo);
 
   std::list<std::shared_ptr<FileSystemCommandHandler> > handlers;
 
-  bool maybe_promote_standby(std::shared_ptr<Filesystem> &fs);
-  bool maybe_expand_cluster(std::shared_ptr<Filesystem> &fs);
-  void maybe_replace_gid(mds_gid_t gid, const MDSMap::mds_info_t& info,
-      bool *mds_propose, bool *osd_propose);
+  bool maybe_promote_standby(FSMap &fsmap, std::shared_ptr<Filesystem> &fs);
+  bool maybe_expand_cluster(FSMap &fsmap, fs_cluster_id_t fscid);
+  void maybe_replace_gid(FSMap &fsmap, mds_gid_t gid,
+      const MDSMap::mds_info_t& info, bool *mds_propose, bool *osd_propose);
   void tick() override;     // check state, take actions
 
-  int dump_metadata(const string& who, Formatter *f, ostream& err);
+  int dump_metadata(const FSMap &fsmap, const std::string &who, Formatter *f,
+      ostream& err);
 
   void update_metadata(mds_gid_t gid, const Metadata& metadata);
-  void remove_from_metadata(MonitorDBStore::TransactionRef t);
+  void remove_from_metadata(const FSMap &fsmap, MonitorDBStore::TransactionRef t);
   int load_metadata(map<mds_gid_t, Metadata>& m);
-  void count_metadata(const string& field, Formatter *f);
+  void count_metadata(const std::string& field, Formatter *f);
 public:
-  void count_metadata(const string& field, map<string,int> *out);
+  void count_metadata(const std::string& field, map<string,int> *out);
 protected:
 
   // MDS daemon GID to latest health state from that GID
   std::map<uint64_t, MDSHealth> pending_daemon_health;
   std::set<uint64_t> pending_daemon_health_rm;
 
-
   map<mds_gid_t, Metadata> pending_metadata;
 
-  mds_gid_t gid_from_arg(const std::string& arg, std::ostream& err);
+  mds_gid_t gid_from_arg(const FSMap &fsmap, const std::string &arg, std::ostream& err);
 
   // When did the mon last call into our tick() method?  Used for detecting
   // when the mon was not updating us for some period (e.g. during slow
index 8d7c8c1f1cc7dc0edf888a57d64b572d4adca103..e1ee081424de6164eb4871537c6660dd40f18c1d 100644 (file)
@@ -32,15 +32,6 @@ public:
 protected:
   FSMap &get_pending_fsmap_writeable() { assert(is_leader()); return pending_fsmap; }
 
-  /* get_working_fsmap returns the "relevant" version of the fsmap (see MDSMonitor.cc history)
-   * used depending in helper methods of MDSMonitor.cc.
-   *
-   * This is technically evil and will be removed in the future.
-   *
-   * See discussion: https://github.com/ceph/ceph/pull/21458#discussion_r182081366
-   */
-  const FSMap &get_working_fsmap() const { return is_leader() ? pending_fsmap : fsmap; }
-
   FSMap &create_pending() {
     assert(is_leader());
     pending_fsmap = fsmap;