#! /bin/busybox ash

####### goto subdir $1 and create link $2 to ../../$MDEV
create_link()
{
    SUBDIR="$1"
    LINK="$2"
    printf 'Create %s --> ../../%s\n' "$1/$2" "$MDEV" >>$DEBUG_FILE
    (cd "$1"; ln -s "../../$MDEV" "$2")
    return
}

####### delete symlink in subdir $1, pointing to ../../$MDEV
delete_link()
{
    for link in "$1"/*; do
	file=`readlink "$link"`;
	if [ "$file" = "../../$2" ]; then
	    printf 'Delete %s\n' "$link" >>$DEBUG_FILE
	    rm -f "$link";
	fi
    done
    return
}

####### Get LABEL and UUID
get_label_and_uuid()
{
    UUID=''; LABEL='';
    LINE=$(blkid /dev/$MDEV)
    if [ -z "$LINE" ]; then
	return;
    fi;
    set $LINE
    eval $2
    eval $3
    
    # Sanitize label: label will be used as a filename ==> replace every '/'
    # by a '\', not forgetting that '\' is also shell's escape character
    [ -z "$LABEL" ] || LABEL=$(echo "$LABEL" | sed 's:/:\\:g')
    return
}

get_path()
{
    # Designed for Sata disks
    diskpath=$(readlink "/sys/class/block/$MDEV");
    # replace / by ' ' to easily parse link name
    set $(echo "$diskpath" | sed 's|/| |g')
    # loop on fields and use them to build path
    devpath='';  isscsi='false'; curpath='';
    I=1;
    while [ $I -le $# ]; do
	eval F=$"$I"; # current field
	printf '$%s = %s; curpath=%s, devpath=%s\n' "$I" "$F" "$curpath" "$devpath"
	case $F in
	    pci*)
		true $(( I++ )); # Consume one more field
		eval N=$"$I";
		devpath=pci-$N;  # Start path with eg pci-0000:00:1f.2
		curpath="/sys/devices/$F/$N"
		;;
	    host)
		curpath="$curpath/$F";
	        if [ -d "$curpath/scsi_host" ]; then
		    F='-scsi-';
		    devpath="$devpath$F";
		    isscsi='true';
		fi
		;;
	    target)
		if [ "$isscsi" = 'true' ]; then
		    true $(( I++ )); # Consume one more field
		    eval N=$"$I";
		    F='-'
		    devpath="$devpath$F$N"
		fi
		;;
	    *)
		[ -z "$curpath" ] || curpath="$curpath/$F";
		;;
	esac
	true $(( I++ ));
    done;

    # If this is a partition, add partition number
    partfile="/sys/block/$diskpath/partition";
    if [ -f "$partfile" ]; then
	partnum=read <"$partfile";
	F='-part';
	devpath="$devpath$F$partnum";
    fi;
}

#############################################################
DEBUG_FILE='/run/mdev-disk.log'

printf 'mdev-disk invoked with action=%s, device=%s and seqnum=%s\n' "$ACTION" "$MDEV" "$SEQNUM" >>$DEBUG_FILE

####### Make sure subdirs exist
[ -d /dev/disk ] || mkdir -m 0755 /dev/disk
[ -d /dev/disk/by-uuid ]  || mkdir -m 0755 /dev/disk/by-uuid
[ -d /dev/disk/by-label ] || mkdir -m 0755 /dev/disk/by-label
[ -d /dev/disk/by-path ]  || mkdir -m 0755 /dev/disk/by-path


####### Create or delete symlinks
case $ACTION in
    add)
	get_label_and_uuid
        # Create symlinks
	[ -z "$UUID" ]    || create_link '/dev/disk/by-uuid'  "$UUID"
	[ -z "$LABEL" ]   || create_link '/dev/disk/by-label' "$LABEL"
	get_path
	[ -z "$devpath" ] || create_link '/dev/disk/by-path'  "$devpath"
	;;

    remove)
        # Delete symlinks
	delete_link '/dev/disk/by-uuid'  "$MDEV"
	delete_link '/dev/disk/by-label' "$MDEV"
	delete_link '/dev/disk/by-path'  "$MDEV"
	;;
esac
