]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: add the osd crush rename-bucket command
authorLoic Dachary <loic-201408@dachary.org>
Thu, 16 Oct 2014 00:14:53 +0000 (17:14 -0700)
committerLoic Dachary <loic-201408@dachary.org>
Thu, 16 Oct 2014 00:22:12 +0000 (17:22 -0700)
The synopsis is:

 osd crush rename-bucket name1 name2

It is made idempotent by interpreting -EALREADY as returned by
CrushWrapper::rename_bucket return as success.

The crush_rename_bucket method first checks for errors with
CrushWrapper::can_rename_bucket if there is no pending crush so that it
can return early and avoid the creation of a pending crush map.

If renaming is possible, CrushWrapper::rename_bucket is called on the
pending crush map (and creates it indirectly if it does not already
exists).

http://tracker.ceph.com/issues/9526 Fixes: #9526

Signed-off-by: Loic Dachary <loic-201408@dachary.org>
src/mon/MonCommands.h
src/mon/OSDMonitor.cc
src/mon/OSDMonitor.h

index 90c03da4f57f38352b389d8362879921f21c5992..a2e5d4b7ba44e2c2bc3cd3e5abf1e1d7256a5ce3 100644 (file)
@@ -400,6 +400,11 @@ COMMAND("osd crush add-bucket " \
        "name=type,type=CephString", \
        "add no-parent (probably root) crush bucket <name> of type <type>", \
        "osd", "rw", "cli,rest")
+COMMAND("osd crush rename-bucket " \
+       "name=srcname,type=CephString,goodchars=[A-Za-z0-9-_.] " \
+       "name=dstname,type=CephString,goodchars=[A-Za-z0-9-_.]", \
+       "rename bucket <srcname> to <dstname>", \
+       "osd", "rw", "cli,rest")
 COMMAND("osd crush set " \
        "name=id,type=CephOsdName " \
        "name=weight,type=CephFloat,range=0.0 " \
index 3c4f51ed6c486f83cbe6c04702ae141984bbd75d..f34a7e903a68baf715a4bd070a7166eea121bf52 100644 (file)
@@ -3195,6 +3195,38 @@ int OSDMonitor::prepare_new_pool(MPoolOp *m)
                            pg_pool_t::TYPE_REPLICATED, 0, ss);
 }
 
+int OSDMonitor::crush_rename_bucket(const string& srcname,
+                                   const string& dstname,
+                                   ostream *ss)
+{
+  int ret;
+  //
+  // Avoid creating a pending crush if it does not already exists and
+  // the rename would fail.
+  //
+  if (!_have_pending_crush()) {
+    ret = _get_stable_crush().can_rename_bucket(srcname,
+                                               dstname,
+                                               ss);
+    if (ret)
+      return ret;
+  }
+
+  CrushWrapper newcrush;
+  _get_pending_crush(newcrush);
+
+  ret = newcrush.rename_bucket(srcname,
+                              dstname,
+                              ss);
+  if (ret)
+    return ret;
+  
+  pending_inc.crush.clear();
+  newcrush.encode(pending_inc.crush);
+  *ss << "renamed bucket " << srcname << " into " << dstname;
+  return 0;
+}
+
 int OSDMonitor::crush_ruleset_create_erasure(const string &name,
                                             const string &profile,
                                             int *ruleset,
@@ -4091,6 +4123,18 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
     ss << "added bucket " << name << " type " << typestr
        << " to crush map";
     goto update;
+  } else if (prefix == "osd crush rename-bucket") {
+    string srcname, dstname;
+    cmd_getval(g_ceph_context, cmdmap, "srcname", srcname);
+    cmd_getval(g_ceph_context, cmdmap, "dstname", dstname);
+
+    err = crush_rename_bucket(srcname, dstname, &ss);
+    if (err == -EALREADY) // equivalent to success for idempotency
+      err = 0;
+    if (err)
+      goto reply;
+    else
+      goto update;
   } else if (osdid_present &&
             (prefix == "osd crush set" || prefix == "osd crush add")) {
     // <OsdName> is 'osd.<id>' or '<id>', passed as int64_t id
index 27a4eddf692fc4de474e08240661ede9d8f36af2..411650dcddcc7187862a29eac1ecfb6ab984435b 100644 (file)
@@ -261,6 +261,9 @@ private:
   bool prepare_pool_op (MPoolOp *m);
   bool prepare_pool_op_create (MPoolOp *m);
   bool prepare_pool_op_delete(MPoolOp *m);
+  int crush_rename_bucket(const string& srcname,
+                         const string& dstname,
+                         ostream *ss);
   int crush_ruleset_create_erasure(const string &name,
                                   const string &profile,
                                   int *ruleset,