diff options
author | Xie Xingguo <xie.xingguo@zte.com.cn> | 2019-12-12 04:11:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-12 04:11:34 +0100 |
commit | c4d12bfef8fa9d06a77186ea3a401e0a4a795025 (patch) | |
tree | f45f68d841cf643c610fdca6407d201166563244 /src/crush | |
parent | Merge PR #32193 into master (diff) | |
parent | crush: remove invalid upmap items (diff) | |
download | ceph-c4d12bfef8fa9d06a77186ea3a401e0a4a795025.tar.xz ceph-c4d12bfef8fa9d06a77186ea3a401e0a4a795025.zip |
Merge pull request #32099 from hjwsm1989/wip-cancel-invalid-upmap-2
crush: remove invalid upmap items
Reviewed-by: xie xingguo <xie.xingguo@zte.com.cn>
Reviewed-by: David Zafman <dzafman@redhat.com>
Diffstat (limited to 'src/crush')
-rw-r--r-- | src/crush/CrushWrapper.cc | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 40f3e8e361e..ed766719508 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -931,14 +931,26 @@ int CrushWrapper::verify_upmap(CephContext *cct, << dendl; return -ENOENT; } + int root_bucket = 0; + int cursor = 0; + std::map<int, int> type_stack; for (unsigned step = 0; step < rule->len; ++step) { auto curstep = &rule->steps[step]; ldout(cct, 10) << __func__ << " step " << step << dendl; switch (curstep->op) { + case CRUSH_RULE_TAKE: + { + root_bucket = curstep->arg1; + } + break; case CRUSH_RULE_CHOOSELEAF_FIRSTN: case CRUSH_RULE_CHOOSELEAF_INDEP: { + int numrep = curstep->arg1; int type = curstep->arg2; + if (numrep <= 0) + numrep += pool_size; + type_stack.emplace(type, numrep); if (type == 0) // osd break; map<int, set<int>> osds_by_parent; // parent_of_desired_type -> osds @@ -968,10 +980,11 @@ int CrushWrapper::verify_upmap(CephContext *cct, { int numrep = curstep->arg1; int type = curstep->arg2; - if (type == 0) // osd - break; if (numrep <= 0) numrep += pool_size; + type_stack.emplace(type, numrep); + if (type == 0) // osd + break; set<int> parents_of_type; for (auto osd : up) { auto parent = get_parent_of_type(osd, type, rule_id); @@ -992,6 +1005,26 @@ int CrushWrapper::verify_upmap(CephContext *cct, } break; + case CRUSH_RULE_EMIT: + { + if (root_bucket < 0) { + int num_osds = 1; + for (auto &item : type_stack) { + num_osds *= item.second; + } + // validate the osd's in subtree + for (int c = 0; cursor < (int)up.size() && c < num_osds; ++cursor, ++c) { + int osd = up[cursor]; + if (!subtree_contains(root_bucket, osd)) { + lderr(cct) << __func__ << " osd " << osd << " not in bucket " << root_bucket << dendl; + return -EINVAL; + } + } + } + type_stack.clear(); + root_bucket = 0; + } + break; default: // ignore break; |