#!/bin/sh
#
# activate_dm_linear
#
# Activate a linear mapping on top of an existing block device.
# This allows for partitions to be mapped via kpartx, so all
# partitions on a device can be accessed.
#

RULE=/etc/udev/rules.d/62-dm_linear.rules

if [ -z "$1" ] ; then
    echo "Usage: $0 [-d] devname"
    exit 1
fi

if [ "$1" == "-d" ] ; then
    remove_only=1
    shift
fi

if [ ! -b "$1" ] ; then
    echo "$1 is not a block device"
    exit 1
fi

dev=${1#/dev/}

if [ ! -d /sys/block/$dev ] ; then
    echo "$1 is not a disk device"
    exit 1
fi

blksize=$(/sbin/blockdev --getsize $1)
if [ $? -ne 0 ] ; then
    echo "blockdev --getsize $1 failed: $?"
    exit 1
fi

for link in $(udevinfo -q symlink -p /block/$dev) ; do
    case "$link" in
	*/by-id/ata*)
            atalink=${link#*/by-id/ata-}
	    ;;
	*/by-id/scsi*)
	    scsilink=${link#*/by-id/scsi-}
	    ;;
    esac
done
if [ "$atalink" ] ; then
    serial="$atalink"
    bus="ata"
fi
if [ "$scsilink" ] ; then
    unset atalink
    serial="$scsilink"
    bus="scsi"
fi
if [ "$serial" ]; then
    # Remove existing rules
    echo "/$serial/d
w
q
" | ed $RULE > /dev/null 2>&1
    [ "$remove_only" = 1 ] && exit 0
    # And create a new one
    if [ "$atalink" ] ; then
	cat >> $RULE <<EOF
ACTION=="add", KERNEL=="sd*[!0-9]", ENV{ID_VENDOR}=="ATA", ENV{ID_ATA_COMPAT}=="$serial", RUN+="dm_linear /dev/\$kernel $blksize ata-\$env{ID_ATA_COMPAT}"
EOF
    else
	cat >> $RULE <<EOF
ACTION=="add", KERNEL=="sd*[!0-9]", ENV{ID_BUS}=="$bus", ENV{ID_SERIAL}=="$serial", RUN+="dm_linear \$kernel /dev/$blksize \$env{ID_BUS}-\$env{ID_SERIAL}"
EOF
    fi
fi
