]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: osd create: add optional 'id' parameter 3743/head
authorMykola Golub <mgolub@mirantis.com>
Sun, 15 Feb 2015 08:35:59 +0000 (10:35 +0200)
committerMykola Golub <mgolub@mirantis.com>
Sun, 12 Apr 2015 11:25:45 +0000 (14:25 +0300)
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
doc/install/manual-deployment.rst
doc/man/8/ceph.rst
doc/rados/operations/add-or-rm-osds.rst
qa/workunits/cephtool/test.sh
src/mon/MonCommands.h
src/mon/OSDMonitor.cc

index aef4d64547e277a6eb62524a38367032227ba0c7..d7506ec8ba232a14393813ce8e2311fd35d3f0d9 100644 (file)
@@ -360,7 +360,7 @@ OSDs with the long form procedure, execute the following on ``node2`` and
    OSD starts up. The following command will output the OSD number, which you 
    will need for subsequent steps. ::
        
-       ceph osd create [{uuid}]
+       ceph osd create [{uuid} [{id}]]
 
 
 #. Create the default directory on your new OSD. :: 
index a721e1aacac89cb12538299e41bf2a47bea45049..f9502215a1016fedc6fb866ed34b0eef6a7cf109 100644 (file)
@@ -536,11 +536,11 @@ Usage::
 
        ceph osd blocked-by
 
-Subcommand ``create`` creates new osd (with optional UUID).
+Subcommand ``create`` creates new osd (with optional UUID and ID).
 
 Usage::
 
-       ceph osd create {<uuid>}
+       ceph osd create {<uuid>} {<id>}
 
 Subcommand ``crush`` is used for CRUSH management. It uses some additional
 subcommands.
index 159ff1b71f54ec1f49f4ee6cdacbd8c9c829dffc..bfb9ff71043eaff4de65a4bae09c3357b76bd7d8 100644 (file)
@@ -73,8 +73,16 @@ weight).
    OSD starts up. The following command will output the OSD number, which you 
    will need for subsequent steps. ::
        
-       ceph osd create [{uuid}]
+       ceph osd create [{uuid} [{id}]]
 
+   If the optional parameter {id} is given it will be used as the OSD id.
+   Note, in this case the command may fail if the number is already in use.
+
+   .. warning:: In general, explicitly specifying {id} is not recommended.
+   IDs are allocated as an array, and skipping entries consumes some extra
+   memory. This can become significant if there are large gaps and/or
+   clusters are large. If {id} is not specified, the smallest available is
+   used.
 
 #. Create the default directory on your new OSD. :: 
 
index c596362f332aecc8526f5587a5944b5627fca1b1..125107afda32b88f9e6c3cf419624c0d765b9baa 100755 (executable)
@@ -956,6 +956,8 @@ function test_mon_osd()
   [ -s $f ]
   rm $f
   save=$(ceph osd getmaxosd | sed -e 's/max_osd = //' -e 's/ in epoch.*//')
+  [ "$save" -gt 0 ]
+  ceph osd setmaxosd $((save - 1)) 2>&1 | grep 'EBUSY'
   ceph osd setmaxosd 10
   ceph osd getmaxosd | grep 'max_osd = 10'
   ceph osd setmaxosd $save
@@ -969,6 +971,7 @@ function test_mon_osd()
 
   local old_osds=$(echo $(ceph osd ls))
   id=`ceph osd create`
+  ceph osd find $id
   ceph osd lost $id --yes-i-really-mean-it
   expect_false ceph osd setmaxosd $id
   local new_osds=$(echo $(ceph osd ls))
@@ -983,6 +986,56 @@ function test_mon_osd()
   ceph osd rm $id
 
   ceph osd
