#!/usr/bin/bash
#
# Copyright (c) 2006, 2025, Oracle and/or its affiliates.
#
# Return a disk to the operating system
#


# Force LC_ALL=C
export LC_ALL=C

USAGE="[-v] <label>|<device>"

exec 3>/dev/null

help=
verbose=
version=
usage=
force=
while case "$#" in 0) break ;; esac
do
    case "$1" in
    -f|--force)
        force=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 [ $(echo $UID) != 0 ]
then
    echo "This operation requires root privileges. Please run as root"
    exit 1
fi

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

#
# Delete a disk by name
#
delete_disk()
{
    if [ "$#" != "1" -o -z "$1" ]
    then
        die "delete_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
        exit 1
    fi

    #
    # Nested if suckage, but there's a reason.  We want to validate
    # ALL of these checks before we squash the disk header.  If any of
    # the checks fails, we will still remove the name, but not
    # squash the header.  It isn't ours to squash.
    #
    INFO="$(oracleasm-read-label "${disk_path}" 2>&3)"
    if [ -z "$INFO" ]
    then
        echo "Disk \"$DISKNAME\" defines an unmarked device" | asm_log 1
    else
        LABEL="$(echo "$INFO" | cut -f1 -d:)"
        if [ -z "$LABEL" ]
        then
            echo "Disk \"$DISKNAME\" defines a device with no label" | asm_log 1
        else
            if [ "$LABEL" != "$DISKNAME" ]
            then
                echo "Disk \"$DISKNAME\" is labeled for disk \"$LABEL\"" | asm_log 1
	    fi
	fi

	if [ "$force" != "t" ]
	then
	    check_disk_group_member "${disk_path}"
	fi

    fi

    iofilter_map_delete ${DISKNAME}
    if [ $? != 0 ]
    then
        echo "Failed to delete disk \"${LABEL}\" from iofilter map" | \
	    asm_log 1
    fi

    if [ "$LABEL" = "$DISKNAME" ]
    then
	echo -n "Clearing disk header: "
	oracleasm-write-label ${force:+-f} -d "${disk_path}" 2>&1 | asm_log 2
	if [ ${PIPESTATUS[0]} != 0 ]
	    then
		echo "failed"
		echo "Unable to clear disk \"${DISKNAME}\"" | asm_log 1
		exit 1
	fi
	echo "done"
    fi

    # No matter what happened above, we can drop the disk
    echo -n "Dropping disk: "
    if [ "$ORACLEASM_DRIVER_SUPPORTED" = "true" ]
    then
        oracleasm-clean-disk "${DISKNAME}" 2>&1 | \
		asm_log 2
        if [ ${PIPESTATUS[0]} != 0 ]
        then
            echo "failed"
            echo "Unable to delete disk \"${DISKNAME}\"" | asm_log 1
            exit 1
        fi
    fi

    # trigger udevadm to clear stale link in /dev/disk/by-label/
    udevadm trigger 2>/dev/null
    # refresh blkid cache so it has updated info
    blkid >/dev/null

    echo "done"
    return 0
}

#
# Delete by device name
#
delete_device()
{
    if [ "$#" != "1" -o -z "$1" ]
    then
        die "delete_device(): Requires an argument"
    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

    if [ "$force" != "t" ]
    then
	check_disk_group_member "${DEV}"
    fi

    RC=0
    # If instantiated, go through the name
    if oracleasm-querydisk "${LABEL}" 1>&3 2>&3
    then
        delete_disk "${LABEL}"
    else
        echo -n "Clearing disk header: "
        oracleasm-write-label ${force:+-f} -d "${DEV}" 2>&3
        if [ "$RC" != 0 ]
        then
            echo "failed"
            echo "Unable to clear disk \"${DEV}\"" | asm_log 1
        fi
        echo "done"
    fi

    # trigger udevadm to clear stale link in /dev/disk/by-label/
    udevadm trigger 2>/dev/null
    # refresh blkid cache so it has updated info
    blkid >/dev/null

    return 0
}


if [ $# != 1 -o -z "$1" ]
then
    usage
fi
TARGET="$1"
shift

case "$TARGET" in
*/*)
    delete_device "$TARGET"
    ;;
*)
    delete_disk "$TARGET"
    ;;
esac

exit 0
