#!/bin/bash
# 
# Determine whether certain disks are ASM disks
#


# Force LC_ALL=C
export LC_ALL=C
 
USAGE="[-l <manager>] [-v] [-d|-p] <label>|<device> ..."

exec 3>/dev/null

help=
verbose=
version=
usage=
device=
paths=
while case "$#" in 0) break ;; esac
do
    case "$1" in
    -l|--manager)
        case "$#" in 1) usage=t; break ;; esac
        shift
        ORACLE_ASMMANAGER="$1"
        ;;
    -d|--device)
        device=t
        ;;
    -p|--paths)
        paths=t
        ;;
    -v|--verbose)
        verbose=t
        exec 3>&2
        ;;
    -V|--version)
        version=t
        ;;
    -h|--help)
        help=t
        ;;
    -*)
        usage=t
        ;;
    *)
        break
        ;;
    esac
    shift
done

# Load configuration
. oracleasm-Xshlib

if [ "$help" = "t" -o "$usage" = "t" ]
then
    usage
fi

if [ "$version" = "t" ]
then
    version
fi



get_paths()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        die "get_paths(): Requires an argument"
    fi

    LABEL="$1"

    # Must use absolute path to which(1) because RedHat aliases it
    BLKID="$(/usr/bin/which blkid 2>/dev/null)"
    [ -z "$BLKID" ] && die "Path scan support is not available"

    $BLKID -t "LABEL=${LABEL}" 2>/dev/null | grep 'TYPE="oracleasm"'
}

#
# Check if the disk is an ASM disk
#
check_disk()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        die "check_disk(): Requires an argument"
    fi

    DISKNAME="$(upper_disk "$1")"
    if [ -z "$DISKNAME" ]
    then
        return 1
    fi

    disk_path="$(asm_disk_path "${ORACLE_ASMMANAGER}" "${DISKNAME}")"
    if [ ! -e "$disk_path" ]
    then
        echo "Disk \"$DISKNAME\" does not exist or is not instantiated" >&2
        return 1
    fi

    INFO="$(oracleasm-read-label "${disk_path}" 2>&3)"
    if [ -z "$INFO" ]
    then
        echo "Disk \"$DISKNAME\" defines an unmarked device" >&2
        return 1
    fi

    LABEL="$(echo "$INFO" | cut -f1 -d:)"
    if [ -z "$LABEL" ]
    then
        echo "Disk \"$DISKNAME\" defines a device with no label" >&2
        return 1
    fi

    if [ "$LABEL" != "$DISKNAME" ]
    then
        echo "Disk \"$DISKNAME\" is labeled for disk \"$LABEL\"" >&2
        return 1
    fi

    if [ "$device" = "t" ]
    then
        DEVINFO="$(print_dev "${disk_path}" 2>/dev/null)"
        if [ -z "$DEVINFO" ]
        then
            DEVINFO='[<unknown>]'
        fi
        DEVF=`printf " %3d   %3d " ${DEVINFO}`
        DEVNAME=`cat /proc/partitions|grep "${DEVF}"|awk '{print "/dev/"$4}'`
        DEVINFO=`printf " on device ${DEVNAME}[%d,%d]" ${DEVINFO}`
    else
        DEVINFO=
    fi

    echo "Disk \"${DISKNAME}\" is a valid ASM disk${DEVINFO}"

    if [ "$paths" = "t" ]
    then
        get_paths "$LABEL"
    fi

    return 0
}

#
# Check a device
#
check_device()
{
    if [ "$#" -lt "1" -o -z "$1" ]
    then
        die "check_device(): Requires an argument"
    fi

    DEV="$1"

    INFO="$(oracleasm-read-label "${DEV}" 2>&3)"
    if [ $? != 0 ]
    then
        echo "Unable to access device \"${DEV}\"" >&2
        return 1
    fi

    if [ -z "$INFO" ]
    then
        echo "Device \"$DEV\" is not marked as an ASM disk" >&2
        return 1
    fi

    LABEL="$(echo "$INFO" | cut -f1 -d:)"
    if [ -z "$LABEL" ]
    then
        echo "Device \"$DEV\" defines a device with no label" >&2
        return 1
    fi

    echo "Device \"$DEV\" is marked an ASM disk with the label \"$LABEL\""

    return 0
}

if [ -z "$1" ]
then
    usage
fi

#
# We care about RC instead of using die() because we want to allow
# multiple disk queries (some failing, some succeeding), but if someone
# passes a single disk, they are relying on the error code.
#
RC=0
for d in "$@"
do
    case "$d" in
    */*)
        check_device "$d"
        RC=$?
        ;;
    *)
        check_disk "$d"
        RC=$?
        ;;
    esac
done

exit $RC
