#!/usr/bin/bash
#
# Copyright (c) 2006, 2025, Oracle and/or its affiliates.
#
# Determine whether certain disks are ASM disks
#


# Force LC_ALL=C
export LC_ALL=C

USAGE="[-v] [-d|-i|-p] <label>|<device> ..."

exec 3>/dev/null

help=
verbose=
version=
usage=
device=
paths=
info=
while case "$#" in 0) break ;; esac
do
    case "$1" in
    -d|--device)
        device=t
        ;;
    -i|--info)
        OD_LONG="$(oracleasm-discover --help 2>&1 | grep long)"
        if [ -z "${OD_LONG}" ]
        then
            echo "oracleasm-discover too old for 'querydisk --info'. "
            echo "Please upgrade the oracleasmlib package."
            exit 1
        fi
        info=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
check_oracleasm_config

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

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

#
# 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 "${DISKNAME}")"
    if [ ! -e "$disk_path" ]
    then
        echo "Disk \"$DISKNAME\" does not exist or is not instantiated" | asm_log 1
        return 1
    fi

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

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

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

    if [ "$info" = "t" ]
    then
        oracleasm-discover -l "ORCL:${DISKNAME}" | grep -vE "^Using ASM|^\[ASM"
        return 0
    fi

    if [ "$device" = "t" ]
    then
	DEVNODE=$(lsblk -no maj:min "${disk_path}" 2>/dev/null | tr : , | tr -d '[:blank:]')
	if [ -z "$DEVNODE" ]
	then
	    DEVNODE='<unknown>'
	fi
	DEVINFO=$(printf " on device ${disk_path} [${DEVNODE}]")
    else
        DEVINFO=
    fi

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

    if [ "$paths" = "t" ]
    then
	lsblk -flps 2> /dev/null | grep ${LABEL} | awk '{print $1 ": LABEL=\""$3"\" TYPE=\""$2"\""}'
    fi

    return 0
}

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

    if [ "$info" = "t" ]
    then
        echo "-i|--info option requires a valid ASM disk label"
        exit 1
    fi

    DEV="$1"

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

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

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

    echo "Device \"$DEV\" is marked as 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
