]> git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/osd/osd_operations/background_recovery.cc
126e0e9029bff76262192d42f87163bb2ddeab30
[ceph.git] / ceph / src / crimson / osd / osd_operations / background_recovery.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include <seastar/core/future.hh>
5
6 #include "messages/MOSDOp.h"
7
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"
12
13 namespace {
14 seastar::logger& logger() {
15 return crimson::get_logger(ceph_subsys_osd);
16 }
17 }
18
19 namespace crimson::osd {
20
21 BackgroundRecovery::BackgroundRecovery(
22 Ref<PG> pg,
23 ShardServices &ss,
24 epoch_t epoch_started,
25 crimson::osd::scheduler::scheduler_class_t scheduler_class)
26 : pg(pg),
27 epoch_started(epoch_started),
28 ss(ss),
29 scheduler_class(scheduler_class)
30 {}
31
32 void BackgroundRecovery::print(std::ostream &lhs) const
33 {
34 lhs << "BackgroundRecovery(" << pg->get_pgid() << ")";
35 }
36
37 void BackgroundRecovery::dump_detail(Formatter *f) const
38 {
39 f->dump_stream("pgid") << pg->get_pgid();
40 f->open_object_section("recovery_detail");
41 {
42 // TODO pg->dump_recovery_state(f);
43 }
44 f->close_section();
45 }
46
47 seastar::future<> BackgroundRecovery::start()
48 {
49 logger().debug("{}: start", *this);
50
51 IRef ref = this;
52 return ss.throttler.with_throttle_while(
53 this, get_scheduler_params(), [this] {
54 return do_recovery();
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();
59 }
60 return seastar::make_exception_future<>(err);
61 });
62 }
63
64 seastar::future<bool> UrgentRecovery::do_recovery()
65 {
66 if (!pg->has_reset_since(epoch_started)) {
67 return with_blocking_future(
68 pg->get_recovery_handler()->recover_missing(soid, need)
69 ).then([] {
70 return seastar::make_ready_future<bool>(false);
71 });
72 }
73 return seastar::make_ready_future<bool>(false);
74 }
75
76 void UrgentRecovery::print(std::ostream &lhs) const
77 {
78 lhs << "UrgentRecovery(" << pg->get_pgid() << ", "
79 << soid << ", v" << need << ")";
80 }
81
82 void UrgentRecovery::dump_detail(Formatter *f) const
83 {
84 f->dump_stream("pgid") << pg->get_pgid();
85 f->open_object_section("recovery_detail");
86 {
87 f->dump_stream("oid") << soid;
88 f->dump_stream("version") << need;
89 }
90 f->close_section();
91 }
92
93 PglogBasedRecovery::PglogBasedRecovery(
94 Ref<PG> pg,
95 ShardServices &ss,
96 const epoch_t epoch_started)
97 : BackgroundRecovery(
98 std::move(pg),
99 ss,
100 epoch_started,
101 crimson::osd::scheduler::scheduler_class_t::background_recovery)
102 {}
103
104 seastar::future<bool> PglogBasedRecovery::do_recovery()
105 {
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));
111 }
112
113 BackfillRecovery::BackfillRecoveryPipeline &BackfillRecovery::bp(PG &pg)
114 {
115 return pg.backfill_pipeline;
116 }
117
118 seastar::future<bool> BackfillRecovery::do_recovery()
119 {
120 logger().debug("{}", __func__);
121
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);
126 }
127 // TODO: limits
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)
134 ).then([this] {
135 pg->get_recovery_handler()->dispatch_backfill_event(std::move(evt));
136 return seastar::make_ready_future<bool>(false);
137 });
138 }
139
140 } // namespace crimson::osd