2 from zope.interface import implements
3 from allmydata.interfaces import ICheckerResults, ICheckAndRepairResults, \
4 IDeepCheckResults, IDeepCheckAndRepairResults, IURI
5 from allmydata.util import base32
8 implements(ICheckerResults)
10 def __init__(self, uri, storage_index):
11 assert IURI.providedBy(uri), uri
13 self.storage_index = storage_index
15 self.data = {"count-corrupt-shares": 0,
16 "list-corrupt-shares": [],
21 def set_healthy(self, healthy):
22 self.healthy = bool(healthy)
24 assert (not hasattr(self, 'recoverable')) or self.recoverable, hasattr(self, 'recoverable') and self.recoverable
25 self.recoverable = True
26 self.summary = "healthy"
28 self.summary = "not healthy"
29 def set_recoverable(self, recoverable):
30 self.recoverable = recoverable
31 if not self.recoverable:
32 assert (not hasattr(self, 'healthy')) or not self.healthy
34 def set_needs_rebalancing(self, needs_rebalancing):
35 self.needs_rebalancing_p = bool(needs_rebalancing)
36 def set_data(self, data):
37 self.data.update(data)
38 def set_summary(self, summary):
39 assert isinstance(summary, str) # should be a single string
40 self.summary = summary
41 def set_report(self, report):
42 assert not isinstance(report, str) # should be list of strings
45 def set_servermap(self, smap):
50 def get_storage_index(self):
51 return self.storage_index
52 def get_storage_index_string(self):
53 return base32.b2a(self.storage_index)
59 def is_recoverable(self):
60 return self.recoverable
62 def needs_rebalancing(self):
63 return self.needs_rebalancing_p
67 def get_summary(self):
71 def get_servermap(self):
74 class CheckAndRepairResults:
75 implements(ICheckAndRepairResults)
77 def __init__(self, storage_index):
78 self.storage_index = storage_index
79 self.repair_attempted = False
81 def get_storage_index(self):
82 return self.storage_index
83 def get_storage_index_string(self):
84 return base32.b2a(self.storage_index)
85 def get_repair_attempted(self):
86 return self.repair_attempted
87 def get_repair_successful(self):
88 if not self.repair_attempted:
90 return self.repair_successful
91 def get_pre_repair_results(self):
92 return self.pre_repair_results
93 def get_post_repair_results(self):
94 return self.post_repair_results
97 class DeepResultsBase:
99 def __init__(self, root_storage_index):
100 self.root_storage_index = root_storage_index
101 if root_storage_index is None:
102 self.root_storage_index_s = "<none>"
104 self.root_storage_index_s = base32.b2a(root_storage_index)
106 self.objects_checked = 0
107 self.objects_healthy = 0
108 self.objects_unhealthy = 0
109 self.objects_unrecoverable = 0
110 self.corrupt_shares = []
111 self.all_results = {}
112 self.all_results_by_storage_index = {}
115 def update_stats(self, new_stats):
116 self.stats.update(new_stats)
118 def get_root_storage_index_string(self):
119 return self.root_storage_index_s
121 def get_corrupt_shares(self):
122 return self.corrupt_shares
124 def get_all_results(self):
125 return self.all_results
127 def get_results_for_storage_index(self, storage_index):
128 return self.all_results_by_storage_index[storage_index]
134 class DeepCheckResults(DeepResultsBase):
135 implements(IDeepCheckResults)
137 def add_check(self, r, path):
139 return # non-distributed object, i.e. LIT file
140 r = ICheckerResults(r)
141 assert isinstance(path, (list, tuple))
142 self.objects_checked += 1
144 self.objects_healthy += 1
146 self.objects_unhealthy += 1
147 if not r.is_recoverable():
148 self.objects_unrecoverable += 1
149 self.all_results[tuple(path)] = r
150 self.all_results_by_storage_index[r.get_storage_index()] = r
151 self.corrupt_shares.extend(r.get_data()["list-corrupt-shares"])
153 def get_counters(self):
154 return {"count-objects-checked": self.objects_checked,
155 "count-objects-healthy": self.objects_healthy,
156 "count-objects-unhealthy": self.objects_unhealthy,
157 "count-objects-unrecoverable": self.objects_unrecoverable,
158 "count-corrupt-shares": len(self.corrupt_shares),
162 class DeepCheckAndRepairResults(DeepResultsBase):
163 implements(IDeepCheckAndRepairResults)
165 def __init__(self, root_storage_index):
166 DeepResultsBase.__init__(self, root_storage_index)
167 self.objects_healthy_post_repair = 0
168 self.objects_unhealthy_post_repair = 0
169 self.objects_unrecoverable_post_repair = 0
170 self.repairs_attempted = 0
171 self.repairs_successful = 0
172 self.repairs_unsuccessful = 0
173 self.corrupt_shares_post_repair = []
175 def add_check_and_repair(self, r, path):
177 return # non-distributed object, i.e. LIT file
178 r = ICheckAndRepairResults(r)
179 assert isinstance(path, (list, tuple))
180 pre_repair = r.get_pre_repair_results()
181 post_repair = r.get_post_repair_results()
182 self.objects_checked += 1
183 if pre_repair.is_healthy():
184 self.objects_healthy += 1
186 self.objects_unhealthy += 1
187 if not pre_repair.is_recoverable():
188 self.objects_unrecoverable += 1
189 self.corrupt_shares.extend(pre_repair.get_data()["list-corrupt-shares"])
190 if r.get_repair_attempted():
191 self.repairs_attempted += 1
192 if r.get_repair_successful():
193 self.repairs_successful += 1
195 self.repairs_unsuccessful += 1
196 if post_repair.is_healthy():
197 self.objects_healthy_post_repair += 1
199 self.objects_unhealthy_post_repair += 1
200 if not post_repair.is_recoverable():
201 self.objects_unrecoverable_post_repair += 1
202 self.all_results[tuple(path)] = r
203 self.all_results_by_storage_index[r.get_storage_index()] = r
204 self.corrupt_shares_post_repair.extend(post_repair.get_data()["list-corrupt-shares"])
206 def get_counters(self):
207 return {"count-objects-checked": self.objects_checked,
208 "count-objects-healthy-pre-repair": self.objects_healthy,
209 "count-objects-unhealthy-pre-repair": self.objects_unhealthy,
210 "count-objects-unrecoverable-pre-repair": self.objects_unrecoverable,
211 "count-objects-healthy-post-repair": self.objects_healthy_post_repair,
212 "count-objects-unhealthy-post-repair": self.objects_unhealthy_post_repair,
213 "count-objects-unrecoverable-post-repair": self.objects_unrecoverable_post_repair,
214 "count-repairs-attempted": self.repairs_attempted,
215 "count-repairs-successful": self.repairs_successful,
216 "count-repairs-unsuccessful": self.repairs_unsuccessful,
217 "count-corrupt-shares-pre-repair": len(self.corrupt_shares),
218 "count-corrupt-shares-post-repair": len(self.corrupt_shares_post_repair),
221 def get_remaining_corrupt_shares(self):
222 return self.corrupt_shares_post_repair