1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include <seastar/core/future.hh>
6 #include "messages/MOSDOp.h"
8 #include "crimson/osd/pg.h"
9 #include "crimson/osd/shard_services.h"
10 #include "common/Formatter.h"
11 #include "crimson/osd/osd_operations/background_recovery.h"
14 seastar::logger
& logger() {
15 return crimson::get_logger(ceph_subsys_osd
);
19 namespace crimson::osd
{
21 BackgroundRecovery::BackgroundRecovery(
24 epoch_t epoch_started
,
25 crimson::osd::scheduler::scheduler_class_t scheduler_class
)
27 epoch_started(epoch_started
),
29 scheduler_class(scheduler_class
)
32 void BackgroundRecovery::print(std::ostream
&lhs
) const
34 lhs
<< "BackgroundRecovery(" << pg
->get_pgid() << ")";
37 void BackgroundRecovery::dump_detail(Formatter
*f
) const
39 f
->dump_stream("pgid") << pg
->get_pgid();
40 f
->open_object_section("recovery_detail");
42 // TODO pg->dump_recovery_state(f);
47 seastar::future
<> BackgroundRecovery::start()
49 logger().debug("{}: start", *this);
52 return ss
.throttler
.with_throttle_while(
53 this, get_scheduler_params(), [this] {
55 }).handle_exception_type([ref
, this](const std::system_error
& err
) {
56 if (err
.code() == std::make_error_code(std::errc::interrupted
)) {
57 logger().debug("{} recovery interruped: {}", *pg
, err
.what());
58 return seastar::now();
60 return seastar::make_exception_future
<>(err
);
64 seastar::future
<bool> UrgentRecovery::do_recovery()
66 if (!pg
->has_reset_since(epoch_started
)) {
67 return with_blocking_future(
68 pg
->get_recovery_handler()->recover_missing(soid
, need
)
70 return seastar::make_ready_future
<bool>(false);
73 return seastar::make_ready_future
<bool>(false);
76 void UrgentRecovery::print(std::ostream
&lhs
) const
78 lhs
<< "UrgentRecovery(" << pg
->get_pgid() << ", "
79 << soid
<< ", v" << need
<< ")";
82 void UrgentRecovery::dump_detail(Formatter
*f
) const
84 f
->dump_stream("pgid") << pg
->get_pgid();
85 f
->open_object_section("recovery_detail");
87 f
->dump_stream("oid") << soid
;
88 f
->dump_stream("version") << need
;
93 PglogBasedRecovery::PglogBasedRecovery(
96 const epoch_t epoch_started
)
101 crimson::osd::scheduler::scheduler_class_t::background_recovery
)
104 seastar::future
<bool> PglogBasedRecovery::do_recovery()
106 if (pg
->has_reset_since(epoch_started
))
107 return seastar::make_ready_future
<bool>(false);
108 return with_blocking_future(
109 pg
->get_recovery_handler()->start_recovery_ops(
110 crimson::common::local_conf()->osd_recovery_max_single_start
));
113 BackfillRecovery::BackfillRecoveryPipeline
&BackfillRecovery::bp(PG
&pg
)
115 return pg
.backfill_pipeline
;
118 seastar::future
<bool> BackfillRecovery::do_recovery()
120 logger().debug("{}", __func__
);
122 if (pg
->has_reset_since(epoch_started
)) {
123 logger().debug("{}: pg got reset since epoch_started={}",
124 __func__
, epoch_started
);
125 return seastar::make_ready_future
<bool>(false);
128 return with_blocking_future(
129 // process_event() of our boost::statechart machine is non-reentrant.
130 // with the backfill_pipeline we protect it from a second entry from
131 // the implementation of BackfillListener.
132 // additionally, this stage serves to synchronize with PeeringEvent.
133 handle
.enter(bp(*pg
).process
)
135 pg
->get_recovery_handler()->dispatch_backfill_event(std::move(evt
));
136 return seastar::make_ready_future
<bool>(false);
140 } // namespace crimson::osd