struct ReplicaScanned : sc::event<ReplicaScanned> {
pg_shard_t from;
BackfillInterval result;
+ ReplicaScanned(pg_shard_t from, BackfillInterval&& result)
+ : from(std::move(from)),
+ result(std::move(result)) {
+ }
};
struct ObjectPushed : sc::event<ObjectPushed> {
const pg_missing_tracker_t& get_local_missing() const {
return peering_state.get_pg_log().get_missing();
}
- epoch_t get_last_peering_reset() const {
+ epoch_t get_last_peering_reset() const final {
return peering_state.get_last_peering_reset();
}
const set<pg_shard_t> &get_acting_recovery_backfill() const {
const hobject_t& begin,
const hobject_t& end)
{
- ceph_abort_msg("Not implemented");
+ logger().debug("{}: target.osd={}", __func__, target.osd);
+ auto msg = make_message<MOSDPGScan>(
+ MOSDPGScan::OP_SCAN_GET_DIGEST,
+ pg->get_pg_whoami(),
+ pg->get_osdmap_epoch(),
+ pg->get_last_peering_reset(),
+ spg_t(pg->get_pgid().pgid, target.shard),
+ begin,
+ end);
+ std::ignore = pg->get_shard_services().send_to_osd(
+ target.osd,
+ std::move(msg),
+ pg->get_osdmap_epoch());
}
void PGRecovery::request_primary_scan(
virtual bool is_unreadable_object(const hobject_t&, eversion_t* v = 0) const = 0;
virtual bool has_reset_since(epoch_t) const = 0;
virtual std::vector<pg_shard_t> get_replica_recovery_order() const = 0;
+ virtual epoch_t get_last_peering_reset() const = 0;
virtual seastar::future<> stop() = 0;
};
MOSDPGScan& m)
{
logger().debug("{}", __func__);
- ceph_assert("Not implemented" == nullptr);
+ // Check that from is in backfill_targets vector
+ ceph_assert(pg.get_peering_state().is_backfill_target(m.from));
+
+ BackfillInterval bi;
+ bi.begin = m.begin;
+ bi.end = m.end;
+ {
+ auto p = m.get_data().cbegin();
+ // take care to preserve ordering!
+ bi.clear_objects();
+ ::decode_noclear(bi.objects, p);
+ }
+ shard_services.start_operation<crimson::osd::BackfillRecovery>(
+ static_cast<crimson::osd::PG*>(&pg),
+ shard_services,
+ pg.get_osdmap_epoch(),
+ crimson::osd::BackfillState::ReplicaScanned{ m.from, std::move(bi) });
return seastar::now();
}