#!/bin/bash
#
# Scan disks to find any ASM disks and perhaps fix their ownership.
#

# Force LC_ALL=C
export LC_ALL=C
 
USAGE="[-l <manager>] [-s] [[-o <order_pattern>] ...] [[-x <exclude_pattern>] ...] [-v] [<device> ...]"

exec 3>/dev/null

help=
verbose=
version=
usage=
SCANARGS=
scanonly=
while case "$#" in 0) break ;; esac
do
    case "$1" in
    -l|--manager)
        case "$#" in 1) usage=t; break ;; esac
        shift
        ORACLE_ASMMANAGER="$1"
        ;;
    -o|--scanorder)
        case "$#" in 1) usage=t; break ;; esac
        shift
        SCANARGS="${SCANARGS} -o $1"
        ;;
    -x|--scanexclude)
        case "$#" in 1) usage=t; break ;; esac
        shift
        SCANARGS="${SCANARGS} -x $1"
        ;;
    -s|--scanonly) 
        scanonly=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



for d in ${ORACLEASM_SCANORDER}
do
    SCANARGS="${SCANARGS} -o $d"
done

for d in ${ORACLEASM_SCANEXCLUDE}
do
    SCANARGS="${SCANARGS} -x $d"
done

to_scan()
{
    if [ $# -gt 0 ]
    then
        for d in "$@"
        do
            echo "$d"
        done
    else
        oracleasm-scan-partitions ${SCANARGS} 2>&3
    fi
}

#
# If we reload the partition table, udev may take time to (re-)create
# the device file.  Thus, we must try a few times on ENOENT.
#
# This is a backoff of four tries:
#
# try1
# sleep 1
# try2
# sleep 3
# try3
# sleep 5
# try4
# fail
#
# We do not retry if --scanonly was specified
#
try_read()
{
    dev="$1"

    delay=1
    rc=0
    info=
    while :
    do
        oracleasm-read-label "$dev"
        rc=$?

        [ "$scanonly" = "t" ] && break

        #
        # oracleasm-read-label returns -errno, but return codes are positive
        # eight-bit values.  So -ENOENT (-2) is 254.
        #
        [ $rc != 254 ] && break

        [ $delay -gt 5 ] && break
        sleep $delay
        delay="$(expr $delay + 2)"
    done

    return $rc
}


if [ -z "$scanonly" ]
then
    echo -n "Reloading disk partitions: "
    to_scan "$@" | oracleasm-reload-partitions 2>&3
    echo "done"
    oracleasm-dropdisks -l "${ORACLE_ASMMANAGER}" -v 2>&3 
fi

echo "Scanning system for ASM disks..."
to_scan "$@" | while read dev
    do
        INFO="$(try_read "$dev" 2>&3)"
        if [ $? != 0 ]
        then
            continue
        fi
        if [ -z "$INFO" ]
        then
            continue
        fi

        LABEL="$(echo "$INFO" | cut -f1 -d:)"
        if [ -z "$LABEL" ]
        then
            continue
        fi

        if oracleasm-querydisk -l "${ORACLE_ASMMANAGER}" "${LABEL}" 1>&3 2>&3 
        then
            continue
        fi

        echo "Instantiating disk \"${LABEL}\""
        oracleasm-instantiate-disk -l "${ORACLE_ASMMANAGER}" "${dev}" \
            "${LABEL}" 2>&3
        if [ $? != 0 ]
        then
            echo "Unable to instantiate disk \"${LABEL}\"" >&2
        fi
    done

oracleasm-listdisks -l "${ORACLE_ASMMANAGER}" 2>&3 | while read LINE
    do
        perm_disk "$(asm_disk_path "${ORACLE_ASMMANAGER}" "${LINE}")" 2>&3
        if [ $? = 1 ]
        then
            die "Unable to fix permissions on ASM disk \"$LINE\""
        fi
    done

exit 0

