1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 #include "crimson/common/interruptible_future.h"
7 #include "crimson/osd/pg_interval_interrupt_condition.h"
8 #include "crimson/osd/recovery_backend.h"
10 #include "messages/MOSDPGPull.h"
11 #include "messages/MOSDPGPush.h"
12 #include "messages/MOSDPGPushReply.h"
13 #include "messages/MOSDPGRecoveryDelete.h"
14 #include "messages/MOSDPGRecoveryDeleteReply.h"
15 #include "os/ObjectStore.h"
17 class ReplicatedRecoveryBackend
: public RecoveryBackend
{
19 ReplicatedRecoveryBackend(crimson::osd::PG
& pg
,
20 crimson::osd::ShardServices
& shard_services
,
21 crimson::os::CollectionRef coll
,
23 : RecoveryBackend(pg
, shard_services
, coll
, backend
)
25 interruptible_future
<> handle_recovery_op(
26 Ref
<MOSDFastDispatchOp
> m
) final
;
28 interruptible_future
<> recover_object(
29 const hobject_t
& soid
,
30 eversion_t need
) final
;
31 interruptible_future
<> recover_delete(
32 const hobject_t
& soid
,
33 eversion_t need
) final
;
34 interruptible_future
<> push_delete(
35 const hobject_t
& soid
,
36 eversion_t need
) final
;
38 interruptible_future
<> handle_pull(
40 interruptible_future
<> handle_pull_response(
42 interruptible_future
<> handle_push(
44 interruptible_future
<> handle_push_reply(
45 Ref
<MOSDPGPushReply
> m
);
46 interruptible_future
<> handle_recovery_delete(
47 Ref
<MOSDPGRecoveryDelete
> m
);
48 interruptible_future
<> handle_recovery_delete_reply(
49 Ref
<MOSDPGRecoveryDeleteReply
> m
);
50 interruptible_future
<PushOp
> prep_push(
51 const hobject_t
& soid
,
57 const hobject_t
& soid
,
59 std::vector
<pg_shard_t
> get_shards_to_push(
60 const hobject_t
& soid
) const;
61 interruptible_future
<PushOp
> build_push_op(
62 const ObjectRecoveryInfo
& recovery_info
,
63 const ObjectRecoveryProgress
& progress
,
64 object_stat_sum_t
* stat
);
65 /// @returns true if this push op is the last push op for
66 /// recovery @c pop.soid
67 interruptible_future
<bool> _handle_pull_response(
71 ceph::os::Transaction
* t
);
72 std::pair
<interval_set
<uint64_t>, ceph::bufferlist
> trim_pushed_data(
73 const interval_set
<uint64_t> ©_subset
,
74 const interval_set
<uint64_t> &intervals_received
,
75 ceph::bufferlist data_received
);
76 interruptible_future
<> submit_push_data(
77 const ObjectRecoveryInfo
&recovery_info
,
81 interval_set
<uint64_t>&& data_zeros
,
82 interval_set
<uint64_t>&& intervals_included
,
83 ceph::bufferlist
&& data_included
,
84 ceph::bufferlist
&& omap_header
,
85 const std::map
<std::string
, bufferlist
, std::less
<>> &attrs
,
86 std::map
<std::string
, bufferlist
>&& omap_entries
,
87 ceph::os::Transaction
*t
);
88 void submit_push_complete(
89 const ObjectRecoveryInfo
&recovery_info
,
90 ObjectStore::Transaction
*t
);
91 interruptible_future
<> _handle_push(
94 PushReplyOp
*response
,
95 ceph::os::Transaction
*t
);
96 interruptible_future
<std::optional
<PushOp
>> _handle_push_reply(
98 const PushReplyOp
&op
);
99 interruptible_future
<> on_local_recover_persist(
100 const hobject_t
& soid
,
101 const ObjectRecoveryInfo
& _recovery_info
,
103 epoch_t epoch_to_freeze
);
104 interruptible_future
<> local_recover_delete(
105 const hobject_t
& soid
,
107 epoch_t epoch_frozen
);
108 seastar::future
<> on_stop() final
{
109 return seastar::now();
112 /// pull missing object from peer
113 interruptible_future
<> maybe_pull_missing_obj(
114 const hobject_t
& soid
,
117 /// load object context for recovery if it is not ready yet
118 using load_obc_ertr
= crimson::errorator
<
119 crimson::ct_error::object_corrupted
>;
120 using load_obc_iertr
=
121 ::crimson::interruptible::interruptible_errorator
<
122 ::crimson::osd::IOInterruptCondition
,
125 interruptible_future
<> maybe_push_shards(
126 const hobject_t
& soid
,
129 /// read the data attached to given object. the size of them is supposed to
130 /// be relatively small.
132 /// @return @c oi.version
133 interruptible_future
<eversion_t
> read_metadata_for_push_op(
134 const hobject_t
& oid
,
135 const ObjectRecoveryProgress
& progress
,
136 ObjectRecoveryProgress
& new_progress
,
139 /// read the remaining extents of object to be recovered and fill push_op
142 /// @param oid object being recovered
143 /// @param copy_subset extents we want
144 /// @param offset the offset in object from where we should read
145 /// @return the new offset
146 interruptible_future
<uint64_t> read_object_for_push_op(
147 const hobject_t
& oid
,
148 const interval_set
<uint64_t>& copy_subset
,
152 interruptible_future
<> read_omap_for_push_op(
153 const hobject_t
& oid
,
154 const ObjectRecoveryProgress
& progress
,
155 ObjectRecoveryProgress
& new_progress
,
158 interruptible_future
<hobject_t
> prep_push_target(
159 const ObjectRecoveryInfo
&recovery_info
,
163 ObjectStore::Transaction
* t
,
164 const std::map
<std::string
, bufferlist
, std::less
<>> &attrs
,
165 bufferlist
&& omap_header
);
166 using interruptor
= crimson::interruptible::interruptor
<
167 crimson::osd::IOInterruptCondition
>;