Watch/notify ops need to be resent after a pg split occurs, as well as
a few other circumstances that the existing objecter checks did not
catch.
Refactor the check the OSD uses for this to add a version taking the
more basic types instead of the whole OSD map, and stash the needed
info when an op is sent.
Fixes: #9806
Backport: giant, firefly, dumpling
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
(cherry picked from commit
cb9262abd7fd5f0a9f583bd34e4c425a049e56ce)
Conflicts:
src/osd/osd_types.cc
src/osdc/Objecter.cc
Minor differences.
int new_up_primary,
const vector<int> &old_up,
const vector<int> &new_up,
- OSDMapRef osdmap,
- OSDMapRef lastmap,
- int64_t pool_id,
+ int old_min_size,
+ int new_min_size,
+ unsigned old_pg_num,
+ unsigned new_pg_num,
pg_t pgid) {
return old_acting_primary != new_acting_primary ||
new_acting != old_acting ||
old_up_primary != new_up_primary ||
new_up != old_up ||
- (!(lastmap->get_pools().count(pool_id))) ||
- (lastmap->get_pools().find(pool_id)->second.min_size !=
- osdmap->get_pools().find(pool_id)->second.min_size) ||
- pgid.is_split(lastmap->get_pg_num(pgid.pool()),
- osdmap->get_pg_num(pgid.pool()), 0);
+ old_min_size != new_min_size ||
+ pgid.is_split(old_pg_num, new_pg_num, 0);
+}
+
+bool pg_interval_t::is_new_interval(
+ int old_acting_primary,
+ int new_acting_primary,
+ const vector<int> &old_acting,
+ const vector<int> &new_acting,
+ int old_up_primary,
+ int new_up_primary,
+ const vector<int> &old_up,
+ const vector<int> &new_up,
+ OSDMapRef osdmap,
+ OSDMapRef lastmap,
+ int64_t pool_id,
+ pg_t pgid) {
+ return !(lastmap->get_pools().count(pgid.pool())) ||
+ is_new_interval(old_acting_primary,
+ new_acting_primary,
+ old_acting,
+ new_acting,
+ old_up_primary,
+ new_up_primary,
+ old_up,
+ new_up,
+ lastmap->get_pools().find(pgid.pool())->second.min_size,
+ osdmap->get_pools().find(pgid.pool())->second.min_size,
+ lastmap->get_pg_num(pgid.pool()),
+ osdmap->get_pg_num(pgid.pool()),
+ pgid);
}
bool pg_interval_t::check_new_interval(
void dump(Formatter *f) const;
static void generate_test_instances(list<pg_interval_t*>& o);
+ /**
+ * Determines whether there is an interval change
+ */
+ static bool is_new_interval(
+ int old_acting_primary,
+ int new_acting_primary,
+ const vector<int> &old_acting,
+ const vector<int> &new_acting,
+ int old_up_primary,
+ int new_up_primary,
+ const vector<int> &old_up,
+ const vector<int> &new_up,
+ int old_min_size,
+ int new_min_size,
+ unsigned old_pg_num,
+ unsigned new_pg_num,
+ pg_t pgid
+ );
+
/**
* Determines whether there is an interval change
*/
if (ret == -ENOENT)
return RECALC_OP_TARGET_POOL_DNE;
}
- int primary;
- vector<int> acting;
- osdmap->pg_to_acting_osds(pgid, &acting, &primary);
+
+ int min_size = pi->min_size;
+ unsigned pg_num = pi->get_pg_num();
+ int up_primary, acting_primary;
+ vector<int> up, acting;
+ osdmap->pg_to_up_acting_osds(pgid, &up, &up_primary,
+ &acting, &acting_primary);
+ if (any_change && pg_interval_t::is_new_interval(
+ t->acting_primary,
+ acting_primary,
+ t->acting,
+ acting,
+ t->up_primary,
+ up_primary,
+ t->up,
+ up,
+ t->min_size,
+ min_size,
+ t->pg_num,
+ pg_num,
+ pi->raw_pg_to_pg(pgid))) {
+ force_resend = true;
+ }
bool need_resend = false;
if (t->pgid != pgid ||
is_pg_changed(
- t->primary, t->acting, primary, acting, t->used_replica || any_change) ||
+ t->acting_primary, t->acting, acting_primary, acting,
+ t->used_replica || any_change) ||
force_resend) {
t->pgid = pgid;
t->acting = acting;
- t->primary = primary;
- ldout(cct, 10) << __func__ << " pgid " << pgid
- << " acting " << acting << dendl;
+ t->acting_primary = acting_primary;
+ t->up_primary = up_primary;
+ t->up = up;
+ t->min_size = min_size;
+ t->pg_num = pg_num;
+ ldout(cct, 10) << __func__ << " "
+ << " pgid " << pgid << " acting " << acting << dendl;
t->used_replica = false;
- if (primary == -1) {
+ if (acting_primary == -1) {
t->osd = -1;
} else {
int osd;
assert(best >= 0);
osd = acting[best];
} else {
- osd = primary;
+ osd = acting_primary;
}
t->osd = osd;
}
pg_t base_pgid; ///< explciti pg target, if any
pg_t pgid; ///< last pg we mapped to
- vector<int> acting; ///< acting for last pg we mapped to
- int primary; ///< primary for last pg we mapped to
+ unsigned pg_num; ///< last pg_num we mapped to
+ vector<int> up; ///< set of up osds for last pg we mapped to
+ vector<int> acting; ///< set of acting osds for last pg we mapped to
+ int up_primary; ///< primary for last pg we mapped to based on the up set
+ int acting_primary; ///< primary for last pg we mapped to based on the acting set
+ int min_size; ///< the min size of the pool when were were last mapped
bool used_replica;
bool paused;
base_oid(oid),
base_oloc(oloc),
precalc_pgid(false),
- primary(-1),
+ pg_num(0),
+ up_primary(-1),
+ acting_primary(-1),
+ min_size(-1),
used_replica(false),
paused(false),
osd(-1)