expect_false ceph osd crush rm bar # not empty
ceph osd crush unlink host2
+ceph osd crush add-bucket host-for-test host root=root-for-test rack=rack-for-test
+ceph osd tree | grep host-for-test
+ceph osd tree | grep rack-for-test
+ceph osd tree | grep root-for-test
+ceph osd crush rm host-for-test
+ceph osd crush rm rack-for-test
+ceph osd crush rm root-for-test
+
# reference foo and bar with a rule
ceph osd crush rule create-simple foo-rule foo host firstn
expect_false ceph osd crush rm foo
"osd", "rw", "cli,rest")
COMMAND("osd crush add-bucket " \
"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] " \
- "name=type,type=CephString", \
- "add no-parent (probably root) crush bucket <name> of type <type>", \
+ "name=type,type=CephString " \
+ "name=args,type=CephString,n=N,goodchars=[A-Za-z0-9-_.=],req=false", \
+ "add no-parent (probably root) crush bucket <name> of type <type> " \
+ "to location <args>", \
"osd", "rw", "cli,rest")
COMMAND("osd crush rename-bucket " \
"name=srcname,type=CephString,goodchars=[A-Za-z0-9-_.] " \
} else if (prefix == "osd crush add-bucket") {
// os crush add-bucket <name> <type>
string name, typestr;
+ vector<string> argvec;
cmd_getval(g_ceph_context, cmdmap, "name", name);
cmd_getval(g_ceph_context, cmdmap, "type", typestr);
+ cmd_getval(g_ceph_context, cmdmap, "args", argvec);
+ map<string,string> loc;
+ if (!argvec.empty()) {
+ CrushWrapper::parse_loc_map(argvec, &loc);
+ dout(0) << "will create and move bucket '" << name
+ << "' to location " << loc << dendl;
+ }
if (!_have_pending_crush() &&
_get_stable_crush().name_exists(name)) {
goto reply;
}
+ if (!loc.empty()) {
+ if (!newcrush.check_item_loc(g_ceph_context, bucketno, loc,
+ (int *)NULL)) {
+ err = newcrush.move_bucket(g_ceph_context, bucketno, loc);
+ if (err < 0) {
+ ss << "error moving bucket '" << name << "' to location " << loc;
+ goto reply;
+ }
+ } else {
+ ss << "no need to move item id " << bucketno << " name '" << name
+ << "' to location " << loc << " in crush map";
+ }
+ }
+
pending_inc.crush.clear();
newcrush.encode(pending_inc.crush, mon->get_quorum_con_features());
- ss << "added bucket " << name << " type " << typestr
- << " to crush map";
+ if (loc.empty()) {
+ ss << "added bucket " << name << " type " << typestr
+ << " to crush map";
+ } else {
+ ss << "added bucket " << name << " type " << typestr
+ << " to location " << loc;
+ }
goto update;
} else if (prefix == "osd crush rename-bucket") {
string srcname, dstname;
def test_crush_add_bucket(self):
self.assert_valid_command(['osd', 'crush', 'add-bucket',
'name', 'type'])
+ self.assert_valid_command(['osd', 'crush', 'add-bucket',
+ 'name', 'type', 'root=foo-root', 'host=foo-host'])
assert_equal({}, validate_command(sigdict, ['osd', 'crush']))
assert_equal({}, validate_command(sigdict, ['osd', 'crush',
'add-bucket']))
- assert_equal({}, validate_command(sigdict, ['osd', 'crush',
- 'add-bucket', 'name',
- 'type',
- 'toomany']))
assert_equal({}, validate_command(sigdict, ['osd', 'crush',
'add-bucket', '^^^',
'type']))