devnums="`deviceid $1`"
dmsetup ls --target crypt | awk '{print $1}' | while read dmdev; do
- if dmsetup deps $dmdev | grep -qF "$devnums"; then
- echo "/dev/mapper/$dmdev"
- fi
+ if dmsetup deps $dmdev | grep -qF "$devnums"; then
+ echo "/dev/mapper/$dmdev"
+ fi
done
}
describe_raid()
{
- echo " RAID level 1"
+ echo " RAID level 1/5"
}
do_raid()
{
local mddevice
local mdlevel
+ local mdlayout
echo "# $device: RAID detected" 1>&2
mddevice="`mdadm -Q $device | sed -ne 's/.*\(raid[0-9] \/dev\/[^.]*\).*/\1/' -eT -ep`"
if [ -z "$mddevice" ]; then
- echo "! raid master device for raid componentn device $device not found" 1>&2
- exit 1
+ echo "! raid master device for raid componentn device $device not found" 1>&2
+ exit 1
fi
mdlevel="${mddevice% *}"
mddevice="${mddevice#* }"
-
+
echo "device $mddevice md"
echo "raidlevel $mdlevel"
- echo "sector $sector"
+ case "$mdlevel" in
+ raid1) ;;
+ raid5) do_raid_raid5 $mddevice ;;
+ *)
+ echo "! unsopported raid level $mdlevel" 1>&2
+ exit 1
+ ;;
+ esac
+
+ echo "sector $sector"
device="$mddevice"
return 1
}
+raid5_leftsymmetric_calc()
+{
+ local ndrives="$1"
+ local drive="$2" # range 0..$ndrives-1
+ local chunk="$3"
+
+ # Algorithm:
+ #
+ # block = chunk / ndrives
+ # blockrow = chunk % ndrives
+ # if blockrow == ndrives-drive-1:
+ # return 'parity'
+ # else:
+ # if drive > ndrives-blockrow-1:
+ # blockrow = blockrow - 1
+ # return block*ndrives*(ndrives-1) + blockrow*ndrives + drive
+
+ dc -e "$chunk $ndrives ~ d $ndrives $drive - 1 - [q]sa=a" \
+ -e "d $ndrives r - 1 - $drive [1-]sa<a" \
+ -e "$ndrives * $drive + r $ndrives * $ndrives 1 - * + p"
+}
+
+do_raid_raid5()
+{
+ local mddevice="$1"
+ local mdlayout
+ local mdcalc
+ local mdchunksize
+ local mddrives
+ local mddrive
+ local chunk
+ local mdchunk
+
+ mdlayout="`mdadm -D $mddevice | awk '/Layout :/{print $3}'`"
+ echo "raidlayout $mdlayout"
+ case "$mdlayout" in
+ left-symmetric) mdcalc="raid5_leftsymmetric_calc" ;;
+ *)
+ echo "! unsopported raid layout $mdlayout" 1>&2
+ exit 1
+ ;;
+ esac
+
+ mdchunksize="`mdadm -D $mddevice | awk '/Chunk Size :/{print $4}'`"
+ mdchunksize="`dc -e "${mdchunksize%K} 2 * p"`"
+ mddrives="`mdadm -D $mddevice | awk '/Raid Devices :/{print $4}'`"
+ mddrive="`mdadm -D $mddevice | awk "/${device##*/}"'$/{print $4}'`"
+
+ echo "raiddrives $mddrives"
+ echo "raiddrive $mddrive"
+ echo "chunksize $mdchunksize"
+
+ chunk="`dc -e "$sector $mdchunksize ~ n [ ] n p"`"
+ subsector="${chunk% *}"
+ chunk="${chunk#* }"
+
+ echo "chunk $chunk"
+ echo "subsector $subsector"
+
+ mdchunk="`$mdcalc $mddrives $mddrive $chunk`"
+ if [ -z "$mdchunk" ]; then
+ echo "chunktype parity"
+ echo "! no parity chunk support"
+ exit 1
+ fi
+
+ echo "chunktype data"
+ echo "raidchunk $mdchunk"
+
+ sector="`dc -e "$mdchunk $mdchunksize * $subsector + p"`"
+}
+
register_mapper "raid"
devnums="`deviceid $device`"
while read dev dir opts; do
- case "$dev" in
- *:*) ;;
- *)
- if [ "$devnums" == "`deviceid $dev`" ]; then
- echo "mountpoint $dir"
- break
- fi
- ;;
- esac
+ case "$dev" in
+ *:*) ;;
+ *)
+ if [ "$devnums" == "`deviceid $dev`" ]; then
+ echo "mountpoint $dir"
+ break
+ fi
+ ;;
+ esac
done < /proc/mounts
-
+
return 1
}
offset="`cryptsetup luksDump $device 2>/dev/null | awk '/^Payload offset/{print $3}'`"
if [ -z "$offset" ]; then
- # Plain dmcrypt
- offset=0
- type=dmcrypt
+ # Plain dmcrypt
+ offset=0
+ type=dmcrypt
else
- type=luks
+ type=luks
fi
cryptdev="`dmcryptmap $device`"
if [ -z "$cryptdev" ]; then
- echo "! Failed to find decrypted mapper device for $device"
- exit 1;
+ echo "! Failed to find decrypted mapper device for $device"
+ exit 1;
fi
cryptsector="`dc -e "$sector $offset - p"`" #`"
echo "device $cryptdev crypt"
echo "type $type"
echo "sector $cryptsector"
-
+
device="$cryptdev"
sector="$cryptsector"
local fssector
echo "# $device: LVM detected" 1>&2
-
+
# Step 3: Get pysical extent number
pvname="`pvdisplay -c $device 2>/dev/null | awk -F: '{print $1,$2,$8}' | sed -e 's/^ *//'`"
if [ -z "$pvname" ]; then
- echo "! $device is not a physical volume" 1>&2
- exit 1
+ echo "! $device is not a physical volume" 1>&2
+ exit 1
fi
pesize="${pvname##* }"
# Step 4: Find associated logical volume
lestart="$(vgdisplay -v $vgname 2>/dev/null | awk '/LV Name/{print $3}' | while read lvname; do \
- lvdisplay -m $lvname 2>/dev/null \
- | awk -v RS="\n *\n( --- Segments ---\n)?" \
- -F"[ \t\n:]+" \
- -v pvname="$pvname" \
- -v penum="$penum" \
- -v lvname="$lvname" \
- '$0 ~ "Physical volume[ \t]+" pvname && $14<=penum && $16>=penum{print lvname,$4,$14}'; \
- done)"
+ lvdisplay -m $lvname 2>/dev/null \
+ | awk -v RS="\n *\n( --- Segments ---\n)?" \
+ -F"[ \t\n:]+" \
+ -v pvname="$pvname" \
+ -v penum="$penum" \
+ -v lvname="$lvname" \
+ '$0 ~ "Physical volume[ \t]+" pvname && $14<=penum && $16>=penum{print lvname,$4,$14}'; \
+ done)"
if [ -z "$lestart" ]; then
- echo "# pysical extent $penum of $pvname is not mapped in any logical volume" 1>&2
- exit 0
+ echo "# pysical extent $penum of $pvname is not mapped in any logical volume" 1>&2
+ exit 0
fi
lvname="${lestart%% *}"
partdev="`fdisk -ul $device | awk -v sector="$sector" -F '[ *]+' '/^\// && !/Extended$/ && $2<=sector && $3>=sector {print $1,$2}'`" #`"
if [ -z "$partdev" ]; then
- echo "# sector $sector is not part of any partition on $device" 1>&2
- exit 0
+ echo "# sector $sector is not part of any partition on $device" 1>&2
+ exit 0
fi
partstart="${partdev#* }"
fsblocksize="`tune2fs -l $device | awk '/Block size/{print $3/512}'`"
if [ -z "$fsblocksize" ]; then
- echo "! $device is not ext2/ext3" 1>&2
- exit 1
+ echo "! $device is not ext2/ext3" 1>&2
+ exit 1
fi
fsblock="`dc -e "$sector $fsblocksize ~ n [ ] n p"`" #`"
# Step 7: Check, whether block is in use
if echo "testb $fsblock" | debugfs $device 2>/dev/null | grep -qF "not in use"; then
- echo "blockstate free"
- exit 0
+ echo "blockstate free"
+ exit 0
fi
echo "blockstate used"
inode="`echo "icheck $fsblock" | debugfs $device 2>/dev/null | awk 'FNR>1{print $2}'`" #`"
if [ -z "$inode" ]; then
- echo "blocktype meta?"
- exit 0
+ echo "blocktype meta?"
+ exit 0
fi
echo "inode $inode"
# Step 9: Find file name(s) referencing the inode
(
- namefound="$(\
- echo "ncheck $inode" \
- | debugfs $device 2>/dev/null \
- | sed -e '1d' -e 's/^[0-9]*[ ]*//' -e 's/^\/\//\//' \
- | while read name; do \
- if [ -z "$firstname" ]; then \
- echo "blocktype data" 1>&3; \
- echo "1"; \
- firstname=1; \
- fi; \
- echo "name $name" 1>&3; \
- done \
- )"
- if [ -z "$namefound" ]; then
- echo "blocktype journal?"
- fi
+ namefound="$(\
+ echo "ncheck $inode" \
+ | debugfs $device 2>/dev/null \
+ | sed -e '1d' -e 's/^[0-9]*[ ]*//' -e 's/^\/\//\//' \
+ | while read name; do \
+ if [ -z "$firstname" ]; then \
+ echo "blocktype data" 1>&3; \
+ echo "1"; \
+ firstname=1; \
+ fi; \
+ echo "name $name" 1>&3; \
+ done \
+ )"
+ if [ -z "$namefound" ]; then
+ echo "blocktype journal?"
+ fi
) 3>&1
return 0
local blocksize
local block
local subsector
-
+
echo "# $device: reiserfs filesystem detected" 1>&2
echo "fstype reiserfs"
# Step 6: Get filesystem blocksize and convert sector number to filesystem block number
blocksize="`debugreiserfs $device 2>/dev/null | awk '/^Blocksize:/{print $2/512}'`"
-
+
if [ -z "$blocksize" ]; then
- echo "! $device is not reiserfs" 1>&2
- exit 1
+ echo "! $device is not reiserfs" 1>&2
+ exit 1
fi
block="`dc -e "$sector $blocksize ~ n [ ] n p"`" #`"
# Step 7: Check, whether block is in use
if debugreiserfs -1 $block $device 2>&1 >/dev/null | grep -qF "free in ondisk bitmap"; then
- echo "blockstate free"
- exit 0
+ echo "blockstate free"
+ exit 0
fi
echo "blockstate used"
type="`debugreiserfs -1 $block $device 2>/dev/null | sed -e '/^=*$/d' | head -1`"
case "$type" in
- "Looks like unformatted") type="data" ;;
- "Reiserfs super block"*) type="superblock" ;;
- "LEAF NODE"*) type="meta" ;;
- "INTERNAL NODE"*) type="meta" ;;
- "Desc block"*) type="journal" ;;
- *) type="" ;;
+ "Looks like unformatted") type="data" ;;
+ "Reiserfs super block"*) type="superblock" ;;
+ "LEAF NODE"*) type="meta" ;;
+ "INTERNAL NODE"*) type="meta" ;;
+ "Desc block"*) type="journal" ;;
+ *) type="" ;;
esac
if [ -n "$type" ]; then
- echo "blocktype $type"
+ echo "blocktype $type"
fi
# Step 8: Find object id to which this block belongs
if entry is None:
return [ '/' ]
else:
- rv = []
- for name, parent in entry:
- for path in scan_path(parent):
- rv.append(os.path.join(path,name))
- return rv
+ rv = []
+ for name, parent in entry:
+ for path in scan_path(parent):
+ rv.append(os.path.join(path,name))
+ return rv
def parse():
global fp
while True:
- while True:
- l = fp.readline()
+ while True:
+ l = fp.readline()
#sys.stderr.write("> parse: %s\n" % repr(l))
- if not(l) : return
+ if not(l) : return
if l.strip() == 67*"=" : break
- parse_leafnode()
+ parse_leafnode()
parse()
X="`dirname "$0"`"
if [ "`basename "$X"`" == "bin" ]; then # `"
- libdir="`dirname "$X"`/share/$name" #`"
+ libdir="`dirname "$X"`/share/$name" #`"
fi
if [ -z "$libdir" -o ! -d "$libdir" ]; then
- libdir="$X/lib"
+ libdir="$X/lib"
fi
if [ ! -d "$libdir" ]; then
- echo "! Library directory not found" 1>&2
- exit 1
+ echo "! Library directory not found" 1>&2
+ exit 1
fi
for lib in `ls "$libdir"/[0-9][0-9]_*.sh | sort`; do
- source $lib
+ source $lib
done
}
local found
found=1
while [ -n "$found" ]; do
- found=""
- for name in $mappers; do
- if detect_$name; then
- found=1
- if do_$name; then
- return
- fi
- break
- fi
- done
+ found=""
+ for name in $mappers; do
+ if detect_$name; then
+ found=1
+ if do_$name; then
+ return
+ fi
+ break
+ fi
+ done
done
}
scan()
{
for name in $scanners; do
- if detect_$name; then
- if do_$name; then
- return
- fi
- fi
+ if detect_$name; then
+ if do_$name; then
+ return
+ fi
+ fi
done
}
while true; do
case "$1" in
- -h|--help) help="0"; shift ;;
- --noscan) noscan="0"; shift ;;
- -V|--version) echo "$name $version"; exit 0 ;;
- --) shift; break ;;
- *) echo "! internal error"; exit 1 ;;
+ -h|--help) help="0"; shift ;;
+ --noscan) noscan="0"; shift ;;
+ -V|--version) echo "$name $version"; exit 0 ;;
+ --) shift; break ;;
+ *) echo "! internal error"; exit 1 ;;
esac
done
EOF
for mapper in $mappers; do
- describe_$mapper
+ describe_$mapper
done
cat <<EOF
EOF
for scanner in $scanners; do
- describe_$scanner
+ describe_$scanner
done
cat <<EOF