From: Mykola Golub Date: Sun, 15 Feb 2015 08:35:59 +0000 (+0200) Subject: mon: osd create: add optional 'id' parameter X-Git-Tag: v9.0.2~224^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=0d1e77039172df33d233b606a31e916b7f25e86a;p=ceph.git mon: osd create: add optional 'id' parameter Signed-off-by: Mykola Golub --- diff --git a/doc/install/manual-deployment.rst b/doc/install/manual-deployment.rst index aef4d64547e27..d7506ec8ba232 100644 --- a/doc/install/manual-deployment.rst +++ b/doc/install/manual-deployment.rst @@ -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. :: diff --git a/doc/man/8/ceph.rst b/doc/man/8/ceph.rst index a721e1aacac89..f9502215a1016 100644 --- a/doc/man/8/ceph.rst +++ b/doc/man/8/ceph.rst @@ -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 {} + ceph osd create {} {} Subcommand ``crush`` is used for CRUSH management. It uses some additional subcommands. diff --git a/doc/rados/operations/add-or-rm-osds.rst b/doc/rados/operations/add-or-rm-osds.rst index 159ff1b71f54e..bfb9ff71043ea 100644 --- a/doc/rados/operations/add-or-rm-osds.rst +++ b/doc/rados/operations/add-or-rm-osds.rst @@ -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. :: diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index c596362f332ae..125107afda32b 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -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 diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 0bfa1fc23e891..aa7e33b3050bc 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -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 " \ diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 306f84e1800a8..7d8aec126f1dc 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -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