From 5f795631973407fc9ee39f3c52e7f905e4711ff8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 12 May 2017 17:39:14 -0400 Subject: crush: implement swap_bucket Swap contents between buckets. Signed-off-by: Sage Weil --- src/crush/CrushWrapper.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/crush/CrushWrapper.h | 20 ++++++++++++++++++++ 2 files changed, 66 insertions(+) (limited to 'src/crush') diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index ee6db9bc629..b4319ce33e4 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -790,6 +790,52 @@ int CrushWrapper::move_bucket(CephContext *cct, int id, const map return insert_item(cct, id, bucket_weight / (float)0x10000, id_name, loc); } +int CrushWrapper::swap_bucket(CephContext *cct, int src, int dst) +{ + if (src >= 0 || dst >= 0) + return -EINVAL; + if (!item_exists(src) || !item_exists(dst)) + return -EINVAL; + crush_bucket *a = get_bucket(src); + crush_bucket *b = get_bucket(dst); + unsigned aw = a->weight; + unsigned bw = b->weight; + + // swap weights + adjust_item_weight(cct, a->id, bw); + adjust_item_weight(cct, b->id, aw); + + // swap items + map tmp; + unsigned as = a->size; + unsigned bs = b->size; + for (unsigned i = 0; i < as; ++i) { + int item = a->items[0]; + int itemw = crush_get_bucket_item_weight(a, 0); + tmp[item] = itemw; + crush_bucket_remove_item(crush, a, item); + } + assert(a->size == 0); + assert(b->size == bs); + for (unsigned i = 0; i < bs; ++i) { + int item = b->items[0]; + int itemw = crush_get_bucket_item_weight(b, 0); + crush_bucket_remove_item(crush, b, item); + crush_bucket_add_item(crush, a, item, itemw); + } + assert(a->size == bs); + assert(b->size == 0); + for (auto t : tmp) { + crush_bucket_add_item(crush, b, t.first, t.second); + } + assert(a->size == bs); + assert(b->size == as); + + // swap names + swap_names(src, dst); + return 0; +} + int CrushWrapper::link_bucket(CephContext *cct, int id, const map& loc) { if (choose_args.size() > 0) { diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index c47a5badc41..dde6d4c63c0 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -402,6 +402,16 @@ public: name_rmap[name] = i; return 0; } + void swap_names(int a, int b) { + string an = name_map[a]; + string bn = name_map[b]; + name_map[a] = bn; + name_map[b] = an; + if (have_rmaps) { + name_rmap[an] = b; + name_rmap[bn] = a; + } + } bool id_has_class(int i) { int idout; int classout; @@ -651,6 +661,16 @@ public: */ int move_bucket(CephContext *cct, int id, const map& loc); + /** + * swap bucket contents of two buckets without touching bucket ids + * + * @param cct cct + * @param src bucket a + * @param dst bucket b + * @return 0 for success, negative on error + */ + int swap_bucket(CephContext *cct, int src, int dst); + /** * add a link to an existing bucket in the hierarchy to the new location * -- cgit v1.2.3