Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mimic: crush/CrushWrapper: ensure crush_choose_arg_map.size == max_buckets #27082

Merged
merged 1 commit into from Apr 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions qa/workunits/mon/crush_ops.sh
Expand Up @@ -224,4 +224,16 @@ ceph osd crush rm fooo
ceph osd crush rm barr
ceph osd crush weight-set rm-compat

# this sequence would crash at one point
ceph osd crush weight-set create-compat
ceph osd crush add-bucket r1 rack root=default
for f in `seq 1 32`; do
ceph osd crush add-bucket h$f host rack=r1
done
for f in `seq 1 32`; do
ceph osd crush rm h$f
done
ceph osd crush rm r1
ceph osd crush weight-set rm-compat

echo OK
20 changes: 12 additions & 8 deletions src/crush/CrushWrapper.cc
Expand Up @@ -408,9 +408,11 @@ void CrushWrapper::update_choose_args(CephContext *cct)
{
for (auto& i : choose_args) {
crush_choose_arg_map &arg_map = i.second;
assert(arg_map.size == (unsigned)crush->max_buckets);
unsigned positions = get_choose_args_positions(arg_map);
for (int j = 0; j < crush->max_buckets; ++j) {
crush_bucket *b = crush->buckets[j];
assert(j < (int)arg_map.size);
auto& carg = arg_map.args[j];
// strip out choose_args for any buckets that no longer exist
if (!b || b->alg != CRUSH_BUCKET_STRAW2) {
Expand Down Expand Up @@ -2308,21 +2310,22 @@ int CrushWrapper::add_bucket(
int pos = -1 - *idout;
for (auto& p : choose_args) {
crush_choose_arg_map& cmap = p.second;
unsigned new_size = crush->max_buckets;
if (cmap.args) {
if ((int)cmap.size <= pos) {
if ((int)cmap.size < crush->max_buckets) {
cmap.args = static_cast<crush_choose_arg*>(realloc(
cmap.args,
sizeof(crush_choose_arg) * (pos + 1)));
sizeof(crush_choose_arg) * new_size));
assert(cmap.args);
memset(&cmap.args[cmap.size], 0,
sizeof(crush_choose_arg) * (pos + 1 - cmap.size));
cmap.size = pos + 1;
sizeof(crush_choose_arg) * (new_size - cmap.size));
cmap.size = new_size;
}
} else {
cmap.args = static_cast<crush_choose_arg*>(calloc(sizeof(crush_choose_arg),
pos + 1));
new_size));
assert(cmap.args);
cmap.size = pos + 1;
cmap.size = new_size;
}
if (size > 0) {
int positions = get_choose_args_positions(cmap);
Expand All @@ -2338,6 +2341,7 @@ int CrushWrapper::add_bucket(
}
}
}
assert(crush->max_buckets == (int)cmap.size);
}
return r;
}
Expand Down Expand Up @@ -2571,8 +2575,8 @@ int CrushWrapper::device_class_clone(
// set up choose_args for the new bucket.
for (auto& w : choose_args) {
crush_choose_arg_map& cmap = w.second;
if (-1-bno >= (int)cmap.size) {
unsigned new_size = -1-bno + 1;
if (crush->max_buckets > (int)cmap.size) {
unsigned new_size = crush->max_buckets;
cmap.args = static_cast<crush_choose_arg*>(realloc(cmap.args,
new_size * sizeof(cmap.args[0])));
assert(cmap.args);
Expand Down