Difference between revisions of "Esperimenti con RAID6 (2026)"
Jump to navigation
Jump to search
(Created page with "Il codice python che segue consente di provare sperimentalemnte le metodologie di fault tolerance descritte nell'articolo "EVENODD: An Optimal Scheme for Tolerating Double Dis...") |
m |
||
| Line 1: | Line 1: | ||
| − | 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. | + | 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. | ||
| + | |||
| + | <source lang=python> | ||
| + | #!/usr/bin/env python3 | ||
| + | |||
| + | def print_table(tab, nrow, ncol): | ||
| + | for i in range(nrow): | ||
| + | for j in range(ncol): | ||
| + | print(tab[i][j], end=" ") | ||
| + | print() | ||
| + | print() | ||
| + | |||
| + | # delete a column | ||
| + | def fail(tab, nrow, f): | ||
| + | for i in range(nrow): | ||
| + | tab[i][f] = 'x' | ||
| + | |||
| + | # compute row parity | ||
| + | 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 | ||
| + | |||
| + | # compute diagonal parity | ||
| + | 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): the last parity is encoded | ||
| + | # if s negate all the diag parity values | ||
| + | s = p[ncol - 1] | ||
| + | for i in range(nrow): | ||
| + | tab[i][ncol + 1] = p[i] ^ s | ||
| + | |||
| + | # restore row parity | ||
| + | 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 | ||
| + | |||
| + | # restore diagonal parity | ||
| + | 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] | ||
| + | # the last parity is encoded | ||
| + | # if s negate all the diag parity values | ||
| + | s = p[(f - 1) % ncol] | ||
| + | # print(p, s) | ||
| + | for i in range(nrow): | ||
| + | tab[i][f] = s ^ p[(f + i) % ncol] | ||
| + | |||
| + | # restore 2 data columns | ||
| + | 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 | ||
| + | |||
| + | # MAIN | ||
| + | def main(): | ||
| + | # input the table | ||
| + | tab=[] | ||
| + | while True: | ||
| + | line = input("") | ||
| + | if len(line) <= 1: | ||
| + | break | ||
| + | tab.append([int(x) for x in line.split()] + [0, 0]) | ||
| + | nrow = len(tab) | ||
| + | ncol = len(tab[0]) - 2 | ||
| + | # add parities row + diag | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | print_table(tab, nrow, ncol + 2) | ||
| + | |||
| + | savetab = tab | ||
| + | |||
| + | while True: | ||
| + | line = input("failure ") | ||
| + | s = line.split() | ||
| + | # failures: 1 or 2 columns | ||
| + | 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) | ||
| + | # missing row parity | ||
| + | if f1 == ncol: | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | # missing diag parity | ||
| + | elif (f1 == ncol + 1): | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | # missing data | ||
| + | else: | ||
| + | restorep(tab, nrow, ncol, f1) | ||
| + | else: | ||
| + | if f1 > f2: | ||
| + | f1, f2 = f2, f1 | ||
| + | print("2 faulty", f1, f2) | ||
| + | if f1 == ncol: | ||
| + | # missind both parities | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | # missind data + row parity | ||
| + | elif f2 == ncol + 1: | ||
| + | restorep(tab, nrow, ncol, f1) | ||
| + | compute_dparity(tab, nrow, ncol) | ||
| + | # missind data + diag parity | ||
| + | elif f2 == ncol: | ||
| + | restored(tab, nrow, ncol, f1) | ||
| + | compute_parity(tab, nrow, ncol) | ||
| + | pass | ||
| + | # missing two data columns | ||
| + | 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 13:09, 17 March 2026
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 print_table(tab, nrow, ncol):
for i in range(nrow):
for j in range(ncol):
print(tab[i][j], end=" ")
print()
print()
# delete a column
def fail(tab, nrow, f):
for i in range(nrow):
tab[i][f] = 'x'
# compute row parity
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
# compute diagonal parity
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): the last parity is encoded
# if s negate all the diag parity values
s = p[ncol - 1]
for i in range(nrow):
tab[i][ncol + 1] = p[i] ^ s
# restore row parity
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
# restore diagonal parity
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]
# the last parity is encoded
# if s negate all the diag parity values
s = p[(f - 1) % ncol]
# print(p, s)
for i in range(nrow):
tab[i][f] = s ^ p[(f + i) % ncol]
# restore 2 data columns
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
# MAIN
def main():
# input the table
tab=[]
while True:
line = input("")
if len(line) <= 1:
break
tab.append([int(x) for x in line.split()] + [0, 0])
nrow = len(tab)
ncol = len(tab[0]) - 2
# add parities row + diag
compute_parity(tab, nrow, ncol)
compute_dparity(tab, nrow, ncol)
print_table(tab, nrow, ncol + 2)
savetab = tab
while True:
line = input("failure ")
s = line.split()
# failures: 1 or 2 columns
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)
# missing row parity
if f1 == ncol:
compute_parity(tab, nrow, ncol)
# missing diag parity
elif (f1 == ncol + 1):
compute_dparity(tab, nrow, ncol)
# missing data
else:
restorep(tab, nrow, ncol, f1)
else:
if f1 > f2:
f1, f2 = f2, f1
print("2 faulty", f1, f2)
if f1 == ncol:
# missind both parities
compute_parity(tab, nrow, ncol)
compute_dparity(tab, nrow, ncol)
# missind data + row parity
elif f2 == ncol + 1:
restorep(tab, nrow, ncol, f1)
compute_dparity(tab, nrow, ncol)
# missind data + diag parity
elif f2 == ncol:
restored(tab, nrow, ncol, f1)
compute_parity(tab, nrow, ncol)
pass
# missing two data columns
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()