2 from zope.interface import implements
3 from allmydata.interfaces import ICheckResults, ICheckAndRepairResults, \
4 IDeepCheckResults, IDeepCheckAndRepairResults, IURI
5 from allmydata.util import base32
8 implements(ICheckResults)
10 def __init__(self, uri, storage_index):
11 assert IURI.providedBy(uri), uri
13 self.storage_index = storage_index
18 def set_healthy(self, healthy):
19 self.healthy = bool(healthy)
21 assert (not hasattr(self, 'recoverable')) or self.recoverable, hasattr(self, 'recoverable') and self.recoverable
22 self.recoverable = True
23 self.summary = "healthy"
25 self.summary = "not healthy"
26 def set_recoverable(self, recoverable):
27 self.recoverable = recoverable
28 if not self.recoverable:
29 assert (not hasattr(self, 'healthy')) or not self.healthy
31 def set_needs_rebalancing(self, needs_rebalancing):
32 self.needs_rebalancing_p = bool(needs_rebalancing)
34 count_shares_needed, count_shares_expected,
35 count_shares_good, count_good_share_hosts,
36 count_recoverable_versions, count_unrecoverable_versions,
37 servers_responding, sharemap,
38 count_wrong_shares, list_corrupt_shares, count_corrupt_shares,
39 list_incompatible_shares, count_incompatible_shares):
40 data = {"count-shares-needed": count_shares_needed,
41 "count-shares-expected": count_shares_expected,
42 "count-shares-good": count_shares_good,
43 "count-good-share-hosts": count_good_share_hosts,
44 "count-recoverable-versions": count_recoverable_versions,
45 "count-unrecoverable-versions": count_unrecoverable_versions,
46 "servers-responding": servers_responding,
48 "count-wrong-shares": count_wrong_shares,
49 "list-corrupt-shares": list_corrupt_shares,
50 "count-corrupt-shares": count_corrupt_shares,
51 "list-incompatible-shares": list_incompatible_shares,
52 "count-incompatible-shares": count_incompatible_shares,
55 def set_summary(self, summary):
56 assert isinstance(summary, str) # should be a single string
57 self.summary = summary
58 def set_report(self, report):
59 assert not isinstance(report, str) # should be list of strings
62 def set_servermap(self, smap):
67 def get_storage_index(self):
68 return self.storage_index
69 def get_storage_index_string(self):
70 return base32.b2a(self.storage_index)
76 def is_recoverable(self):
77 return self.recoverable
79 def needs_rebalancing(self):
80 return self.needs_rebalancing_p
82 def get_encoding_needed(self):
83 return self._data["count-shares-needed"]
84 def get_encoding_expected(self):
85 return self._data["count-shares-expected"]
87 def get_share_counter_good(self):
88 return self._data["count-shares-good"]
89 def get_share_counter_wrong(self):
90 return self._data["count-wrong-shares"]
92 def get_corrupt_shares(self):
93 return self._data["list-corrupt-shares"]
95 def get_incompatible_shares(self):
96 return self._data["list-incompatible-shares"]
98 def get_servers_responding(self):
99 return self._data["servers-responding"]
101 def get_host_counter_good_shares(self):
102 return self._data["count-good-share-hosts"]
104 def get_version_counter_recoverable(self):
105 return self._data["count-recoverable-versions"]
106 def get_version_counter_unrecoverable(self):
107 return self._data["count-unrecoverable-versions"]
109 def get_sharemap(self):
110 return self._data["sharemap"]
115 def get_summary(self):
117 def get_report(self):
119 def get_servermap(self):
120 return self.servermap
122 class CheckAndRepairResults:
123 implements(ICheckAndRepairResults)
125 def __init__(self, storage_index):
126 self.storage_index = storage_index
127 self.repair_attempted = False
129 def get_storage_index(self):
130 return self.storage_index
131 def get_storage_index_string(self):
132 return base32.b2a(self.storage_index)
133 def get_repair_attempted(self):
134 return self.repair_attempted
135 def get_repair_successful(self):
136 if not self.repair_attempted:
138 return self.repair_successful
139 def get_pre_repair_results(self):
140 return self.pre_repair_results
141 def get_post_repair_results(self):
142 return self.post_repair_results
145 class DeepResultsBase:
147 def __init__(self, root_storage_index):
148 self.root_storage_index = root_storage_index
149 if root_storage_index is None:
150 self.root_storage_index_s = "<none>" # is this correct?
152 self.root_storage_index_s = base32.b2a(root_storage_index)
154 self.objects_checked = 0
155 self.objects_healthy = 0
156 self.objects_unhealthy = 0
157 self.objects_unrecoverable = 0
158 self.corrupt_shares = []
159 self.all_results = {}
160 self.all_results_by_storage_index = {}
163 def update_stats(self, new_stats):
164 self.stats.update(new_stats)
166 def get_root_storage_index_string(self):
167 return self.root_storage_index_s
169 def get_corrupt_shares(self):
170 return self.corrupt_shares
172 def get_all_results(self):
173 return self.all_results
175 def get_results_for_storage_index(self, storage_index):
176 return self.all_results_by_storage_index[storage_index]
182 class DeepCheckResults(DeepResultsBase):
183 implements(IDeepCheckResults)
185 def add_check(self, r, path):
187 return # non-distributed object, i.e. LIT file
189 assert isinstance(path, (list, tuple))
190 self.objects_checked += 1
192 self.objects_healthy += 1
194 self.objects_unhealthy += 1
195 if not r.is_recoverable():
196 self.objects_unrecoverable += 1
197 self.all_results[tuple(path)] = r
198 self.all_results_by_storage_index[r.get_storage_index()] = r
199 self.corrupt_shares.extend(r.get_data()["list-corrupt-shares"])
201 def get_counters(self):
202 return {"count-objects-checked": self.objects_checked,
203 "count-objects-healthy": self.objects_healthy,
204 "count-objects-unhealthy": self.objects_unhealthy,
205 "count-objects-unrecoverable": self.objects_unrecoverable,
206 "count-corrupt-shares": len(self.corrupt_shares),
210 class DeepCheckAndRepairResults(DeepResultsBase):
211 implements(IDeepCheckAndRepairResults)
213 def __init__(self, root_storage_index):
214 DeepResultsBase.__init__(self, root_storage_index)
215 self.objects_healthy_post_repair = 0
216 self.objects_unhealthy_post_repair = 0
217 self.objects_unrecoverable_post_repair = 0
218 self.repairs_attempted = 0
219 self.repairs_successful = 0
220 self.repairs_unsuccessful = 0
221 self.corrupt_shares_post_repair = []
223 def add_check_and_repair(self, r, path):
225 return # non-distributed object, i.e. LIT file
226 r = ICheckAndRepairResults(r)
227 assert isinstance(path, (list, tuple))
228 pre_repair = r.get_pre_repair_results()
229 post_repair = r.get_post_repair_results()
230 self.objects_checked += 1
231 if pre_repair.is_healthy():
232 self.objects_healthy += 1
234 self.objects_unhealthy += 1
235 if not pre_repair.is_recoverable():
236 self.objects_unrecoverable += 1
237 self.corrupt_shares.extend(pre_repair.get_data()["list-corrupt-shares"])
238 if r.get_repair_attempted():
239 self.repairs_attempted += 1
240 if r.get_repair_successful():
241 self.repairs_successful += 1
243 self.repairs_unsuccessful += 1
244 if post_repair.is_healthy():
245 self.objects_healthy_post_repair += 1
247 self.objects_unhealthy_post_repair += 1
248 if not post_repair.is_recoverable():
249 self.objects_unrecoverable_post_repair += 1
250 self.all_results[tuple(path)] = r
251 self.all_results_by_storage_index[r.get_storage_index()] = r
252 self.corrupt_shares_post_repair.extend(post_repair.get_data()["list-corrupt-shares"])
254 def get_counters(self):
255 return {"count-objects-checked": self.objects_checked,
256 "count-objects-healthy-pre-repair": self.objects_healthy,
257 "count-objects-unhealthy-pre-repair": self.objects_unhealthy,
258 "count-objects-unrecoverable-pre-repair": self.objects_unrecoverable,
259 "count-objects-healthy-post-repair": self.objects_healthy_post_repair,
260 "count-objects-unhealthy-post-repair": self.objects_unhealthy_post_repair,
261 "count-objects-unrecoverable-post-repair": self.objects_unrecoverable_post_repair,
262 "count-repairs-attempted": self.repairs_attempted,
263 "count-repairs-successful": self.repairs_successful,
264 "count-repairs-unsuccessful": self.repairs_unsuccessful,
265 "count-corrupt-shares-pre-repair": len(self.corrupt_shares),
266 "count-corrupt-shares-post-repair": len(self.corrupt_shares_post_repair),
269 def get_remaining_corrupt_shares(self):
270 return self.corrupt_shares_post_repair