Difference between revisions of "Esempio didattico su RAID6"
Jump to navigation
Jump to search
m |
m |
||
| Line 1: | Line 1: | ||
Il codice python che segue consente di provare sperimentalemnte le metodologie di fault tolerance descritte nell'articolo | Il codice python che segue consente di provare sperimentalemnte le metodologie di fault tolerance descritte nell'articolo | ||
[http://www.cs.unibo.it/~renzo//doc/papers/p245-blaum.pdf"EVENODD: An Optimal Scheme for Tolerating Double Disk Failures"] di Mario Blaurn et al. | [http://www.cs.unibo.it/~renzo//doc/papers/p245-blaum.pdf"EVENODD: An Optimal Scheme for Tolerating Double Disk Failures"] di Mario Blaurn et al. | ||
| + | |||
| + | <source lang=python> | ||
| + | #!/usr/bin/env python3 | ||
| + | |||
| + | def compute_parity(tab, nrow, ncol): | ||
| + | for i in range(nrow): | ||
| + | p = 0 | ||
| + | for j in range(ncol): | ||
| + | p ^= tab[i][j] | ||
| + | tab[i][ncol] = p | ||
| + | |||
| + | def compute_dparity(tab, nrow, ncol): | ||
| + | p = [0] * ncol | ||
| + | for i in range(nrow): | ||
| + | for j in range(ncol): | ||
| + | p[(i+j) % ncol] ^= tab[i][j] | ||
| + | # print(p) | ||
| + | s = p[ncol - 1] | ||
| + | for i in range(nrow): | ||
| + | tab[i][ncol + 1] = p[i] ^ s | ||
| + | |||
| + | def print_table(tab, nrow, ncol): | ||
| + | for i in range(nrow): | ||
| + | for j in range(ncol): | ||
| + | print(tab[i][j], end=" ") | ||
| + | print() | ||
| + | print() | ||
| + | |||
| + | def fail(tab, nrow, f): | ||
| + | for i in range(nrow): | ||
| + | tab[i][f] = 'x' | ||
| + | |||
| + | def restorep(tab, nrow, ncol, f): | ||
| + | for i in range(nrow): | ||
| + | p = tab[i][ncol] | ||
| + | for j in range(ncol): | ||
| + | if j != f: | ||
| + | p ^= tab[i][j] | ||
| + | tab[i][f] = p | ||
| + | |||
| + | def restored(tab, nrow, ncol, f): | ||
| + | p = [tab[i][ncol + 1] for i in range(nrow)] + [0] | ||
| + | for i in range(nrow): | ||
| + | for j in range(ncol): | ||
| + | if j != f: | ||
| + | p[(i+j) % ncol] ^= tab[i][j] | ||
| + | s = p[(f - 1) % ncol] | ||
| + | # print(p, s) | ||
| + | for i in range(nrow): | ||
| + | tab[i][f] = s ^ p[(f + i) % ncol] | ||
| + | |||
| + | def restore2(tab, nrow, ncol, f1, f2): | ||
| + | s = 0 | ||
| + | for i in range(nrow): | ||
| + | s ^= tab[i][ncol] ^ tab[i][ncol + 1] | ||
| + | p = [s ^ tab[i][ncol + 1] for i in range(nrow)] + [s] | ||
| + | # print(s, p) | ||
| + | nindex = (nrow + f2) % ncol | ||
| + | for _ in range(nrow): | ||
| + | v = p[nindex] | ||
| + | # print(nindex, (nindex + 1) % ncol) | ||
| + | for i in range(nrow): | ||
| + | j = (nindex - i) % ncol | ||
| + | if j != f1: | ||
| + | v ^= tab[i][j] | ||
| + | else: | ||
| + | row = i | ||
| + | # print(row) | ||
| + | tab[row][f1] = v | ||
| + | nindex = (row + f2) % ncol | ||
| + | v = tab[row][ncol] | ||
| + | for j in range(ncol): | ||
| + | if j != f2: | ||
| + | v ^= tab[row][j] | ||
| + | tab[row][f2] = v | ||
| + | |||
| + | def main(): | ||
| + | tab=[] | ||
| + | while True: | ||
| + | line = input("") | ||
| + | if len(line) <= 1: | ||
| + | break | ||
| + | tab.append([0 if x == "0" else 1 for x in line.split()] + [0, 0]) | ||
| + | nrow = len(tab) | ||
| + | ncol = len(tab[0]) - 2 | ||
| + | # print_table(tab, nrow, ncol) | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | # print_table(tab, nrow, ncol + 1) | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | print_table(tab, nrow, ncol + 2) | ||
| + | |||
| + | savetab = tab | ||
| + | |||
| + | while True: | ||
| + | line = input("failure ") | ||
| + | s = line.split() | ||
| + | if len(s) == 2: | ||
| + | f1, f2 = int(s[0]), int(s[1]) | ||
| + | elif len(s) == 1: | ||
| + | f1 = f2 = int(s[0]) | ||
| + | else: | ||
| + | return | ||
| + | |||
| + | fail(tab, nrow, f1) | ||
| + | fail(tab, nrow, f2) | ||
| + | print_table(tab, nrow, ncol + 2) | ||
| + | if f1 == f2: | ||
| + | print("1 faulty", f1) | ||
| + | if f1 == ncol: | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | elif (f1 == ncol + 1): | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | else: | ||
| + | restorep(tab, nrow, ncol, f1) | ||
| + | else: | ||
| + | if f1 > f2: | ||
| + | f1, f2 = f2, f1 | ||
| + | print("2 faulty", f1, f2) | ||
| + | if f1 == ncol: | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | elif f2 == ncol + 1: | ||
| + | restorep(tab, nrow, ncol, f1) | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | elif f2 == ncol: | ||
| + | restored(tab, nrow, ncol, f1) | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | pass | ||
| + | else: | ||
| + | restore2(tab, nrow, ncol, f1, f2) | ||
| + | print_table(tab, nrow, ncol + 2) | ||
| + | if tab == savetab: | ||
| + | print('OK') | ||
| + | else: | ||
| + | print('ERR!!!!') | ||
| + | |||
| + | if __name__ == "__main__": | ||
| + | main() | ||
| + | </source> | ||
Latest revision as of 16:36, 4 April 2023
Il codice python che segue consente di provare sperimentalemnte le metodologie di fault tolerance descritte nell'articolo "EVENODD: An Optimal Scheme for Tolerating Double Disk Failures" di Mario Blaurn et al.
#!/usr/bin/env python3
def compute_parity(tab, nrow, ncol):
for i in range(nrow):
p = 0
for j in range(ncol):
p ^= tab[i][j]
tab[i][ncol] = p
def compute_dparity(tab, nrow, ncol):
p = [0] * ncol
for i in range(nrow):
for j in range(ncol):
p[(i+j) % ncol] ^= tab[i][j]
# print(p)
s = p[ncol - 1]
for i in range(nrow):
tab[i][ncol + 1] = p[i] ^ s
def print_table(tab, nrow, ncol):
for i in range(nrow):
for j in range(ncol):
print(tab[i][j], end=" ")
print()
print()
def fail(tab, nrow, f):
for i in range(nrow):
tab[i][f] = 'x'
def restorep(tab, nrow, ncol, f):
for i in range(nrow):
p = tab[i][ncol]
for j in range(ncol):
if j != f:
p ^= tab[i][j]
tab[i][f] = p
def restored(tab, nrow, ncol, f):
p = [tab[i][ncol + 1] for i in range(nrow)] + [0]
for i in range(nrow):
for j in range(ncol):
if j != f:
p[(i+j) % ncol] ^= tab[i][j]
s = p[(f - 1) % ncol]
# print(p, s)
for i in range(nrow):
tab[i][f] = s ^ p[(f + i) % ncol]
def restore2(tab, nrow, ncol, f1, f2):
s = 0
for i in range(nrow):
s ^= tab[i][ncol] ^ tab[i][ncol + 1]
p = [s ^ tab[i][ncol + 1] for i in range(nrow)] + [s]
# print(s, p)
nindex = (nrow + f2) % ncol
for _ in range(nrow):
v = p[nindex]
# print(nindex, (nindex + 1) % ncol)
for i in range(nrow):
j = (nindex - i) % ncol
if j != f1:
v ^= tab[i][j]
else:
row = i
# print(row)
tab[row][f1] = v
nindex = (row + f2) % ncol
v = tab[row][ncol]
for j in range(ncol):
if j != f2:
v ^= tab[row][j]
tab[row][f2] = v
def main():
tab=[]
while True:
line = input("")
if len(line) <= 1:
break
tab.append([0 if x == "0" else 1 for x in line.split()] + [0, 0])
nrow = len(tab)
ncol = len(tab[0]) - 2
# print_table(tab, nrow, ncol)
compute_parity(tab, nrow, ncol)
# print_table(tab, nrow, ncol + 1)
compute_dparity(tab, nrow, ncol)
print_table(tab, nrow, ncol + 2)
savetab = tab
while True:
line = input("failure ")
s = line.split()
if len(s) == 2:
f1, f2 = int(s[0]), int(s[1])
elif len(s) == 1:
f1 = f2 = int(s[0])
else:
return
fail(tab, nrow, f1)
fail(tab, nrow, f2)
print_table(tab, nrow, ncol + 2)
if f1 == f2:
print("1 faulty", f1)
if f1 == ncol:
compute_parity(tab, nrow, ncol)
elif (f1 == ncol + 1):
compute_dparity(tab, nrow, ncol)
else:
restorep(tab, nrow, ncol, f1)
else:
if f1 > f2:
f1, f2 = f2, f1
print("2 faulty", f1, f2)
if f1 == ncol:
compute_parity(tab, nrow, ncol)
compute_dparity(tab, nrow, ncol)
elif f2 == ncol + 1:
restorep(tab, nrow, ncol, f1)
compute_dparity(tab, nrow, ncol)
elif f2 == ncol:
restored(tab, nrow, ncol, f1)
compute_parity(tab, nrow, ncol)
pass
else:
restore2(tab, nrow, ncol, f1, f2)
print_table(tab, nrow, ncol + 2)
if tab == savetab:
print('OK')
else:
print('ERR!!!!')
if __name__ == "__main__":
main()