Dependencies:
#!/usr/bin/env ruby
require 'mmap'
require 'hexdump'
require 'raid5'
base = "stride"
base = sprintf("%s/%s", File.dirname(__FILE__), base)
badblocks = File.open('%s/bad' % base, 'w')
bstart = 147060
blocks = 171520
blksz = 512
zeroes = "\0" * blksz
sda = Mmap.new('%s/sda' % base, 'r')
sdb = Mmap.new('%s/sdb' % base, 'rw')
sdc = Mmap.new('%s/sdc-good' % base, 'r')
sdd = Mmap.new('%s/sdd' % base, 'r')
sde = Mmap.new('%s/sde' % base, 'r')
[ sda, sdb, sdc, sdd, sde ].each {|map| map.madvise(Mmap::MADV_DONTNEED) }
Range.new(bstart, blocks - 1).each {|index|
if index % 8 == 0
printf("\r %06u/%06u ", index, blocks - 1)
STDOUT.flush
end
offset = blksz * index
b_sda = sda[offset, blksz]
b_sdb = sdb[offset, blksz]
b_sdc = sdc[offset, blksz]
b_sdd = sdd[offset, blksz]
b_sde = sde[offset, blksz]
unless xor_block(b_sda, b_sdb, b_sdc, b_sdd, b_sde) == zeroes
printf("\r %06u/%06u %s ", index, blocks - 1, "Mismatch")
resolution = "Untouched"
if b_sdb == zeroes
good_sdb = xor_block(b_sda, b_sdc, b_sdd, b_sde)
sdb[offset, blksz] = good_sdb
sdb.flush
resolution = "Repaired"
end
printf("%s\n", resolution)
# Log the details of the failure
badblocks << sprintf("====\n#{index} - Z:%s\n", (b_sdb == zeroes).inspect)
badblocks << "%s\n" % resolution
badblocks << hexdump(b_sdb) unless b_sdb == zeroes
badblocks << "Should be\n"
badblocks << hexdump(xor_block(b_sda, b_sdc, b_sdd, b_sde))
badblocks << "\n"
end
}
printf("\r %1$06u/%1$06u\nAll done!\n", blocks - 1)
exit
kaboom unless xor_block(sda, sdb, sdc, sdd) == sde
#sdb = xor_block(sda, sdc, sdd, sde)
#File.open('%s/sdb' % base, 'w').write(sdb)
# dd if=sdb of=/dev/sdb bs=512 count=8 seek=976601648
