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