]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
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 | ||
f67539c2 TL |
11 | using std::set; |
12 | ||
9f95a23c TL |
13 | bool MissingLoc::readable_with_acting( |
14 | const hobject_t &hoid, | |
f67539c2 TL |
15 | const set<pg_shard_t> &acting, |
16 | eversion_t* v) const { | |
17 | if (!needs_recovery(hoid, v)) | |
9f95a23c TL |
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; | |
f67539c2 | 27 | for (auto i = locs.begin(); i != locs.end(); ++i) { |
9f95a23c TL |
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; | |
f67539c2 | 42 | for (auto i = needs_recovery_map.begin(); |
9f95a23c TL |
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? | |
f67539c2 | 78 | for (auto p = needs_recovery_map.begin(); |
9f95a23c TL |
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; | |
f67539c2 | 143 | for (auto p = missing_loc_sources.begin(); |
9f95a23c TL |
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 | |
f67539c2 | 162 | auto p = missing_loc.begin(); |
9f95a23c | 163 | while (p != missing_loc.end()) { |
f67539c2 | 164 | auto q = p->second.begin(); |
9f95a23c TL |
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 | |
f67539c2 | 193 | auto p = missing_loc.begin(); |
9f95a23c | 194 | while (p != missing_loc.end()) { |
f67539c2 | 195 | auto q = p->second.begin(); |
9f95a23c TL |
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 | |
f67539c2 | 218 | for (auto p = missing_loc_sources.begin(); p != missing_loc_sources.end();) { |
9f95a23c TL |
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 | } |