HDDイメージをブロックデバイスにマップするスクリプト for linux

が転がっていたので忘れないうちに貼り付けておこう。
パーティションイメージではなくてHDDイメージ。VMを使っているとHDDイメージの中のパーティションを mount したくなるときがあって、このスクリプトを使うとお手軽に個々のパーティションをそれぞれブロックデバイスに割り付けられる。
sfdisk を使ってパーティションのオフセットを解析して、Device Mapper に割り当てている。

split-hddimg

#!/bin/bash
if [ -z "$2" ]; then
	echo "Usage: `basename $0` <hdd image> </dev/loopX>"
	exit 1
fi

img=$1
dev=$2
if ! losetup $dev $img; then
	echo "losetup failed."
	exit 1
fi


sfdisk=$(which sfdisk)
dmsetup=$(which dmsetup)

# expand link
if [ -L $dev ];then
	realdev=$(dirname $dev)/$(readlink $dev)
else
	realdev=$dev
fi

devdir=$(dirname $realdev)
devfile=$(basename $realdev)

# expand relative path
if ! echo "$devdir" | grep -q '^/'; then
	devdir="$(pwd)/devdir/"
else
	devdir="$devdir/"
fi

# expand .
while echo "$devdir" | grep -q '/\./'; do
	devdir="$(echo "$devdir" | sed -e 's/\/\.\//\//g')"
done
# expand ..
while echo "$devdir" | grep -q '/[^/][^/]*/\.\./'; do
	devdir="$(echo "$devdir" | sed -e 's/\/[^/][^/]*\/\.\.\//\//g')"
done

device="$devdir$devfile"
if [ ! -b "$device" -o ! -r "$device" ]; then
	echo "Error: Block device $1 can't be accessed"
	losetup -d $dev
	exit 1
fi
if [ ! -n "$sfdisk" -o ! -x "$sfdisk" ]; then
	echo "Error: sfdisk utility not found"
	losetup -d $dev
	exit 1
fi
if [ ! -n "$dmsetup" -o ! -x "$dmsetup" ]; then
	echo "Error: dmsetup utility not found"
	losetup -d $dev
	exit 1
fi

if [ ! -c /dev/mapper/control ];then
	modprobe dm_mod
fi

$sfdisk -d "$device" | grep "^ *$devdir" | sed -e 's/[=,]/ /g' | awk '{ print $1 " " $4 " " $6 }' | \
while read DEV START SIZE; do
	DEV="$(echo "$DEV" | sed -e 's/^\/dev\///' -e 's/\//-/g')"
	test "$SIZE" -gt 0 || continue
	echo "/dev/mapper/$DEV $START $SIZE"
	echo "0 $SIZE linear $device $START" | $dmsetup create $DEV
done

echo "OK. Use unsplit-hddimg $dev to unmap partitions."

unsplit-hddimg

#!/bin/bash
if [ -z "$1" ]; then
	echo "Usage: `basename $0` </dev/loopX>"
	exit 1
fi

dev=$1
sfdisk=$(which sfdisk)
dmsetup=$(which dmsetup)

# expand link
if [ -L $dev ];then
	realdev=$(dirname $dev)/$(readlink $dev)
else
	realdev=$dev
fi

devdir=$(dirname $realdev)
devfile=$(basename $realdev)

# expand relative path
if ! echo "$devdir" | grep -q '^/'; then
	devdir="$(pwd)/devdir/"
else
	devdir="$devdir/"
fi

# expand .
while echo "$devdir" | grep -q '/\./'; do
	devdir="$(echo "$devdir" | sed -e 's/\/\.\//\//g')"
done
# expand ..
while echo "$devdir" | grep -q '/[^/][^/]*/\.\./'; do
	devdir="$(echo "$devdir" | sed -e 's/\/[^/][^/]*\/\.\.\//\//g')"
done

device="$devdir$devfile"
if [ ! -b "$device" -o ! -r "$device" ]; then
	echo "Error: Block device $1 can't be accessed"
	exit 1
fi
if [ ! -n "$sfdisk" -o ! -x "$sfdisk" ]; then
	echo "Error: sfdisk utility not found"
	exit 1
fi
if [ ! -n "$dmsetup" -o ! -x "$dmsetup" ]; then
	echo "Error: dmsetup utility not found"
	exit 1
fi

$sfdisk -d "$device" | grep "^ *$devdir" | sed -e 's/[=,]/ /g' | awk '{ print $1 " " $4 " " $6 }' | \
while read DEV START SIZE; do
	DEV="$(echo "$DEV" | sed -e 's/^\/dev\///' -e 's/\//-/g')"
	test "$SIZE" -gt 0 || continue
	echo "removing $DEV"
	$dmsetup remove $DEV
done
losetup -d $device