Dependencies:
- KnowledgeBase/hexdump.rb
- raid5.rb
#!/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