+
+  # reset max_osd.
+  ceph osd setmaxosd $id
+  ceph osd getmaxosd | grep "max_osd = $save"
+  local max_osd=$save
+
+  ceph osd create $uuid 0 2>&1 | grep 'EINVAL'
+  ceph osd create $uuid $((max_osd - 1)) 2>&1 | grep 'EINVAL'
+
+  id=`ceph osd create $uuid $max_osd`
+  [ "$id" = "$max_osd" ]
+  ceph osd find $id
+  max_osd=$((max_osd + 1))
+  ceph osd getmaxosd | grep "max_osd = $max_osd"
+
+  ceph osd create $uuid $((id - 1)) 2>&1 | grep 'EINVAL'
+  ceph osd create $uuid $((id + 1)) 2>&1 | grep 'EINVAL'
+  id2=`ceph osd create $uuid`
+  [ "$id" = "$id2" ]
+  id2=`ceph osd create $uuid $id`
+  [ "$id" = "$id2" ]
+
+  uuid=`uuidgen`
+  local gap_start=$max_osd
+  id=`ceph osd create $uuid $((gap_start + 100))`
+  [ "$id" = "$((gap_start + 100))" ]
+  max_osd=$((id + 1))
+  ceph osd getmaxosd | grep "max_osd = $max_osd"
+
+  ceph osd create $uuid $gap_start 2>&1 | grep 'EINVAL'
+
+  id=`ceph osd create`
+  [ "$id" = "$gap_start" ]
+  gap_start=$((gap_start + 1))
+
+  id=`ceph osd create $(uuidgen)`
+  [ "$id" = "$gap_start" ]
+  gap_start=$((gap_start + 1))
+
+  id=`ceph osd create $(uuidgen) $gap_start`
+  [ "$id" = "$gap_start" ]
+  gap_start=$((gap_start + 1))
+
+  local new_osds=$(echo $(ceph osd ls))
+  for id in $(echo $new_osds | sed -e "s/$old_osds//") ; do
+      [ $id -ge $save ]
+      ceph osd rm $id
+  done
+  ceph osd setmaxosd $save
+
   ceph osd ls
   ceph osd pool create data 10
   ceph osd lspools | grep data
index 0bfa1fc23e8913215971242f7edba9e6a77be08b..aa7e33b3050bc0ead5afb94286911383a7c19dec 100644 (file)
@@ -590,8 +590,9 @@ COMMAND("osd lost " \
        "mark osd as permanently lost. THIS DESTROYS DATA IF NO MORE REPLICAS EXIST, BE CAREFUL", \
        "osd", "rw", "cli,rest")
 COMMAND("osd create " \
-       "name=uuid,type=CephUUID,req=false", \
-       "create new osd (with optional UUID)", "osd", "rw", "cli,rest")
+       "name=uuid,type=CephUUID,req=false " \
+       "name=id,type=CephInt,range=0,req=false", \
+       "create new osd (with optional UUID and ID)", "osd", "rw", "cli,rest")
 COMMAND("osd blacklist " \
        "name=blacklistop,type=CephChoices,strings=add|rm " \
        "name=addr,type=CephEntityAddr " \
index 306f84e1800a80ad4f5e776b1262e63fbe11fb34..7d8aec126f1dc2854e90c13baf245390ff05fc14 100644 (file)
@@ -5796,11 +5796,23 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
   } else if (prefix == "osd create") {
     int i = -1;
 
+    // optional id provided?
+    int64_t id = -1;
+    if (cmd_getval(g_ceph_context, cmdmap, "id", id)) {
+      if (id < 0) {
+       ss << "invalid osd id value '" << id << "'";
+       err = -EINVAL;
+       goto reply;
+      }
+      dout(10) << " osd create got id " << id << dendl;
+    }
+
     // optional uuid provided?
     uuid_d uuid;
     string uuidstr;
     if (cmd_getval(g_ceph_context, cmdmap, "uuid", uuidstr)) {
       if (!uuid.parse(uuidstr.c_str())) {
+       ss << "invalid uuid value '" << uuidstr << "'";
        err = -EINVAL;
        goto reply;
       }
@@ -5808,6 +5820,11 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
       i = osdmap.identify_osd(uuid);
       if (i >= 0) {
        // osd already exists
+       if (id >= 0 && i != id) {
+         ss << "uuid " << uuidstr << " already in use for different id " << i;
+         err = -EINVAL;
+         goto reply;
+       }
        err = 0;
        if (f) {
          f->open_object_section("created_osd");
@@ -5820,12 +5837,32 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
        }
        goto reply;
       }
-      i = pending_inc.identify_osd(uuid);
-      if (i >= 0) {
+      // i < 0
+      if (id >= 0) {
+       if (osdmap.exists(id)) {
+         ss << "id " << id << " already in use and does not match uuid "
+            << uuid;
+         err = -EINVAL;
+         goto reply;
+       }
+       if (pending_inc.new_state.count(id)) {
+         // osd is about to exist
+         wait_for_finished_proposal(new C_RetryMessage(this, m));
+         return true;
+       }
+       i = id;
+      }
+      if (pending_inc.identify_osd(uuid) >= 0) {
        // osd is about to exist
        wait_for_finished_proposal(new C_RetryMessage(this, m));
        return true;
       }
+      if (i >= 0) {
+       // raise max_osd
+       if (osdmap.get_max_osd() <= i && pending_inc.new_max_osd <= i)
+         pending_inc.new_max_osd = i + 1;
+       goto done;
+      }
     }
 
     // allocate a new id