]> git.proxmox.com Git - ceph.git/blob - ceph/src/osd/MissingLoc.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / osd / MissingLoc.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 "MissingLoc.h"
5
6 #define dout_context cct
7 #undef dout_prefix
8 #define dout_prefix (gen_prefix(*_dout))
9 #define dout_subsys ceph_subsys_osd
10
11 using std::set;
12
13 bool MissingLoc::readable_with_acting(
14 const hobject_t &hoid,
15 const set<pg_shard_t> &acting,
16 eversion_t* v) const {
17 if (!needs_recovery(hoid, v))
18 return true;
19 if (is_deleted(hoid))
20 return false;
21 auto missing_loc_entry = missing_loc.find(hoid);
22 if (missing_loc_entry == missing_loc.end())
23 return false;
24 const set<pg_shard_t> &locs = missing_loc_entry->second;
25 ldout(cct, 10) << __func__ << ": locs:" << locs << dendl;
26 set<pg_shard_t> have_acting;
27 for (auto i = locs.begin(); i != locs.end(); ++i) {
28 if (acting.count(*i))
29 have_acting.insert(*i);
30 }
31 return (*is_readable)(have_acting);
32 }
33
34 void MissingLoc::add_batch_sources_info(
35 const set<pg_shard_t> &sources,
36 HBHandle *handle)
37 {
38 ldout(cct, 10) << __func__ << ": adding sources in batch "
39 << sources.size() << dendl;
40 unsigned loop = 0;
41 bool sources_updated = false;
42 for (auto i = needs_recovery_map.begin();
43 i != needs_recovery_map.end();
44 ++i) {
45 if (handle && ++loop >= cct->_conf->osd_loop_before_reset_tphandle) {
46 handle->reset_tp_timeout();
47 loop = 0;
48 }
49 if (i->second.is_delete())
50 continue;
51
52 auto p = missing_loc.find(i->first);
53 if (p == missing_loc.end()) {
54 p = missing_loc.emplace(i->first, set<pg_shard_t>()).first;
55 } else {
56 _dec_count(p->second);
57 }
58 missing_loc[i->first].insert(sources.begin(), sources.end());
59 _inc_count(p->second);
60
61 if (!sources_updated) {
62 missing_loc_sources.insert(sources.begin(), sources.end());
63 sources_updated = true;
64 }
65 }
66 }
67
68 bool MissingLoc::add_source_info(
69 pg_shard_t fromosd,
70 const pg_info_t &oinfo,
71 const pg_missing_t &omissing,
72 HBHandle *handle)
73 {
74 bool found_missing = false;
75 unsigned loop = 0;
76 bool sources_updated = false;
77 // found items?
78 for (auto p = needs_recovery_map.begin();
79 p != needs_recovery_map.end();
80 ++p) {
81 const hobject_t &soid(p->first);
82 eversion_t need = p->second.need;
83 if (handle && ++loop >= cct->_conf->osd_loop_before_reset_tphandle) {
84 handle->reset_tp_timeout();
85 loop = 0;
86 }
87 if (p->second.is_delete()) {
88 ldout(cct, 10) << __func__ << " " << soid
89 << " delete, ignoring source" << dendl;
90 continue;
91 }
92 if (oinfo.last_update < need) {
93 ldout(cct, 10) << "search_for_missing " << soid << " " << need
94 << " also missing on osd." << fromosd
95 << " (last_update " << oinfo.last_update
96 << " < needed " << need << ")" << dendl;
97 continue;
98 }
99 if (p->first >= oinfo.last_backfill) {
100 // FIXME: this is _probably_ true, although it could conceivably
101 // be in the undefined region! Hmm!
102 ldout(cct, 10) << "search_for_missing " << soid << " " << need
103 << " also missing on osd." << fromosd
104 << " (past last_backfill " << oinfo.last_backfill
105 << ")" << dendl;
106 continue;
107 }
108 if (omissing.is_missing(soid)) {
109 ldout(cct, 10) << "search_for_missing " << soid << " " << need
110 << " also missing on osd." << fromosd << dendl;
111 continue;
112 }
113
114 ldout(cct, 10) << "search_for_missing " << soid << " " << need
115 << " is on osd." << fromosd << dendl;
116
117 {
118 auto p = missing_loc.find(soid);
119 if (p == missing_loc.end()) {
120 p = missing_loc.emplace(soid, set<pg_shard_t>()).first;
121 } else {
122 _dec_count(p->second);
123 }
124 p->second.insert(fromosd);
125 _inc_count(p->second);
126 }
127
128 if (!sources_updated) {
129 missing_loc_sources.insert(fromosd);
130 sources_updated = true;
131 }
132 found_missing = true;
133 }
134
135 ldout(cct, 20) << "needs_recovery_map missing " << needs_recovery_map
136 << dendl;
137 return found_missing;
138 }
139
140 void MissingLoc::check_recovery_sources(const OSDMapRef& osdmap)
141 {
142 set<pg_shard_t> now_down;
143 for (auto p = missing_loc_sources.begin();
144 p != missing_loc_sources.end();
145 ) {
146 if (osdmap->is_up(p->osd)) {
147 ++p;
148 continue;
149 }
150 ldout(cct, 10) << __func__ << " source osd." << *p << " now down" << dendl;
151 now_down.insert(*p);
152 missing_loc_sources.erase(p++);
153 }
154
155 if (now_down.empty()) {
156 ldout(cct, 10) << __func__ << " no source osds (" << missing_loc_sources << ") went down" << dendl;
157 } else {
158 ldout(cct, 10) << __func__ << " sources osds " << now_down << " now down, remaining sources are "
159 << missing_loc_sources << dendl;
160
161 // filter missing_loc
162 auto p = missing_loc.begin();
163 while (p != missing_loc.end()) {
164 auto q = p->second.begin();
165 bool changed = false;
166 while (q != p->second.end()) {
167 if (now_down.count(*q)) {
168 if (!changed) {
169 changed = true;
170 _dec_count(p->second);
171 }
172 p->second.erase(q++);
173 } else {
174 ++q;
175 }
176 }
177 if (p->second.empty()) {
178 missing_loc.erase(p++);
179 } else {
180 if (changed) {
181 _inc_count(p->second);
182 }
183 ++p;
184 }
185 }
186 }
187 }
188
189 void MissingLoc::remove_stray_recovery_sources(pg_shard_t stray)
190 {
191 ldout(cct, 10) << __func__ << " remove osd " << stray << " from missing_loc" << dendl;
192 // filter missing_loc
193 auto p = missing_loc.begin();
194 while (p != missing_loc.end()) {
195 auto q = p->second.begin();
196 bool changed = false;
197 while (q != p->second.end()) {
198 if (*q == stray) {
199 if (!changed) {
200 changed = true;
201 _dec_count(p->second);
202 }
203 p->second.erase(q++);
204 } else {
205 ++q;
206 }
207 }
208 if (p->second.empty()) {
209 missing_loc.erase(p++);
210 } else {
211 if (changed) {
212 _inc_count(p->second);
213 }
214 ++p;
215 }
216 }
217 // filter missing_loc_sources
218 for (auto p = missing_loc_sources.begin(); p != missing_loc_sources.end();) {
219 if (*p != stray) {
220 ++p;
221 continue;
222 }
223 ldout(cct, 10) << __func__ << " remove osd" << stray << " from missing_loc_sources" << dendl;
224 missing_loc_sources.erase(p++);
225 }
226 }