]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/OSDMonitor: add 'osd repeer <pgid>' command 22940/head
authorSage Weil <sage@redhat.com>
Sun, 8 Jul 2018 16:00:12 +0000 (11:00 -0500)
committerSage Weil <sage@redhat.com>
Mon, 9 Jul 2018 21:33:11 +0000 (16:33 -0500)
Selecting force peering on a single PG.  In reality this probably induces
*2* interval changes.

Note that in the case of a single OSD cluster we can't actually force a
repeer on a single PG because the pg_temp code is pretty robust about
filtering out redundant or meaningless changes, so we can't pg_temp our
way into a new interval if there are no other OSDs to switch to and the
code also prevents an empty pg_temp.

Signed-off-by: Sage Weil <sage@redhat.com>
qa/workunits/cephtool/test.sh
src/mon/MonCommands.h
src/mon/Monitor.cc
src/mon/OSDMonitor.cc

index ac181ad3c3eb5065577f947af193b76a9b1b33fa..b7209de0ed93b5db6c37650dbbb40b7ed5952d42 100755 (executable)
@@ -1950,6 +1950,9 @@ function test_mon_pg()
   expect_false ceph osd pg-temp 1.0 asdf
   ceph osd pg-temp 1.0 # cleanup pg-temp
 
+  ceph pg repeer 1.0
+  expect_false ceph pg repeer 0.0   # pool 0 shouldn't exist anymore
+
   # don't test ceph osd primary-temp for now
 }
 
index 0f9d1c2cafe18caee1dd1a0ce9a950f2da242f71..eb9e55cba8e5bff7cf9c3c666eb249321dc829cc 100644 (file)
 
 COMMAND("pg map name=pgid,type=CephPgid", "show mapping of pg to osds", \
        "pg", "r", "cli,rest")
+COMMAND("pg repeer name=pgid,type=CephPgid", "force a PG to repeer",
+       "osd", "rw", "cli,rest")
 COMMAND("osd last-stat-seq name=id,type=CephOsdName", \
        "get the last pg stats sequence number reported for this osd", \
        "osd", "r", "cli,rest")
index 12518f34c892dab58c55a0306f00a34eeb01c4e2..2522e0eb3846db4f67f2d51ca549d5602e9f9115 100644 (file)
@@ -3126,7 +3126,9 @@ void Monitor::handle_command(MonOpRequestRef op)
     mdsmon()->dispatch(op);
     return;
   }
-  if ((module == "osd" || prefix == "pg map") &&
+  if ((module == "osd" ||
+       prefix == "pg map" ||
+       prefix == "pg repeer") &&
       prefix != "osd last-stat-seq") {
     osdmon()->dispatch(op);
     return;
index 5ef6d7e0bb6dc854fe9bd73efb06da1db5d93fd7..dfc91dc692043e13860ce3c744a97779b76b86fb 100644 (file)
@@ -10158,6 +10158,51 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
     pending_inc.new_primary_temp[pgid] = osd;
     ss << "set " << pgid << " primary_temp mapping to " << osd;
     goto update;
+  } else if (prefix == "pg repeer") {
+    pg_t pgid;
+    string pgidstr;
+    cmd_getval(cct, cmdmap, "pgid", pgidstr);
+    if (!pgid.parse(pgidstr.c_str())) {
+      ss << "invalid pgid '" << pgidstr << "'";
+      err = -EINVAL;
+      goto reply;
+    }
+    if (!osdmap.pg_exists(pgid)) {
+      ss << "pg '" << pgidstr << "' does not exist";
+      err = -ENOENT;
+      goto reply;
+    }
+    vector<int> acting;
+    int primary;
+    osdmap.pg_to_acting_osds(pgid, &acting, &primary);
+    if (primary < 0) {
+      err = -EAGAIN;
+      ss << "pg currently has no primary";
+      goto reply;
+    }
+    if (acting.size() > 1) {
+      // map to just primary; it will map back to what it wants
+      pending_inc.new_pg_temp[pgid] = { primary };
+    } else {
+      // hmm, pick another arbitrary osd to induce a change.  Note
+      // that this won't work if there is only one suitable OSD in the cluster.
+      int i;
+      bool done = false;
+      for (i = 0; i < osdmap.get_max_osd(); ++i) {
+       if (i == primary || !osdmap.is_up(i) || !osdmap.exists(i)) {
+         continue;
+       }
+       pending_inc.new_pg_temp[pgid] = { primary, i };
+       done = true;
+       break;
+      }
+      if (!done) {
+       err = -EAGAIN;
+       ss << "not enough up OSDs in the cluster to force repeer";
+       goto reply;
+      }
+    }
+    goto update;
   } else if (prefix == "osd pg-upmap" ||
              prefix == "osd rm-pg-upmap" ||
              prefix == "osd pg-upmap-items" ||