From: xie xingguo Date: Tue, 27 Jun 2017 12:24:59 +0000 (+0800) Subject: crush: fix potential class id collision X-Git-Tag: v12.1.1~42^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=906f0b5bcda450a95f20648c2312139aca5491d4;p=ceph.git crush: fix potential class id collision Signed-off-by: xie xingguo --- diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 012a065fbdc..15ce05139bc 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -1283,6 +1283,31 @@ int CrushWrapper::trim_roots_with_class(bool unused) return 0; } +int32_t CrushWrapper::_alloc_class_id() const { + if (class_name.empty()) { + return 0; + } + int32_t class_id = class_name.rbegin()->first + 1; + if (class_id >= 0) { + return class_id; + } + // wrapped, pick a random start and do exhaustive search + uint32_t upperlimit = numeric_limits::max() + 1; + class_id = rand() % upperlimit; + const auto start = class_id; + do { + if (!class_name.count(class_id)) { + return class_id; + } else { + class_id++; + if (class_id < 0) { + class_id = 0; + } + } + } while (class_id != start); + assert(0 == "no available class id"); +} + void CrushWrapper::reweight(CephContext *cct) { set roots; diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 56b26dbd075..5e3a8ea6da6 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -482,10 +482,12 @@ public: return 0; } + int32_t _alloc_class_id() const; + int get_or_create_class_id(const string& name) { int c = get_class_id(name); if (c < 0) { - int i = class_name.size(); + int i = _alloc_class_id(); class_name[i] = name; class_rname[name] = i; return i;