#!/bin/sh DATABASE=/dev/.bdev mk_dev() { NAME=$1-${2/\//-} ( /sbin/dmsetup -v create $NAME || \ /sbin/dmsetup remove $NAME &> /dev/null ) | \ sed -e '/minor:/!d;s/^[^0-9]*\([0-9]*\),[^0-9]*\([0-9]*\).*$/\1:\2/' } rm_dev() { NAME=$1-${2/\//-} /sbin/dmsetup remove $NAME &> /dev/null } mk_nod() { /bin/mknod /dev/$1 b ${2%:[0-9]*} ${2#[0-9]*:} } rm_nod() { rm -f /dev/$1 } #################################################################### mk_part() { echo part $1 $2 $3 $4 >> /tmp/log NDEV=$(echo "0 $3 linear $4 $2" | mk_dev part $1 $4) if [ -z "$NDEV" ]; then return 1 fi OF=$DATABASE/of/$5 TO=$DATABASE/to/$NDEV echo TYPE=part > $TO echo NAME=$1 >> $TO echo "LIST=\"\$LIST $NDEV\"" >> $OF } get_parts() { /sbin/sfdisk -dfqL /dev/$1 2> /dev/null | \ sed -s '/start=/!d;s/[=,]/ /g;s/^\/dev\/tmp-//' | \ awk '{ print $1 " " $4 " " $6 }' } check_parts() { get_parts $4 | \ while read PART START SIZE; do if [ "$SIZE" -gt 0 ]; then mk_part $PART $START $SIZE $3 $2 fi done } rm_part() { rm_dev part $1 } ################################################################## register_dev() { echo register $1 $2 >> /tmp/log echo DEV=$2 > $DATABASE/of/$1 } unregister_dev() { echo unregister $1 $2 >> /tmp/log rm -f $DATABASE/of/$1 } add_dev() { if [ -f $DATABASE/to/$2 ]; then source $DATABASE/to/$2 else NAME=$1 RET=1 fi echo add "$NAME $2" >> /tmp/log TMP=tmp-$NAME mk_nod $TMP $2 check_parts $1 $NAME $2 $TMP rm_nod $TMP } notify_dev() { echo notify $TYPE $1 $2 >> /tmp/log case $TYPE in part) rm_part $1 $2 ;; esac } remove_dev() { if [ -f $DATABASE/to/$2 ]; then source $DATABASE/to/$2 rm -f $DATABASE/to/$2 else NAME=$1 RET=1 fi echo remove $NAME $2 >> /tmp/log for i in $LIST; do if [ -e $DATABASE/to/$i ]; then source $DATABASE/to/$i notify_dev $NAME $i fi done } ################################################################## if [ ${DEVPATH} == ${DEVPATH#/block} ]; then exit 1 fi if [ -n "$2" ]; then ACTION=add KERNEL=$1 DEV=$2 if [ ! -f /sys/block/$KERNEL/dev ]; then exit 0 fi else if [ "$ACTION" != remove ]; then exit 0 fi KERNEL=${DEVPATH##*/} fi dotlockfile -r3 -p $DATABASE/lock || exit 1 RET=0 NAME="" echo action $ACTION >> /tmp/log case "$ACTION" in add) if [ ! -f $DATABASE/uptodate ]; then rm -Rf $DATABASE/of $DATABASE/to mkdir -p $DATABASE/of $DATABASE/to for i in /sys/block/*; do register_dev ${i#/sys/block/} $(<$i/dev) done touch $DATABASE/uptodate if [ -e $DATABASE/of/$KERNEL ]; then add_dev $KERNEL $DEV fi else if [ ! -e $DATABASE/of/$KERNEL ]; then register_dev $KERNEL $DEV if [ -e $DATABASE/of/$KERNEL ]; then add_dev $KERNEL $DEV fi fi fi ;; remove) if [ -e $DATABASE/of/$KERNEL ]; then LIST="" source $DATABASE/of/$KERNEL remove_dev $KERNEL $DEV unregister_dev $KERNEL $DEV fi ;; esac dotlockfile -u $DATABASE/lock if [ $RET -gt 0 ]; then exit 1 else if [ -n "$NAME" ]; then echo result $NAME >> /tmp/log case $ACTION in add) mk_nod $NAME $DEV ;; remove) rm_nod $NAME esac else echo ignore >> /tmp/log fi exit 0 fi