samba
11/28/2012 - 5:38 AM

Superblock finder

Superblock finder

#!/bin/sh

# A tool to find superblocks in an EXT4 volume (probably easily adapted for EXT2,3)
# The usecase for this tool is likely pretty narrow...
# I have an LVM volume on a RAID array that was incorrectly reassembled (i.e. recreated)
# in the wrong order (I think), and I'm trying to recover from it, but it's unrecognizable
# as a filesystem since the primary superblock is missing. 
# This tool identifies all (seemingly) valid superblocks in a volume, though using them may
# introduce other errors if your filesystem is badly damaged. USE WITH CAUTION.
# The goal is to estimate how far offset the superblocks are and if disc order in the array
# impacts positioning of the superblocks, and thereby predict (if possible) a correct order.

DEVICE=$1
START=${2:-1}
END=${3:-45000}


findblock () {
        local start=$2 end=$3 device=$1;
        for i in `seq $start $end`; do
                fsck.ext4 -v -n -b $i $device 2>/dev/null 1>/dev/null
                [ $? -eq 8 ] && continue;
                echo '# found:' $i
                return 0
        done
        return 1
}

case $START in
        auto) 
                findblock $DEVICE 8000 9000 || echo '# missing 8192';
                findblock $DEVICE 32000 33000 || echo '# missing 32768';
                findblock $DEVICE 98000 99000 || echo '# missing 98304';
                findblock $DEVICE 163000 164000 || echo '# missing 163840';
                findblock $DEVICE 229000 230000 || echo '# missing 229376';
                findblock $DEVICE 294000 295000 || echo '# missing 294912';
                findblock $DEVICE 819000 820000 || echo '# missing 819200';
                findblock $DEVICE 884000 885000 || echo '# missing 884376';
                findblock $DEVICE 1605000 1606000 || echo '# missing 1605632';
                findblock $DEVICE 2654000 2653000 || echo '# missing 2654208';
                findblock $DEVICE 4095500 4096500 || echo '# missing 4096000';
                findblock $DEVICE 7962000 7963000 || echo '# missing 7962624';
                findblock $DEVICE 11239000 11240000 || echo '# missing 11239424';
                findblock $DEVICE 20479000 20481000 || echo '# missing 20480000';
        ;;
        *) findblock $DEVICE $START $END;;
esac