Skip to content

Commit

Permalink
Objecter: resend linger ops on any interval change
Browse files Browse the repository at this point in the history
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 cb9262a)

Conflicts:
	src/osd/osd_types.cc
	src/osdc/Objecter.cc
            Minor differences.
  • Loading branch information
jdurgin authored and smithfarm committed Jun 23, 2015
1 parent a44b7b4 commit 9206064
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 20 deletions.
42 changes: 34 additions & 8 deletions src/osd/osd_types.cc
Expand Up @@ -2205,19 +2205,45 @@ bool pg_interval_t::is_new_interval(
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,
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(
Expand Down
19 changes: 19 additions & 0 deletions src/osd/osd_types.h
Expand Up @@ -1752,6 +1752,25 @@ struct pg_interval_t {
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
*/
Expand Down
43 changes: 34 additions & 9 deletions src/osdc/Objecter.cc
Expand Up @@ -1483,9 +1483,29 @@ int Objecter::calc_target(op_target_t *t, bool any_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;

Expand All @@ -1497,15 +1517,20 @@ int Objecter::calc_target(op_target_t *t, bool any_change)

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;
Expand Down Expand Up @@ -1541,7 +1566,7 @@ int Objecter::calc_target(op_target_t *t, bool any_change)
assert(best >= 0);
osd = acting[best];
} else {
osd = primary;
osd = acting_primary;
}
t->osd = osd;
}
Expand Down
13 changes: 10 additions & 3 deletions src/osdc/Objecter.h
Expand Up @@ -1072,8 +1072,12 @@ class Objecter : public md_config_obs_t {
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;
Expand All @@ -1085,7 +1089,10 @@ class Objecter : public md_config_obs_t {
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)
Expand Down

0 comments on commit 9206064

Please sign in to comment.