summaryrefslogtreecommitdiffstats
path: root/src/crush
diff options
context:
space:
mode:
authorxie xingguo <xie.xingguo@zte.com.cn>2018-10-15 14:34:56 +0200
committerxie xingguo <xie.xingguo@zte.com.cn>2018-10-16 02:45:49 +0200
commitd7ff33e9fd994fced37e487b4eaf8f5cae1cfe58 (patch)
tree5ccc46d5cbba7614c48b5774d962b0db7a4931fa /src/crush
parentMerge PR #24494 into master (diff)
downloadceph-d7ff33e9fd994fced37e487b4eaf8f5cae1cfe58.tar.xz
ceph-d7ff33e9fd994fced37e487b4eaf8f5cae1cfe58.zip
crush: get "ceph osd crush class create/rm" back
This reverts a27fd9d25cb2819e25cc48b790c40afac0250464 and b863883ca783487401fde4f4480ed1d9b093363e. Quote form Sébastien Han: > IIRC at some point, we were able to create a device class from the CLI. Now it seems that the device class gets created when at least one OSD of a particular class starts. In ceph-ansible, we create pools after the initial monitors are up and we want to assign a device crush class on some of them. That's not possible at the moment since there no device class available yet. Also, someone might want to create its own device class. Something as crazy as running Filestore with a tmpfs osd store and might want to isolate them. I know it's a very limited use case, but still, it could be desired. See also https://www.spinics.net/lists/ceph-devel/msg41152.html Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
Diffstat (limited to 'src/crush')
-rw-r--r--src/crush/CrushWrapper.cc33
-rw-r--r--src/crush/CrushWrapper.h1
2 files changed, 34 insertions, 0 deletions
diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc
index d4585ce0ea0..0e8e688c87c 100644
--- a/src/crush/CrushWrapper.cc
+++ b/src/crush/CrushWrapper.cc
@@ -1536,6 +1536,39 @@ void CrushWrapper::get_subtree_of_type(int type, vector<int> *subtrees)
}
}
+bool CrushWrapper::class_is_in_use(int class_id, ostream *ss)
+{
+ list<unsigned> rules;
+ for (unsigned i = 0; i < crush->max_rules; ++i) {
+ crush_rule *r = crush->rules[i];
+ if (!r)
+ continue;
+ for (unsigned j = 0; j < r->len; ++j) {
+ if (r->steps[j].op == CRUSH_RULE_TAKE) {
+ int root = r->steps[j].arg1;
+ for (auto &p : class_bucket) {
+ auto& q = p.second;
+ if (q.count(class_id) && q[class_id] == root) {
+ rules.push_back(i);
+ }
+ }
+ }
+ }
+ }
+ if (rules.empty()) {
+ return false;
+ }
+ if (ss) {
+ ostringstream os;
+ for (auto &p: rules) {
+ os << "'" << get_rule_name(p) <<"',";
+ }
+ string out(os.str());
+ out.resize(out.size() - 1); // drop last ','
+ *ss << "still referenced by crush_rule(s): " << out;
+ }
+ return true;
+}
int CrushWrapper::rename_class(const string& srcname, const string& dstname)
{
diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h
index cbe487ce537..7e73b361661 100644
--- a/src/crush/CrushWrapper.h
+++ b/src/crush/CrushWrapper.h
@@ -1290,6 +1290,7 @@ public:
const std::set<int32_t>& used_ids,
int *clone,
map<int,map<int,vector<int>>> *cmap_item_weight);
+ bool class_is_in_use(int class_id, ostream *ss = nullptr);
int rename_class(const string& srcname, const string& dstname);
int populate_classes(
const std::map<int32_t, map<int32_t, int32_t>>& old_class_bucket);