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
,
27 crimson::net::ConnectionRef conn
) final
;
29 interruptible_future
<> recover_object(
30 const hobject_t
& soid
,
31 eversion_t need
) final
;
32 interruptible_future
<> recover_delete(
33 const hobject_t
& soid
,
34 eversion_t need
) final
;
35 interruptible_future
<> push_delete(
36 const hobject_t
& soid
,
37 eversion_t need
) final
;
39 interruptible_future
<> handle_pull(
41 interruptible_future
<> handle_pull_response(
43 interruptible_future
<> handle_push(
45 interruptible_future
<> handle_push_reply(
46 Ref
<MOSDPGPushReply
> m
);
47 interruptible_future
<> handle_recovery_delete(
48 Ref
<MOSDPGRecoveryDelete
> m
);
49 interruptible_future
<> handle_recovery_delete_reply(
50 Ref
<MOSDPGRecoveryDeleteReply
> m
);
51 interruptible_future
<PushOp
> prep_push(
52 const hobject_t
& soid
,
57 pull_info_t
& pull_info
,
58 const hobject_t
& soid
,
60 std::vector
<pg_shard_t
> get_shards_to_push(
61 const hobject_t
& soid
) const;
62 interruptible_future
<PushOp
> build_push_op(
63 const ObjectRecoveryInfo
& recovery_info
,
64 const ObjectRecoveryProgress
& progress
,
65 object_stat_sum_t
* stat
);
66 /// @returns true if this push op is the last push op for
67 /// recovery @c pop.soid
68 interruptible_future
<bool> _handle_pull_response(
72 ceph::os::Transaction
* t
);
73 std::pair
<interval_set
<uint64_t>, ceph::bufferlist
> trim_pushed_data(
74 const interval_set
<uint64_t> ©_subset
,
75 const interval_set
<uint64_t> &intervals_received
,
76 ceph::bufferlist data_received
);
77 interruptible_future
<> submit_push_data(
78 const ObjectRecoveryInfo
&recovery_info
,
82 interval_set
<uint64_t>&& data_zeros
,
83 interval_set
<uint64_t>&& intervals_included
,
84 ceph::bufferlist
&& data_included
,
85 ceph::bufferlist
&& omap_header
,
86 const std::map
<std::string
, bufferlist
, std::less
<>> &attrs
,
87 std::map
<std::string
, bufferlist
>&& omap_entries
,
88 ceph::os::Transaction
*t
);
89 void submit_push_complete(
90 const ObjectRecoveryInfo
&recovery_info
,
91 ObjectStore::Transaction
*t
);
92 interruptible_future
<> _handle_push(
95 PushReplyOp
*response
,
96 ceph::os::Transaction
*t
);
97 interruptible_future
<std::optional
<PushOp
>> _handle_push_reply(
99 const PushReplyOp
&op
);
100 interruptible_future
<> on_local_recover_persist(
101 const hobject_t
& soid
,
102 const ObjectRecoveryInfo
& _recovery_info
,
104 epoch_t epoch_to_freeze
);
105 interruptible_future
<> local_recover_delete(
106 const hobject_t
& soid
,
108 epoch_t epoch_frozen
);
109 seastar::future
<> on_stop() final
{
110 return seastar::now();
113 /// pull missing object from peer
114 interruptible_future
<> maybe_pull_missing_obj(
115 const hobject_t
& soid
,
118 /// load object context for recovery if it is not ready yet
119 using load_obc_ertr
= crimson::errorator
<
120 crimson::ct_error::object_corrupted
>;
121 using load_obc_iertr
=
122 ::crimson::interruptible::interruptible_errorator
<
123 ::crimson::osd::IOInterruptCondition
,
126 interruptible_future
<> maybe_push_shards(
127 const hobject_t
& soid
,
130 /// read the data attached to given object. the size of them is supposed to
131 /// be relatively small.
133 /// @return @c oi.version
134 interruptible_future
<eversion_t
> read_metadata_for_push_op(
135 const hobject_t
& oid
,
136 const ObjectRecoveryProgress
& progress
,
137 ObjectRecoveryProgress
& new_progress
,
140 /// read the remaining extents of object to be recovered and fill push_op
143 /// @param oid object being recovered
144 /// @param copy_subset extents we want
145 /// @param offset the offset in object from where we should read
146 /// @return the new offset
147 interruptible_future
<uint64_t> read_object_for_push_op(
148 const hobject_t
& oid
,
149 const interval_set
<uint64_t>& copy_subset
,
153 interruptible_future
<> read_omap_for_push_op(
154 const hobject_t
& oid
,
155 const ObjectRecoveryProgress
& progress
,
156 ObjectRecoveryProgress
& new_progress
,
159 interruptible_future
<hobject_t
> prep_push_target(
160 const ObjectRecoveryInfo
&recovery_info
,
164 ObjectStore::Transaction
* t
,
165 const std::map
<std::string
, bufferlist
, std::less
<>> &attrs
,
166 bufferlist
&& omap_header
);
167 using interruptor
= crimson::interruptible::interruptor
<
168 crimson::osd::IOInterruptCondition
>;