]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mon/OSDMonitor: add 'osd crush swap-bucket' command
authorSage Weil <sage@redhat.com>
Fri, 12 May 2017 21:40:00 +0000 (17:40 -0400)
committerSage Weil <sage@redhat.com>
Mon, 15 May 2017 13:15:59 +0000 (09:15 -0400)
Swap contents of two crush buckets.  Do it safely by default so that
the origin bucket has to be an orphan (unless forced).

Signed-off-by: Sage Weil <sage@redhat.com>
src/mon/MonCommands.h
src/mon/OSDMonitor.cc

index 970a30b43d846ba9f76aa09ca2fa8315269de781..c7b932690b91ed1d070a38b4680edccbf213443a 100644 (file)
@@ -512,6 +512,12 @@ COMMAND("osd crush move " \
        "name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=]", \
        "move existing entry for <name> to location <args>", \
        "osd", "rw", "cli,rest")
+COMMAND("osd crush swap-bucket " \
+       "name=source,type=CephString,goodchars=[A-Za-z0-9-_.] " \
+       "name=dest,type=CephString,goodchars=[A-Za-z0-9-_.] " \
+       "name=force,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
+       "swap existing bucket contents from (orphan) bucket <source> and <target>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush link " \
        "name=name,type=CephString " \
        "name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=]", \
index 9b82b4a9f993975b2270c4b964f857a504aa1129..4c61f98b29f6f9c3b603cf5d959b32323f0751a3 100644 (file)
@@ -6685,7 +6685,44 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
        err = 0;
       }
     } while (false);
-
+  } else if (prefix == "osd crush swap-bucket") {
+    string source, dest, force;
+    cmd_getval(g_ceph_context, cmdmap, "source", source);
+    cmd_getval(g_ceph_context, cmdmap, "dest", dest);
+    cmd_getval(g_ceph_context, cmdmap, "force", force);
+    CrushWrapper newcrush;
+    _get_pending_crush(newcrush);
+    if (!newcrush.name_exists(source)) {
+      ss << "source item " << source << " does not exist";
+      err = -ENOENT;
+      goto reply;
+    }
+    if (!newcrush.name_exists(dest)) {
+      ss << "dest item " << dest << " does not exist";
+      err = -ENOENT;
+      goto reply;
+    }
+    int sid = newcrush.get_item_id(source);
+    int did = newcrush.get_item_id(dest);
+    int sparent;
+    if (newcrush.get_immediate_parent_id(sid, &sparent) == 0 &&
+       force != "--yes-i-really-mean-it") {
+      ss << "source item " << source << " is not an orphan bucket; pass --yes-i-really-mean-it to proceed anyway";
+      err = -EPERM;
+      goto reply;
+    }
+    int r = newcrush.swap_bucket(g_ceph_context, sid, did);
+    if (r < 0) {
+      ss << "failed to swap bucket contents: " << cpp_strerror(r);
+      goto reply;
+    }
+    ss << "swapped bucket of " << source << " to " << dest;
+    pending_inc.crush.clear();
+    newcrush.encode(pending_inc.crush, mon->get_quorum_con_features());
+    wait_for_finished_proposal(op,
+                              new Monitor::C_Command(mon, op, err, ss.str(),
+                                                     get_last_committed() + 1));
+    return true;
   } else if (prefix == "osd crush link") {
     // osd crush link <name> <loc1> [<loc2> ...]
     string name;