Difference between revisions of "Esperimenti con RAID6 (2026)"

From Sistemi Operativi
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()