diff options
author | Sage Weil <sage@newdream.net> | 2012-05-02 12:08:26 -0700 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2012-05-02 14:55:53 -0700 |
commit | bfa7635162566ccbf3a3ab326a71024836a146f6 (patch) | |
tree | 9cf26496e8c4aa075036230719aa22162c99c4b9 | |
parent | eca7eac34af0468fe6d8c7db0f87d04c18dc51eb (diff) | |
download | ceph-bfa7635162566ccbf3a3ab326a71024836a146f6.tar.gz |
crush: add check_item_loc
The check_item_loc() method will take an item and position and tell you if
it matches the items current location. The matching is identical to that
used for insert_item, in that a specific location constraint match means
success, even if a less specific one does not match (e.g., rack=wrongrack,
host=correcthost will return true).
Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r-- | src/crush/CrushWrapper.cc | 53 | ||||
-rw-r--r-- | src/crush/CrushWrapper.h | 1 |
2 files changed, 54 insertions, 0 deletions
diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 13351d54d04..5473e60a85d 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -65,6 +65,59 @@ int CrushWrapper::remove_item(CephContext *cct, int item) return ret; } +/** + * see if item is located where we think it is + * + * @param cct cct + * @param item item id + * @param loc location to check (map of type to bucket names) + */ +bool CrushWrapper::check_item_loc(CephContext *cct, int item, map<string,string>& loc, + float *weight) // typename -> bucketname +{ + ldout(cct, 5) << "check_item_loc item " << item << " loc " << loc << dendl; + + int cur = item; + for (map<int,string>::const_iterator p = type_map.begin(); p != type_map.end(); p++) { + if (p->first == 0) + continue; + + if (loc.count(p->second) == 0) { + ldout(cct, 2) << "warning: did not specify location for '" << p->second << "' level (levels are " + << type_map << ")" << dendl; + continue; + } + + int id = get_item_id(loc[p->second].c_str()); + if (!id) { + ldout(cct, 5) << "check_item_loc bucket " << loc[p->second] << " of type " << p->second << " dne" << dendl; + return false; + } + + if (id >= 0) { + ldout(cct, 5) << "check_item_loc requested " << loc[p->second] << " for type " << p->second + << " is a device, not bucket" << dendl; + return false; + } + + crush_bucket *b = get_bucket(id); + assert(b); + + // make sure the item doesn't already exist in this bucket + for (unsigned j=0; j<b->size; j++) + if (b->items[j] == cur) { + ldout(cct, 2) << "check_item_loc " << cur << " exists in bucket " << b->id << dendl; + if (weight) + *weight = (float)crush_get_bucket_item_weight(b, j) / (float)0x10000; + return true; + } + return false; + } + + ldout(cct, 1) << "check_item_loc item " << item << " loc " << loc << dendl; + return false; +} + int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string name, map<string,string>& loc) // typename -> bucketname { diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 5376a78ffc9..25ada59d12e 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -164,6 +164,7 @@ public: void find_roots(set<int>& roots) const; + bool check_item_loc(CephContext *cct, int item, map<string,string>& loc, float *weight); int insert_item(CephContext *cct, int id, float weight, string name, map<string,string>& loc); int remove_item(CephContext *cct, int id); int adjust_item_weight(CephContext *cct, int id, int weight); |