#!/usr/bin/bash
#
# Copyright (c) 2022, 2024, Oracle and/or its affiliates.
#
# Remove specified ASM disk from the iofilter map.
#

ORACLE_ASM_IOFILTER_MAP_PATH="/sys/fs/bpf/iofilter_asm"
IOFILTER_ASM="/usr/lib/oracleasm/iofilter_asm"
ORACLE_ASM_CONFIG_FILE="/etc/sysconfig/oracleasm"

#
# Log command output and errors to syslog file
#

asm_log()
{
    while read -r line; do
        echo "$line" | logger
    done
}

iofilter_map_delete_path ()
{
    # Check if iofilter_asm program is available
    if [ ! -f "${IOFILTER_ASM}" ]
    then
	return  0
    fi

    if [ "$#" -lt "3" ]
    then
        echo "iofilter_map_delete_path(): Requires arguments"
	return 0
    fi

    disk_path="$1"
    dev_major="$2"
    dev_minor="$3"

    # Get disk type (disk or partition)
    disk_type=$(lsblk -dn -o type ${disk_path})

    # check if this is DM device path
    dev_dir=$(dirname $disk_path)
    if [ "${dev_dir}" = "/dev/mapper" ]
    then
        dm_path=$disk_path
    fi

    # For the whole disk or for the DM device path just delete
    # the entry in the iofilter map. If it is a physical disk partition
    # then the parent entry is also to be updated in the map.
    if [ "${disk_type}" != "part" -o "${disk_path}" = "${dm_path}" ]
    then
        # regular whole disk or DM device
        ${IOFILTER_ASM} --delete "${disk_path}" --pin \
	    "${ORACLE_ASM_IOFILTER_MAP_PATH}" \
	    --devnum "$dev_major:$dev_minor" --silent | asm_log
    else
	parent_disk=$(lsblk -no PKNAME ${disk_path})
	${IOFILTER_ASM} --delete "${disk_path}" --pin \
	    "${ORACLE_ASM_IOFILTER_MAP_PATH}" --parent "/dev/${parent_disk}" \
	    --devnum "$dev_major:$dev_minor" --silent | asm_log
    fi

    if [ ${PIPESTATUS[0]} != 0 ]
    then
        #DEBUG echo "Failed to delete disk ${disk_path} from iofilter map"
        return 1
    fi

    echo "Removed disk ${disk_path} from iofilter map" | asm_log

    return 0
}

# Load config parameters file
[ -f "${ORACLE_ASM_CONFIG_FILE}" ] && . "${ORACLE_ASM_CONFIG_FILE}"

# Force LC_ALL=C
export LC_ALL=C
 
USAGE="<disk-label> <device-path> <device-major> <device-minor>"

version=

exec 3>/dev/null

while case "$#" in 0) break ;; esac
do
    case "$1" in
    -h|--help)
        help=t
        ;;
    -V|--version)
        version=t
        ;;
    -*)
        usage=t
        ;;
    *)
        break
        ;;
    esac
    shift
done

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

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

if [ ! -e "${ORACLE_ASM_IOFILTER_MAP_PATH}" ]
then
	# No iofilter map exists
	exit 0
fi

if [ $# -lt 4 ]
then
    usage
    exit 1
fi

LABEL="$1"
DISK_NAME="$2"
DEV_MAJOR="$3"
DEV_MINOR="$4"

# Remove ASM disk element (if it exists) from the iofilter map.
iofilter_map_delete_path "${DISK_NAME}" "${DEV_MAJOR}" "${DEV_MINOR}"

exit 0
