derr << __func__ << " " << hoid << " had no clone_snaps" << dendl;
}
}
- if (!is_delete && pg_log.get_missing().is_missing(recovery_info.soid) &&
- pg_log.get_missing().get_items().find(recovery_info.soid)->second.need > recovery_info.version) {
+ if (!is_delete && recovery_state.get_pg_log().get_missing().is_missing(recovery_info.soid) &&
+ recovery_state.get_pg_log().get_missing().get_items().find(recovery_info.soid)->second.need > recovery_info.version) {
ceph_assert(is_primary());
- const pg_log_entry_t *latest = pg_log.get_log().objects.find(recovery_info.soid)->second;
+ const pg_log_entry_t *latest = recovery_state.get_pg_log().get_log().objects.find(recovery_info.soid)->second;
if (latest->op == pg_log_entry_t::LOST_REVERT &&
latest->reverting_to == recovery_info.version) {
dout(10) << " got old revert version " << recovery_info.version
bool is_delete)
{
info.stats.stats.sum.add(stat_diff);
- missing_loc.recovered(soid);
+ recovery_state.object_recovered(soid);
publish_stats_to_osd();
dout(10) << "pushed " << soid << " to all replicas" << dendl;
map<hobject_t, ObjectContextRef>::iterator i = recovering.find(soid);
bool PrimaryLogPG::is_missing_object(const hobject_t& soid) const
{
- return pg_log.get_missing().get_items().count(soid);
+ return recovery_state.get_pg_log().get_missing().get_items().count(soid);
}
void PrimaryLogPG::maybe_kick_recovery(
{
eversion_t v;
bool work_started = false;
- if (!missing_loc.needs_recovery(soid, &v))
+ if (!recovery_state.get_missing_loc().needs_recovery(soid, &v))
return;
map<hobject_t, ObjectContextRef>::const_iterator p = recovering.find(soid);
if (p != recovering.end()) {
dout(7) << "object " << soid << " v " << v << ", already recovering." << dendl;
- } else if (missing_loc.is_unfound(soid)) {
+ } else if (recovery_state.get_missing_loc().is_unfound(soid)) {
dout(7) << "object " << soid << " v " << v << ", is unfound." << dendl;
} else {
dout(7) << "object " << soid << " v " << v << ", recovering." << dendl;
PGBackend::RecoveryHandle *h = pgbackend->open_recovery_op();
if (is_missing_object(soid)) {
recover_missing(soid, v, cct->_conf->osd_client_op_priority, h);
- } else if (missing_loc.is_deleted(soid)) {
+ } else if (recovery_state.get_missing_loc().is_deleted(soid)) {
prep_object_replica_deletes(soid, v, h, &work_started);
} else {
prep_object_replica_pushes(soid, v, h, &work_started);
*/
if (waiting_for_degraded_object.count(soid))
return true;
- if (pg_log.get_missing().get_items().count(soid))
+ if (recovery_state.get_pg_log().get_missing().get_items().count(soid))
return true;
ceph_assert(!get_acting_recovery_backfill().empty());
for (set<pg_shard_t>::iterator i = get_acting_recovery_backfill().begin();
PG_STATE_BACKFILL_TOOFULL))
return;
- if (pg_log.get_log().approx_size() <
+ if (recovery_state.get_pg_log().get_log().approx_size() <
cct->_conf->osd_max_pg_log_entries *
cct->_conf->osd_force_recovery_pg_log_entries_factor)
return;
// find the oldest missing object
- version_t min_version = pg_log.get_log().head.version;
+ version_t min_version = recovery_state.get_pg_log().get_log().head.version;
hobject_t soid;
- if (!pg_log.get_missing().get_rmissing().empty()) {
- min_version = pg_log.get_missing().get_rmissing().begin()->first;
- soid = pg_log.get_missing().get_rmissing().begin()->second;
+ if (!recovery_state.get_pg_log().get_missing().get_rmissing().empty()) {
+ min_version = recovery_state.get_pg_log().get_missing().get_rmissing().begin()->first;
+ soid = recovery_state.get_pg_log().get_missing().get_rmissing().begin()->second;
}
ceph_assert(!get_acting_recovery_backfill().empty());
for (set<pg_shard_t>::iterator it = get_acting_recovery_backfill().begin();
return -EROFS;
}
- uint64_t unfound = missing_loc.num_unfound();
+ uint64_t unfound = recovery_state.get_missing_loc().num_unfound();
if (!unfound) {
ss << "pg has no unfound objects";
return 0; // make command idempotent
offset.dump(f.get());
f->close_section();
}
- auto &needs_recovery_map = missing_loc.get_needs_recovery();
+ auto &needs_recovery_map = recovery_state.get_missing_loc()
+ .get_needs_recovery();
f->dump_int("num_missing", needs_recovery_map.size());
f->dump_int("num_unfound", get_num_unfound());
map<hobject_t, pg_missing_item>::const_iterator p =
{
f->open_array_section("objects");
int32_t num = 0;
- for (; p != needs_recovery_map.end() && num < cct->_conf->osd_command_max_records; ++p) {
- if (missing_loc.is_unfound(p->first)) {
+ for (; p != needs_recovery_map.end() &&
+ num < cct->_conf->osd_command_max_records;
+ ++p) {
+ if (recovery_state.get_missing_loc().is_unfound(p->first)) {
f->open_object_section("object");
{
f->open_object_section("oid");
p->second.dump(f.get()); // have, need keys
{
f->open_array_section("locations");
- for (set<pg_shard_t>::iterator r =
- missing_loc.get_locations(p->first).begin();
- r != missing_loc.get_locations(p->first).end();
- ++r)
- f->dump_stream("shard") << *r;
+ for (auto &&r : recovery_state.get_missing_loc().get_locations(
+ p->first)) {
+ f->dump_stream("shard") << r;
+ }
f->close_section();
}
f->close_section();
}
map<hobject_t, pg_missing_item>::const_iterator missing_iter =
- pg_log.get_missing().get_items().lower_bound(current);
+ recovery_state.get_pg_log().get_missing().get_items().lower_bound(current);
vector<hobject_t>::iterator ls_iter = sentries.begin();
hobject_t _max = hobject_t::get_max();
while (1) {
const hobject_t &mcand =
- missing_iter == pg_log.get_missing().get_items().end() ?
+ missing_iter == recovery_state.get_pg_log().get_missing().get_items().end() ?
_max :
missing_iter->first;
const hobject_t &lcand =
if (candidate.get_namespace() == cct->_conf->osd_hit_set_namespace)
continue;
- if (missing_loc.is_deleted(candidate))
+ if (recovery_state.get_missing_loc().is_deleted(candidate))
continue;
// skip wrong namespace
}
if (next.is_max() &&
- missing_iter == pg_log.get_missing().get_items().end() &&
+ missing_iter == recovery_state.get_pg_log().get_missing().get_items().end() &&
ls_iter == sentries.end()) {
result = 1;
break;
}
- ceph_assert(snapid == CEPH_NOSNAP || pg_log.get_missing().get_items().empty());
+ ceph_assert(snapid == CEPH_NOSNAP || recovery_state.get_pg_log().get_missing().get_items().empty());
map<hobject_t, pg_missing_item>::const_iterator missing_iter =
- pg_log.get_missing().get_items().lower_bound(current);
+ recovery_state.get_pg_log().get_missing().get_items().lower_bound(current);
vector<hobject_t>::iterator ls_iter = sentries.begin();
hobject_t _max = hobject_t::get_max();
while (1) {
const hobject_t &mcand =
- missing_iter == pg_log.get_missing().get_items().end() ?
+ missing_iter == recovery_state.get_pg_log().get_missing().get_items().end() ?
_max :
missing_iter->first;
const hobject_t &lcand =
if (candidate.get_namespace() != m->get_hobj().nspace)
continue;
- if (missing_loc.is_deleted(candidate))
+ if (recovery_state.get_missing_loc().is_deleted(candidate))
continue;
if (filter && !pgls_filter(filter, candidate, filter_out))
candidate.get_key()));
}
if (next.is_max() &&
- missing_iter == pg_log.get_missing().get_items().end() &&
+ missing_iter == recovery_state.get_pg_log().get_missing().get_items().end() &&
ls_iter == sentries.end()) {
result = 1;
}
}
if (can_backoff &&
(g_conf()->osd_backoff_on_degraded ||
- (g_conf()->osd_backoff_on_unfound && missing_loc.is_unfound(head)))) {
+ (g_conf()->osd_backoff_on_unfound &&
+ recovery_state.get_missing_loc().is_unfound(head)))) {
add_backoff(session, head, head);
maybe_kick_recovery(head);
} else {
if (cursor.is_complete()) {
// include reqids only in the final step. this is a bit fragile
// but it works...
- pg_log.get_log().get_object_reqids(ctx->obc->obs.oi.soid, 10,
+ recovery_state.get_pg_log().get_log().get_object_reqids(ctx->obc->obs.oi.soid, 10,
&reply_obj.reqids,
&reply_obj.reqid_return_codes);
dout(20) << " got reqids" << dendl;
uint64_t features = m->get_features();
object_copy_data_t reply_obj;
- pg_log.get_log().get_object_reqids(oid, 10, &reply_obj.reqids,
+ recovery_state.get_pg_log().get_log().get_object_reqids(oid, 10, &reply_obj.reqids,
&reply_obj.reqid_return_codes);
dout(20) << __func__ << " got reqids " << reply_obj.reqids << dendl;
encode(reply_obj, osd_op.outdata, features);
hobject_t next = soid;
next.snap = *p;
ceph_assert(next.snap < soid.snap);
- if (pg_log.get_missing().is_missing(next)) {
+ if (recovery_state.get_pg_log().get_missing().is_missing(next)) {
dout(10) << __func__ << " missing clone is " << next << dendl;
if (pmissing)
*pmissing = next;
void PrimaryLogPG::populate_obc_watchers(ObjectContextRef obc)
{
ceph_assert(is_active());
- auto it_objects = pg_log.get_log().objects.find(obc->obs.oi.soid);
+ auto it_objects = recovery_state.get_pg_log().get_log().objects.find(obc->obs.oi.soid);
ceph_assert((recovering.count(obc->obs.oi.soid) ||
!is_missing_object(obc->obs.oi.soid)) ||
- (it_objects != pg_log.get_log().objects.end() && // or this is a revert... see recover_primary()
+ (it_objects != recovery_state.get_pg_log().get_log().objects.end() && // or this is a revert... see recover_primary()
it_objects->second->op ==
pg_log_entry_t::LOST_REVERT &&
it_objects->second->reverting_to ==
bool can_create,
const map<string, bufferlist> *attrs)
{
- auto it_objects = pg_log.get_log().objects.find(soid);
+ auto it_objects = recovery_state.get_pg_log().get_log().objects.find(soid);
ceph_assert(
- attrs || !pg_log.get_missing().is_missing(soid) ||
+ attrs || !recovery_state.get_pg_log().get_missing().is_missing(soid) ||
// or this is a revert... see recover_primary()
- (it_objects != pg_log.get_log().objects.end() &&
+ (it_objects != recovery_state.get_pg_log().get_log().objects.end() &&
it_objects->second->op ==
pg_log_entry_t::LOST_REVERT));
ObjectContextRef obc = object_contexts.lookup(soid);
<< " snapset " << ssc->snapset
<< " maps to " << oid << dendl;
- if (pg_log.get_missing().is_missing(oid)) {
+ if (recovery_state.get_pg_log().get_missing().is_missing(oid)) {
dout(10) << __func__ << " " << oid << " @" << oid.snap
<< " snapset " << ssc->snapset
<< " " << oid << " is missing" << dendl;
hobject_t soid(oid.oid, oid.get_key(), ssc->snapset.clones[k], oid.get_hash(),
info.pgid.pool(), oid.get_namespace());
- if (pg_log.get_missing().is_missing(soid)) {
+ if (recovery_state.get_pg_log().get_missing().is_missing(soid)) {
dout(20) << __func__ << " " << soid << " missing, try again later"
<< dendl;
if (pmissing)
int priority,
PGBackend::RecoveryHandle *h)
{
- if (missing_loc.is_unfound(soid)) {
+ if (recovery_state.get_missing_loc().is_unfound(soid)) {
dout(7) << __func__ << " " << soid
<< " v " << v
<< " but it is unfound" << dendl;
return PULL_NONE;
}
- if (missing_loc.is_deleted(soid)) {
+ if (recovery_state.get_missing_loc().is_deleted(soid)) {
start_recovery_op(soid);
ceph_assert(!recovering.count(soid));
recovering.insert(make_pair(soid, ObjectContextRef()));
if (soid.snap && soid.snap < CEPH_NOSNAP) {
// do we have the head?
hobject_t head = soid.get_head();
- if (pg_log.get_missing().is_missing(head)) {
+ if (recovery_state.get_pg_log().get_missing().is_missing(head)) {
if (recovering.count(head)) {
dout(10) << " missing but already recovering head " << head << dendl;
return PULL_NONE;
} else {
int r = recover_missing(
- head, pg_log.get_missing().get_items().find(head)->second.need, priority,
+ head, recovery_state.get_pg_log().get_missing().get_items().find(head)->second.need, priority,
h);
if (r != PULL_NONE)
return PULL_HEAD;
{
eversion_t v;
pg_missing_item pmi;
- bool is_missing = pg_log.get_missing().is_missing(oid, &pmi);
+ bool is_missing = recovery_state.get_pg_log().get_missing().is_missing(oid, &pmi);
ceph_assert(is_missing);
v = pmi.have;
dout(10) << "pick_newest_available " << oid << " " << v << " on osd." << osd->whoami << " (local)" << dendl;
list<hobject_t> oids;
dout(30) << __func__ << ": log before:\n";
- pg_log.get_log().print(*_dout);
+ recovery_state.get_pg_log().get_log().print(*_dout);
*_dout << dendl;
mempool::osd_pglog::list<pg_log_entry_t> log_entries;
utime_t mtime = ceph_clock_now();
map<hobject_t, pg_missing_item>::const_iterator m =
- missing_loc.get_needs_recovery().begin();
+ recovery_state.get_missing_loc().get_needs_recovery().begin();
map<hobject_t, pg_missing_item>::const_iterator mend =
- missing_loc.get_needs_recovery().end();
+ recovery_state.get_missing_loc().get_needs_recovery().end();
ObcLockManager manager;
eversion_t v = get_next_version();
v.epoch = get_osdmap_epoch();
- uint64_t num_unfound = missing_loc.num_unfound();
+ uint64_t num_unfound = recovery_state.get_missing_loc().num_unfound();
while (m != mend) {
const hobject_t &oid(m->first);
- if (!missing_loc.is_unfound(oid)) {
+ if (!recovery_state.get_missing_loc().is_unfound(oid)) {
// We only care about unfound objects
++m;
continue;
// clear old locations - merge_new_log_entries will have
// handled rebuilding missing_loc for each of these
// objects if we have the RECOVERY_DELETES flag
- missing_loc.recovered(oid);
+ recovery_state.object_recovered(oid);
}
}
agent_setup();
}
-void PrimaryLogPG::plpg_on_new_interval()
-{
- dout(20) << __func__ << " checking missing set deletes flag. missing = " << pg_log.get_missing() << dendl;
-
- if (!pg_log.get_missing().may_include_deletes &&
- get_osdmap()->test_flag(CEPH_OSDMAP_RECOVERY_DELETES)) {
- pg_log.rebuild_missing_set_with_deletes(osd->store, ch, info);
- }
- ceph_assert(pg_log.get_missing().may_include_deletes == get_osdmap()->test_flag(CEPH_OSDMAP_RECOVERY_DELETES));
-}
-
void PrimaryLogPG::on_change(ObjectStore::Transaction *t)
{
dout(10) << __func__ << dendl;
// clear state. called on recovery completion AND cancellation.
void PrimaryLogPG::_clear_recovery_state()
{
- missing_loc.clear();
#ifdef DEBUG_RECOVERY_OIDS
recovering_oids.clear();
#endif
waiting_for_unreadable_object.erase(soid);
}
if (is_missing_object(soid))
- pg_log.set_last_requested(0); // get recover_primary to start over
+ recovery_state.set_last_requested(0);
finish_degraded_object(soid);
}
return have_unfound();
}
- const auto &missing = pg_log.get_missing();
+ const auto &missing = recovery_state.get_pg_log().get_missing();
uint64_t num_unfound = get_num_unfound();
ceph_assert(recovery_ops_active == 0);
dout(10) << __func__ << " needs_recovery: "
- << missing_loc.get_needs_recovery()
+ << recovery_state.get_missing_loc().get_needs_recovery()
<< dendl;
dout(10) << __func__ << " missing_loc: "
- << missing_loc.get_missing_locs()
+ << recovery_state.get_missing_loc().get_missing_locs()
<< dendl;
int unfound = get_num_unfound();
if (unfound) {
{
ceph_assert(is_primary());
- const auto &missing = pg_log.get_missing();
+ const auto &missing = recovery_state.get_pg_log().get_missing();
dout(10) << __func__ << " recovering " << recovering.size()
<< " in pg,"
PGBackend::RecoveryHandle *h = pgbackend->open_recovery_op();
map<version_t, hobject_t>::const_iterator p =
- missing.get_rmissing().lower_bound(pg_log.get_log().last_requested);
+ missing.get_rmissing().lower_bound(recovery_state.get_pg_log().get_log().last_requested);
while (p != missing.get_rmissing().end()) {
handle.reset_tp_timeout();
hobject_t soid;
version_t v = p->first;
- auto it_objects = pg_log.get_log().objects.find(p->second);
- if (it_objects != pg_log.get_log().objects.end()) {
+ auto it_objects = recovery_state.get_pg_log().get_log().objects.find(p->second);
+ if (it_objects != recovery_state.get_pg_log().get_log().objects.end()) {
latest = it_objects->second;
ceph_assert(latest->is_update() || latest->is_delete());
soid = latest->soid;
// only advance last_requested if we haven't skipped anything
if (!skipped)
- pg_log.set_last_requested(v);
+ recovery_state.set_last_requested(v);
}
pgbackend->run_recovery_op(h, get_recovery_op_priority());
osd->clog->error() << info.pgid << " missing primary copy of " << soid << ", unfound";
else
osd->clog->error() << info.pgid << " missing primary copy of " << soid
- << ", will try copies on " << missing_loc.get_locations(soid);
+ << ", will try copies on "
+ << recovery_state.get_missing_loc().get_locations(soid);
return uhoh;
}
handle.reset_tp_timeout();
const hobject_t soid(p->second);
- if (missing_loc.is_unfound(soid)) {
+ if (recovery_state.get_missing_loc().is_unfound(soid)) {
dout(10) << __func__ << ": " << soid << " still unfound" << dendl;
continue;
}
continue;
}
- if (missing_loc.is_deleted(soid)) {
+ if (recovery_state.get_missing_loc().is_deleted(soid)) {
dout(10) << __func__ << ": " << soid << " is a delete, removing" << dendl;
map<hobject_t,pg_missing_item>::const_iterator r = m.get_items().find(soid);
started += prep_object_replica_deletes(soid, r->second.need, h, work_started);
continue;
}
- if (soid.is_snap() && pg_log.get_missing().is_missing(soid.get_head())) {
+ if (soid.is_snap() &&
+ recovery_state.get_pg_log().get_missing().is_missing(
+ soid.get_head())) {
dout(10) << __func__ << ": " << soid.get_head()
<< " still missing on primary" << dendl;
continue;
}
- if (pg_log.get_missing().is_missing(soid)) {
+ if (recovery_state.get_pg_log().get_missing().is_missing(soid)) {
dout(10) << __func__ << ": " << soid << " still missing on primary" << dendl;
continue;
}
dout(10) << __func__<< ": bi is current " << dendl;
ceph_assert(bi->version == projected_last_update);
} else if (bi->version >= info.log_tail) {
- if (pg_log.get_log().empty() && projected_log.empty()) {
+ if (recovery_state.get_pg_log().get_log().empty() && projected_log.empty()) {
/* Because we don't move log_tail on split, the log might be
* empty even if log_tail != last_update. However, the only
* way to get here with an empty log is if log_tail is actually
}
};
dout(10) << "scanning pg log first" << dendl;
- pg_log.get_log().scan_log_after(bi->version, func);
+ recovery_state.get_pg_log().get_log().scan_log_after(bi->version, func);
dout(10) << "scanning projected log" << dendl;
projected_log.scan_log_after(bi->version, func);
bi->version = projected_last_update;
{
dout(10) << __func__ << dendl;
- ceph_assert(info.last_update >= pg_log.get_tail()); // otherwise we need some help!
+ ceph_assert(
+ info.last_update >=
+ recovery_state.get_pg_log().get_tail()); // otherwise we need some help!
if (!cct->_conf->osd_debug_verify_stray_on_activate)
return;
// just scan the log.
set<hobject_t> did;
- for (list<pg_log_entry_t>::const_reverse_iterator p = pg_log.get_log().log.rbegin();
- p != pg_log.get_log().log.rend();
+ for (list<pg_log_entry_t>::const_reverse_iterator p = recovery_state.get_pg_log().get_log().log.rbegin();
+ p != recovery_state.get_pg_log().get_log().log.rend();
++p) {
if (did.count(p->soid))
continue;
}
dout(20) << __func__ << " " << to << " .. " << info.last_update << dendl;
- list<pg_log_entry_t>::const_reverse_iterator p = pg_log.get_log().log.rbegin();
- while (p != pg_log.get_log().log.rend() && p->version > to)
+ list<pg_log_entry_t>::const_reverse_iterator p =
+ recovery_state.get_pg_log().get_log().log.rbegin();
+ while (p != recovery_state.get_pg_log().get_log().log.rend() && p->version > to)
++p;
- while (p != pg_log.get_log().log.rend() && p->version > from) {
+ while (p != recovery_state.get_pg_log().get_log().log.rend() && p->version > from) {
hit_set->insert(p->soid);
++p;
}