#!/bin/bash

set -e
#set -x

LOCKDIR=/var/run/lock
LOCKFILE=${LOCKDIR}/$(basename ${0})
if [ "${1}" = "--nolock" ] ; then
        shift
else
        logger -t "udev" "===> Claming lock for $0 in ${LOCKFILE}"
        if ! flock -w 120 -x ${LOCKFILE} $0 --nolock $@ ; then
                exit 1
        fi
        exit 0
fi

logger -t "udev" "===> DEVPATH=${DEVPATH} ID_BUS=${ID_BUS}"

# Script param (sent as env var):
# ID_BUS (example: scsi, ata)
# DEVPATH (example: /devices/pci0000:80/0000:80:08.2/0000:81:00.0/ata8/host7/target7:0:0/7:0:0:0/block/sdc)
#
# In fact, we see the variables as per:
# udevadm test -a -p  $(udevadm info -q path -n /dev/sdc)

CHASSIS_MANUFACTURER=$(dmidecode -s system-manufacturer)
CHASSIS_MODEL=$(dmidecode -s system-product-name)
CACHE_FILE=/run/oci-hdd-cache

if [ -x /usr/bin/storcli64 ] ; then
	STORCLI=/usr/bin/storcli64
elif [ -x /usr/bin/storcli_x64 ] ; then
	STORCLI=/usr/bin/storcli_x64
elif [ -x /usr/bin/storcli ] ; then
	STORCLI=/usr/bin/storcli
fi

use_cache_file () {
	usecache=false
	# read a cache file, if exist and recent
	if [ -f $CACHE_FILE ]; then
		lastentry=$(stat -c %Y $CACHE_FILE)
		lastvalid=$(date -d "now -3 min" +%s)
		if [ $lastentry -gt $lastvalid ]; then
			usecache=true
		else
			rm $CACHE_FILE
		fi
	elif [ -e $CACHE_FILE ]; then
		rm $CACHE_FILE
	fi

	# cache is invalid
	if ! $usecache; then
		logger -t "udev" "[Rebuilding cache file]"
		# We should rebuild the cache: exit 1
		return 1
	else
		logger -t "udev" "[Using cache file]"
		# We can re-use the cache: exit 0
		return 0
	fi
}

# After calling this function, $CACHE_FILE will contain something like this:
# [
#  {
#    "SN": "     WD-WX21DA5FN7U8",
#    "Port": "2 ",
#    "Controller": 0
#  },
#  {
#    "SN": "     WD-WX81DA4HNKXL",
#    "Port": "3 ",
#    "Controller": 0
#  ...
get_transformed_storcli_output () {
	if use_cache_file ; then
		return 0
	else
		# Greetings to Raphael Gomes for this JQ wonder... :)
		${STORCLI} /call/eall/sall show all J | jq '.Controllers
    | map({
        Controller: .["Command Status"]["Controller"],
        "Drives": (
            .["Response Data"]
                | to_entries
                | map(
                    select(.key | endswith("Detailed Information"))
                        | .value
                        | {
                            "SN": (to_entries | map(select(.key | endswith("Device attributes")) | .value)[0]["SN"] | gsub("\\s+"; "";"g")),
                            "Port": (to_entries | map(select(.key | endswith("Policies/Settings")) | .value)[0]["Connected Port Number"] | gsub("\\s+$"; "")),
                        }
                )
        )
    })
    | map(
        .Controller as $controller
        | .Drives
        | map(. * {Controller: $controller})
    )
    | flatten' >${CACHE_FILE}
	fi
}

case "${CHASSIS_MANUFACTURER}" in
"LinuxKVM"|"OpenStack Foundation")
	case "${CHASSIS_MODEL}" in
	"qemu-oci"|"OpenStack Nova")
		if [ -n "$ID_BUS" ] && [ "$ID_BUS" = "scsi" ]; then
			card=$(echo $DEVPATH | cut -d/ -f5)
			target=$(echo $DEVPATH | cut -d/ -f8)
			if [ "$card" = "virtio0" ] || [ "$card" = "virtio1" ] ; then
				case "${target}" in
				"2:0:0:0"|"1:0:0:0"|"0:0:0:0") disk="sda" ;;
				"2:0:1:0"|"2:0:0:1"|"1:0:1:0"|"0:0:1:0") disk="sdb" ;;
				"2:0:2:0"|"2:0:0:2"|"1:0:2:0"|"0:0:2:0") disk="sdc" ;;
				"2:0:3:0"|"2:0:0:3"|"1:0:3:0"|"0:0:3:0") disk="sdd" ;;
				"2:0:4:0"|"2:0:0:4"|"1:0:4:0"|"0:0:4:0") disk="sde" ;;
				"2:0:5:0"|"2:0:0:5"|"1:0:5:0"|"0:0:5:0") disk="sdf" ;;
				"2:0:6:0"|"2:0:0:6"|"1:0:6:0"|"0:0:6:0") disk="sdg" ;;
				"2:0:7:0"|"2:0:0:7"|"1:0:7:0"|"0:0:7:0") disk="sdh" ;;
				"2:0:8:0"|"2:0:0:8"|"1:0:8:0"|"0:0:8:0") disk="sdi" ;;
				"2:0:9:0"|"2:0:0:9"|"1:0:9:0"|"0:0:9:0") disk="sdj" ;;
				*) logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
				esac
				logger -t "udev" "Adding symlink $disk for device $card-$target"
				echo $disk
				exit 0
			else
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			fi
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
	;;
	*)
		logger -t "udev" "Qemu chassis not supported, exit."
		exit 1
	;;
	esac
;;
"Dell Inc.")
	case "${CHASSIS_MODEL}" in
	"PowerEdge R410")
		# Here we have 2 internal SSDs on CDROM link and 4 SATA HDD
		if [ -n "$ID_BUS" ] && [ "$ID_BUS" = "ata" ]; then
			card=$(echo $DEVPATH | cut -d/ -f5)
			target=$(echo $DEVPATH | cut -d/ -f8)
			if   [ "$card" = "ata1" ] && [ "$target" = "0:0:0:0" ]; then disk="sda"
			elif [ "$card" = "ata1" ] && [ "$target" = "0:1:0:0" ]; then disk="sdb"
			elif [ "$card" = "ata2" ] && [ "$target" = "1:0:0:0" ]; then disk="sdc"
			elif [ "$card" = "ata3" ] && [ "$target" = "2:0:0:0" ]; then disk="sdd"
			elif [ "$card" = "ata4" ] && [ "$target" = "3:0:0:0" ]; then disk="sde"
			elif [ "$card" = "ata5" ] && [ "$target" = "4:0:0:0" ]; then disk="sdf"
			else logger -t "udev" "Device $DEVPATH detected but not supported."; exit 1
			fi
		else    
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
		logger -t "udev" "Adding symlink $disk for device $card-$target"
		echo "$disk"
		exit 0
	;;
	# This should work on an LSI raid thingy, so on all Dell provided
	# we have the same ID_BUS / DEVPATH thing.
	"PowerEdge R430"|"PowerEdge R610"|"PowerEdge R620"|"PowerEdge R630"|"PowerEdge R640"|"DSS 2500"|"DSS2500"|"PowerEdge R720xd"|"PowerEdge R6525")
		if [ -n "$ID_BUS" ] && [ "$ID_BUS" = "scsi" ]; then
			target=$(echo $DEVPATH | cut -d/ -f8)
			case "${target}" in
			"0:2:0:0"|"0:0:0:0") disk="sda" ;;
			"0:2:1:0"|"0:0:1:0") disk="sdb" ;;
			"0:2:2:0"|"0:0:2:0") disk="sdc" ;;
			"0:2:3:0"|"0:0:3:0") disk="sdd" ;;
			"0:2:4:0"|"0:0:4:0") disk="sde" ;;
			"0:2:5:0"|"0:0:5:0") disk="sdf" ;;
			"0:2:6:0"|"0:0:6:0") disk="sdg" ;;
			"0:2:7:0"|"0:0:7:0") disk="sdh" ;;
			"0:2:8:0"|"0:0:8:0") disk="sdi" ;;
			"0:2:9:0"|"0:0:9:0") disk="sdj" ;;
			"0:2:10:0"|"0:0:10:0") disk="sdk" ;;
			"0:2:11:0"|"0:0:11:0") disk="sdl" ;;
			"0:2:12:0"|"0:0:12:0") disk="sdm" ;;
			*) logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
			esac
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
		logger -t "udev" "Adding symlink $disk for device $card-$target"
		echo "$disk"
		exit 0
	;;
	# Example DEVPATH for this type of server:
	# sda:
	# DEVPATH=/devices/pci0000:00/0000:00:1f.2/ata10/host10/target9:0:0/9:0:0:0/block/sda
	# DEVPATH=/devices/pci0000:00/0000:00:1f.2/ata10/host10/target10:0:0/10:0:0:0/block/sda
	# sdb to sde:
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:0/0:0:0:0/block/sda
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:1/0:0:1:0/block/sdb
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:2/0:0:2:0/block/sdc
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:3/0:0:3:0/block/sdd
	# or:
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:0/0:2:0:0/block/sda
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:1/0:2:1:0/block/sdb
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:2/0:2:2:0/block/sdc
	# DEVPATH=/devices/pci0000:00/0000:00:03.0/0000:02:00.0/host0/target0:0:3/0:2:3:0/block/sdd
	# Example with R440 USB:
	# DEVPATH=/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/host15/target15:0:0/15:0:0:0/block/sde
	"PowerEdge R420"|"PowerEdge R440"|"DSS1510"|"DSS 1510")
		card=$(echo $DEVPATH | cut -d/ -f5)
		host=$(echo $DEVPATH | cut -d/ -f6)
		target=$(echo $DEVPATH | cut -d/ -f8)
		case "${host}" in
		"usb2"|"1-1"|"2-1"|"2-8")
			case "${target}" in
			"host11"|"host15"|"1-1.4:1.0"|"2-1.2:1.0")	PHYDISK=sda	;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
		;;
		"host3"|"host9"|"host10")
			case "${target}" in
			"3:0:0:0"|"9:0:0:0"|"10:0:0:0")
				PHYDISK=sda
			;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
		;;
		"host0")
#			echo "In host0, target is ${target}"
			case "${target}" in
			"0:0:0:0"|"0:2:0:0")	PHYDISK=sda	;;
			"0:0:1:0"|"0:2:1:0")	PHYDISK=sdb	;;
			"0:0:2:0"|"0:2:2:0")	PHYDISK=sdc	;;
			"0:0:3:0"|"0:2:3:0")	PHYDISK=sdd	;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
		;;
		*)
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		;;
		esac
		echo "$PHYDISK"
	;;
	"PowerEdge R740xd")
		SHORTNAME=$(basename "${DEVNAME}")
		# shellcheck disable=SC2012
		PHYSDRIVE=$(ls "/sys/block/${SHORTNAME}/device/scsi_generic/" |awk -F 'sg' '{print $2}')
	
		logger -t "udev" "PHYSDRIVE: $PHYSDRIVE"
		case "${PHYSDRIVE}" in
			# The format is:
			# ${BAY}
			# Cause we strip controller and enclusure just before
			"0") PHYDISK="sda" ;;
			"1") PHYDISK="sdb" ;;
			"2") PHYDISK="sdc" ;;
			"3") PHYDISK="sdd" ;;
			"4") PHYDISK="sde" ;;
			"5") PHYDISK="sdf" ;;
			"6") PHYDISK="sdg" ;;
			"7") PHYDISK="sdh" ;;
			"8") PHYDISK="sdi" ;;
			"9") PHYDISK="sdj" ;;
			"10") PHYDISK="sdk" ;;
			"11") PHYDISK="sdl" ;;
			"12") PHYDISK="sdm" ;;
			"13") PHYDISK="sdn" ;;
		esac

		if ! [ -n "$PHYDISK" ]; then
			logger -t "udev" "Device $DEVNAME detected but not found."
			exit 1
		fi

		logger -t "udev" "Adding symlink $PHYDISK for device $DEVNAME"
		echo "$PHYDISK"
		exit 0
	;;
	*)
		logger -t "udev" "Dell chassis not supported, exit."
		exit 1
	;;
	esac
;;
"HPE")
	case "${CHASSIS_MODEL}" in
	"CL2800 Gen10")
		ata=$(echo $DEVPATH | cut -d/ -f5)
#		target=$(echo $DEVPATH | awk -F '/' '{ print $8 }')
		case "$ata" in
		"ata1")	PHYDISK=sda	;;
		"ata2")	PHYDISK=sdb	;;
		"ata3")	PHYDISK=sdc	;;
		"ata4")	PHYDISK=sdd	;;
		"ata5")	PHYDISK=sde	;;
		"ata6")	PHYDISK=sdf	;;
		"ata7")	PHYDISK=sdg	;;
		"ata8")	PHYDISK=sdh	;;
		"ata9")	PHYDISK=sdi	;;
		"ata10")	PHYDISK=sdj	;;
		"ata11")	PHYDISK=sdk	;;
		"ata12")	PHYDISK=sdl	;;
		"ata13")	PHYDISK=sdm	;;
		"ata14")	PHYDISK=sdn	;;
		esac
		if [ -n "$PHYDISK" ] ; then
			echo "$PHYDISK"
			exit 0
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
	;;
	"ProLiant DL365 Gen10 Plus")
		card=$(echo $DEVPATH | cut -d/ -f6)
		target=$(echo $DEVPATH | awk -F '/' '{ print $8 }')
		if [ "${card}" = "host0" ] ; then
			case "${target}" in
			"0:3:111:0"|"0:2:1:0")	PHYDISK=sda	;;
			"0:2:2:0")	PHYDISK=sdb	;;
			"0:2:3:0")	PHYDISK=sdc	;;
			"0:2:4:0")	PHYDISK=sdd	;;
			"0:2:5:0")	PHYDISK=sde	;;
			"0:2:6:0")	PHYDISK=sdf	;;
			"0:2:7:0")	PHYDISK=sdg	;;
			"0:2:8:0")	PHYDISK=sdh	;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
			echo ${PHYDISK}
			exit 0
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
	;;
	"ProLiant DL345 Gen11")
		target=$(echo $DEVPATH | cut -d/ -f8 | cut -c1-4)
		drive=$(echo $DEVPATH | cut -d/ -f10)
#		logger -t "udev" "===> Found drive $drive"
		usecache=false
		if [ -z "$STORCLI" ]; then 
			logger -t "udev" "Device $DEVPATH detected but cannot find storcli"
			exit 1
		fi
		if echo $drive | grep -q '^sd' ; then
			case "${target}" in
			"0:3:")
				# RAID0
				part=$(echo $DEVPATH | cut -d/ -f11)
				if [ -n "${part}" ] ; then
					logger -t "udev" "Device $DEVPATH detected, but ignored as it looks like a partition."; exit 1
				fi
				disk=$(echo $DEVPATH | cut -d/ -f10)
				usecache=false
				# read a cache file, if exist and recent
				if [ -f ${CACHE_FILE}_VD ]; then
					lastentry=$(stat -c %Y ${CACHE_FILE}2)
					lastvalid=$(date -d "now -3 min" +%s)
					if [ $lastentry -gt $lastvalid ]; then
						usecache=true
					else
						rm ${CACHE_FILE}_VD
					fi
				elif [ -e ${CACHE_FILE}_VD ]; then
					rm ${CACHE_FILE}_VD
				fi
				# cache is invalid
				if ! $usecache; then
					${STORCLI} /call/vall show all J > ${CACHE_FILE}_VD
					logger -t "udev" "[VD Cache built]"
				else
					logger -t "udev" "[VD Using cache]"
				fi
				VD_BIGNUM=$(cat ${CACHE_FILE}_VD | jq -r '.["Controllers"][]["Response Data"] | to_entries | map(select(.value["OS Drive Name"]? == "/dev/'${disk}'") | .key )[]' | sed -e 's/^VD//' -e 's/ Properties//')
				EIDSlot=$(cat ${CACHE_FILE}_VD | jq -r '.["Controllers"][]["Response Data"]["PDs for VD '${VD_BIGNUM}'"][]["EID:Slt"]')
                                case "${EIDSlot}" in
                                        "248:1")        PHYDISK="sde"   ;;
                                        "248:2")        PHYDISK="sdf"   ;;  
                                        "248:3")        PHYDISK="sdg"   ;;  
                                        "248:4")        PHYDISK="sdh"   ;;  
                                        "249:1")        PHYDISK="sda"   ;;  
                                        "249:2")        PHYDISK="sdb"   ;;  
                                        "249:3")        PHYDISK="sdc"   ;;  
                                        "249:4")        PHYDISK="sdd"   ;;  
                                        "250:1")        PHYDISK="sdi"   ;;  
                                        "250:2")        PHYDISK="sdj"   ;;  
                                        "250:3")        PHYDISK="sdk"   ;;  
                                        "250:4")        PHYDISK="sdl"   ;;  
                                        "251:1")        PHYDISK="sdm"   ;;  
                                        "251:2")        PHYDISK="sdn"   ;;  
                                        "251:3")        PHYDISK="sdo"   ;;  
                                        "251:4")        PHYDISK="sdp"   ;;  
                                *)      logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
                                esac
                                logger -t "udev" "===> Location for $DEVPATH is $EIDSlot, so should be $PHYDISK."
                                echo $PHYDISK 
                                exit 0
			;;
			"0:2:")
				# JBOD
				MY_SERIAL=$(lsblk -o SERIAL /dev/$drive | tail -n1)
				#logger -t "udev" "===> Serial is $MY_SERIAL"
                                usecache=false
                                # read a cache file, if exist and recent
                                if [ -f $CACHE_FILE ]; then
                                        lastentry=$(stat -c %Y $CACHE_FILE)
                                        lastvalid=$(date -d "now -3 min" +%s)
                                        if [ $lastentry -gt $lastvalid ]; then
                                                usecache=true
                                        else
                                                rm $CACHE_FILE
                                        fi
                                elif [ -e $CACHE_FILE ]; then
                                        rm $CACHE_FILE
                                fi
                                # cache is invalid
                                if ! $usecache; then
                                        # Rebuild cache with StorCli
                                for EIDSlot in $(storcli_x64 /c0 show  J | jq '..|objects|."Drive LIST"//empty|.[]["EID:Slt"]' | tr -d '"');
                                        do
                                                EID=$(echo $EIDSlot| cut -d ':' -f 1)
                                                BAY=$(echo $EIDSlot| cut -d ':' -f 2)
                                                PA=/c0/e${EID}/s${BAY}
                                                # Search Drive Attributes
                                                PROPERTIES=$(storcli_x64 ${PA} show all J|jq '..|objects|."'"Drive ${PA} Device attributes"'"//empty')
                                                SERIAL=$(echo ${PROPERTIES} | jq '.SN')
                                                BOX=$(echo ${PROPERTIES} | jq '.Box')
                                                # Save Serial Number, Box and Bay of drive in Cache File
                                                echo ${SERIAL}:${BOX}:${BAY} >> $CACHE_FILE
                                        done
                                        logger -t "udev" "[Cache built]"
                                else
                                        logger -t "udev" "[Using cache]"
                                fi

                                MY_BOX=$(cat $CACHE_FILE | grep $MY_SERIAL | cut -d ':' -f 2)
                                MY_BAY=$(cat $CACHE_FILE | grep $MY_SERIAL | cut -d ':' -f 3)
                                case "${MY_BOX}" in
                                1)
                                        case "${MY_BAY}" in
                                        1)      PHYDISK=sda     ;;
                                        2)      PHYDISK=sdb     ;;
                                        3)      PHYDISK=sdc     ;;
                                        4)      PHYDISK=sdd     ;;
                                        *)
                                                logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
                                        ;;
                                        esac
                                ;;
                                2)
                                        case "${MY_BAY}" in
                                        1)      PHYDISK=sde     ;;
                                        2)      PHYDISK=sdf     ;;
                                        3)      PHYDISK=sdg     ;;
                                        4)      PHYDISK=sdh     ;;
                                        *)
                                                logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
                                        ;;
                                        esac
                                ;;
                                3)
                                        case "${MY_BAY}" in
                                        1)      PHYDISK=sdi     ;;
                                        2)      PHYDISK=sdj     ;;
                                        3)      PHYDISK=sdk     ;;
                                        4)      PHYDISK=sdl     ;;
                                        *)
                                                logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
                                        ;;
                                        esac
                                ;;
                                8)
                                        case "${MY_BAY}" in
                                        1)      PHYDISK=sdm     ;;
                                        2)      PHYDISK=sdn     ;;
                                        3)      PHYDISK=sdo     ;;
                                        4)      PHYDISK=sdp     ;;
                                        *)
                                                logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
                                        ;;
                                        esac
                                ;;
                                esac
			;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
			logger -t "udev" "===> Location for $MY_SERIAL is $MY_BOX:$MY_BAY, so should be $PHYDISK."
			echo ${PHYDISK}
			exit 0
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
	;;
	"ProLiant DL385 Gen10 Plus"|"ProLiant DL385 Gen10 Plus v2")
		card=$(echo $DEVPATH | cut -d/ -f6)
		target=$(echo $DEVPATH | awk -F '/' '{ print $9 }')
		# We expect here 2 SATA SSDs and 12 SAS HDD
		if [ "${card}" = "ata7" ] && [ "${target}" = "6:0:0:0" ]; then
			disk="sda"
		elif [ "${card}" = "ata8" ] && [ "${target}" = "7:0:0:0" ]; then
			disk="sdb"
		elif   [ "${card}" = "host8" ] ; then
			usecache=false
			# read a cache file, if exist and recent
			if [ -f $CACHE_FILE ]; then
				lastentry=$(stat -c %Y $CACHE_FILE)
				lastvalid=$(date -d "now -3 min" +%s)
				if [ $lastentry -gt $lastvalid ]; then
					usecache=true
				else
					rm $CACHE_FILE
				fi
			elif [ -e $CACHE_FILE ]; then
				rm $CACHE_FILE
			fi
			# cache is recent and a file
			if $usecache; then
				# Just read from cache file...
				disk=$(grep $DEVNAME $CACHE_FILE | awk '{ print $2 }')
				if ! [ -n "$disk" ]; then
					logger -t "udev" "[Cache mode] Device $DEVPATH detected but not found."
					exit 1
				fi
			else
				disk=""

				# Parse the output of "ssacli controller slot=0 physicaldrive all show detail"
				# and build a cache file...
				TMPFILE=$(mktemp -t parse-hpe-drives.XXXXXX)
				# The grep here just helps because we later have less lines to parse.
				SLOT_NUM=$(ssacli controller all show | head -n 2 | tail -n 1 | sed -r 's/.*(Slot [0-9]+).*/\1/' | sed 's/Slot //')
				ssacli controller slot=${SLOT_NUM} physicaldrive all show detail | grep -E 'physicaldrive|Disk Name: /dev/' >$TMPFILE
				while IFS='' read -r LINE || [ -n "${LINE}" ]; do
					if echo ${LINE} | grep -q physicaldrive ; then
						PHYSDRIVE=$(echo ${LINE} | sed 's/^.*physicaldrive //')
						case "${PHYSDRIVE}" in
							# The format is:
							# ${SAS_PORT}:${BOX}:${BAY}
							# Since we don't care about ports, but where the drive is physically located
							# we use ${BOX}:${BAY}, so the physical location of the drives is deterministic
							# and we don't care the order of the ports.
							"1I:1:1"|"2I:1:1"|"3I:1:1") PHYDISK="sdc" ;;
							"1I:1:2"|"2I:1:2"|"3I:1:2") PHYDISK="sdd" ;;
							"1I:1:3"|"2I:1:3"|"3I:1:3") PHYDISK="sde" ;;
							"1I:1:4"|"2I:1:4"|"3I:1:4") PHYDISK="sdf" ;;
							"1I:2:1"|"2I:2:1"|"3I:2:1") PHYDISK="sdg" ;;
							"1I:2:2"|"2I:2:2"|"3I:2:2") PHYDISK="sdh" ;;
							"1I:2:3"|"2I:2:3"|"3I:2:3") PHYDISK="sdi" ;;
							"1I:2:4"|"2I:2:4"|"3I:2:4") PHYDISK="sdj" ;;
							"1I:3:1"|"2I:3:1"|"3I:3:1") PHYDISK="sdk" ;;
							"1I:3:2"|"2I:3:2"|"3I:3:2") PHYDISK="sdl" ;;
							"1I:3:3"|"2I:3:3"|"3I:3:3") PHYDISK="sdm" ;;
							"1I:3:4"|"2I:3:4"|"3I:3:4") PHYDISK="sdn" ;;
						esac
					elif echo ${LINE} | grep -q 'Disk Name: /dev/' ; then
						MY_DEV_NAME=$(echo ${LINE} | sed 's#^.*Disk Name: ##')
						if [ -n "${PHYDISK}" ] ; then
							echo "$MY_DEV_NAME $PHYDISK" >> $CACHE_FILE
							unset PHYDISK
						fi
						unset MY_DEV_NAME
					fi
				done <$TMPFILE
				rm -f ${TMPFILE}

				# Once it's built, just read from the cache file.
				disk=$(grep $DEVNAME $CACHE_FILE | awk '{ print $2 }')
				if ! [ -n "$disk" ]; then
					logger -t "udev" "[Normal mode] Device $DEVPATH detected but not found."
					exit 1
				fi
			fi
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
		logger -t "udev" "Adding symlink $disk for device $DEVPATH"
		echo "$disk"
		exit 0
	;;
	"ProLiant DL365 Gen10 Plus")
		card=$(echo $DEVPATH | cut -d/ -f6)
		target=$(echo $DEVPATH | awk -F '/' '{ print $8 }')
		if [ "${card}" = "host0" ] ; then
			case "${target}" in
				"0:2:1:0")	PHYDISK="sda" ;;
				"0:2:2:0")	PHYDISK="sdb" ;;
				"0:2:3:0")	PHYDISK="sdc" ;;
				"0:2:4:0")	PHYDISK="sdd" ;;
				"0:2:5:0")	PHYDISK="sde" ;;
				"0:2:6:0")	PHYDISK="sdf" ;;
				"0:2:7:0")	PHYDISK="sdg" ;;
				"0:2:8:0")	PHYDISK="sdh" ;;
				"0:2:9:0")	PHYDISK="sdi" ;;
				"0:2:10:0")	PHYDISK="sdj" ;;
				*)      logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			esac
			logger -t "udev" "Adding symlink $PHYDISK for device $DEVPATH"
			echo $PHYDISK
			exit 0
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
	;;
	"ProLiant DL365 Gen11")
		host=$(echo $DEVPATH | cut -d/ -f6)
		port=$(echo $DEVPATH | cut -d/ -f7)
		# Swift proxy with 4 account+container SSDs.
		if 	[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:102 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:103 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:104 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:105 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:106 ] ; then
			case "$port" in
			"target0:3:106")	PHYDISK="sda" ;;
			"target0:3:105")	PHYDISK="sdb" ;;
			"target0:3:104")	PHYDISK="sdc" ;;
			"target0:3:103")	PHYDISK="sdd" ;;
			"target0:3:102")	PHYDISK="sde" ;;
			*)			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			esac
		# Swift proxy with 4 account+container SSDs.
		elif	[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:107 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:108 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:109 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:110 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:111 ] ; then
			case "$port" in
			"target0:3:107")	PHYDISK="sda" ;;
			"target0:3:108")	PHYDISK="sdb" ;;
			"target0:3:109")	PHYDISK="sdc" ;;
			"target0:3:110")	PHYDISK="sdd" ;;
			"target0:3:111")	PHYDISK="sde" ;;
			*)			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			esac
		# Servers with only 2 devices in RAID1.
		elif	[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:110 ] && \
			[ -d /sys/devices/pci0000:*/0000:??:??.?/0000:??:00.0/host0/target0:3:111 ] ; then
			case "$port" in
			"target0:3:110")        PHYDISK="sda" ;;
			"target0:3:111")        PHYDISK="sdb" ;;
			esac
		else
			drive_letter=$(echo $DEVPATH | cut -d/ -f10)
			drive_serial=$(smartctl -a /dev/${drive_letter} | grep -i "Serial Number:" | sed -e 's/Serial Number://' -e 's/Serial number://' -e 's/ //g')
			get_transformed_storcli_output
			PORT=$(cat /run/oci-hdd-cache | jq -r --arg sn "${drive_serial}" '. | map(select(.SN == $sn)) | first | .Port' | sed -e 's/ //g')
			case "${PORT}" in
			"2(path0)")	PHYDISK="sdb" ;;
			"3(path0)")	PHYDISK="sdc" ;;
			"4(path0)")	PHYDISK="sdd" ;;
			"5(path0)")	PHYDISK="sde" ;;
			*)		PHYDISK="sda" ;;
			esac
		fi
		if [ -n "${PHYDISK}" ] ; then
			echo $PHYDISK
			logger -t "udev" "Adding symlink $PHYDISK for device $DEVPATH"
		else
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		fi
	;;
	*)
		logger -t "udev" "HPE chassis not supported, exit."
		exit 1
	;;
	esac
;;
"Lenovo")
	case "${CHASSIS_MODEL}" in
	"ThinkSystem SR645")
		host=$(echo $DEVPATH | cut -d/ -f6)
		target=$(echo $DEVPATH | cut -d/ -f8)
		case "${host}" in
		"host0")
			case "${target}" in
			"0:3:109:0"|"0:3:110:0"|"0:3:111:0")
                		if [ -z "$STORCLI" ]; then
		                        logger -t "udev" "Device $DEVPATH detected but cannot find storcli"
                		        exit 1
		                fi
				part=$(echo $DEVPATH | cut -d/ -f11)
				if [ -n "${part}" ] ; then
					logger -t "udev" "Device $DEVPATH detected, but ignored as it looks like a partition."; exit 1
				fi
				disk=$(echo $DEVPATH | cut -d/ -f10)
				VD_BIGNUM=$(${STORCLI} /call/vall show all J | jq -r '.["Controllers"][]["Response Data"] | to_entries | map(select(.value["OS Drive Name"]? == "/dev/'${disk}'") | .key )[]' | sed -e 's/^VD//' -e 's/ Properties//')
				VD_SMALLNUM=$(${STORCLI} /call/vall show all J | jq -r '.["Controllers"][]["Response Data"]["/c0/v'${VD_BIGNUM}'"][]["DG/VD"]' | cut -d/ -f1)
				case "${VD_SMALLNUM}" in
				"0")	PHYDISK="sda"	;;
				"1")	PHYDISK="sdb"	;;
				"2")	PHYDISK="sdc"	;;
				"3")	PHYDISK="sdd"	;;
				"4")	PHYDISK="sde"	;;
				"5")	PHYDISK="sdf"	;;
				"6")	PHYDISK="sdg"	;;
				"7")	PHYDISK="sdh"	;;
				"8")	PHYDISK="sdi"	;;
				"9")	PHYDISK="sdj"	;;
				*)	logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
				esac
				logger -t "udev" "Adding symlink $PHYDISK for device $DEVPATH"
				echo $PHYDISK
				exit 0
			;;
			"0:2:0:0")      echo "sda"      ;;
			"0:2:1:0")      echo "sdb"      ;;
			"0:2:2:0")      echo "sdc"      ;;
			"0:2:3:0")      echo "sdd"      ;;
			"0:2:4:0")      echo "sde"      ;;
			"0:2:5:0")      echo "sdf"      ;;
			"0:2:6:0")      echo "sdg"      ;;
			"0:2:7:0")      echo "sdh"      ;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
		;;
		*)
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		;;
		esac
	;;
	"ThinkSystem SR665")
		host=$(echo $DEVPATH | cut -d/ -f6)
		target=$(echo $DEVPATH | cut -d/ -f8)
		case "${host}" in
		"ata1")
			echo "sda";
		;;
		"ata2")
			echo "sdb";
		;;
		"host0")
			case "${target}" in
			# Note that the first value is in case of JBOD
			"0:0:0:0"|"0:2:0:0"|"0:3:96:0")	echo "sdc"	;;
			"0:0:1:0"|"0:2:1:0"|"0:3:97:0")	echo "sdd"	;;
			"0:0:2:0"|"0:2:2:0"|"0:3:98:0")	echo "sde"	;;
			"0:0:3:0"|"0:2:3:0"|"0:3:99:0")	echo "sdf"	;;
			"0:0:4:0"|"0:2:4:0"|"0:3:100:0")	echo "sdg"	;;
			"0:0:5:0"|"0:2:5:0"|"0:3:101:0")	echo "sdh"	;;
			"0:0:6:0"|"0:2:6:0"|"0:3:102:0")	echo "sdi"	;;
			"0:0:7:0"|"0:2:7:0"|"0:3:103:0")	echo "sdj"	;;
			"0:0:8:0"|"0:2:8:0"|"0:3:104:0")	echo "sdk"	;;
			"0:0:9:0"|"0:2:9:0"|"0:3:105:0")	echo "sdl"	;;
			"0:0:10:0"|"0:2:10:0"|"0:3:106:0")	echo "sdm"	;;
			"0:0:11:0"|"0:2:11:0"|"0:3:107:0")	echo "sdn"	;;
			"0:0:12:0"|"0:2:12:0"|"0:2:24:0"|"0:3:108:0")	echo "sdo"	;;
			"0:0:13:0"|"0:2:13:0"|"0:2:25:0"|"0:3:109:0")	echo "sdp"	;;
			"0:0:14:0"|"0:2:14:0"|"0:2:26:0"|"0:3:110:0")	echo "sdq"	;;
			"0:0:15:0"|"0:2:15:0"|"0:2:27:0"|"0:3:111:0")	echo "sdr"	;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
		;;
		*)
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		;;
		esac
	;;
	*)
		logger -t "udev" "Lenovo chassis not supported (yet), exit."
		exit 1
	;;
	esac
;;
"GIGABYTE")
	case "${CHASSIS_MODEL}" in
	"R182-Z93-00")
		host=$(echo $DEVPATH | cut -d/ -f6)
		target=$(echo $DEVPATH | cut -d/ -f8)
		case "${host}" in
		"host0")
			case "${target}" in
			"0:2:0:0")      echo "sda"      ;;
			"0:2:1:0")      echo "sdb"      ;;
			"0:2:2:0")      echo "sdc"      ;;
			"0:2:3:0")      echo "sdd"      ;;
			"0:2:4:0")      echo "sde"      ;;
			"0:2:5:0")      echo "sdf"      ;;
			"0:2:6:0")      echo "sdg"      ;;
			"0:2:7:0")      echo "sdh"      ;;
			*)
				logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
			;;
			esac
		;;
		*)
			logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1
		;;
		esac
	;;
	"MZ01-CE1-00")
		host=$(echo $DEVPATH | cut -d/ -f6)
		port=$(echo $DEVPATH | cut -d/ -f7)
		case "${host}" in
		"ata1"|"ata13")	echo "sda"      ;;
		"ata2"|"ata14"|"ata16") echo "sdb"	;;
		*)
			drive_letter=$(echo $DEVPATH | cut -d/ -f12)
			if [ -z "${drive_letter}" ] ; then
				drive_letter=$(echo $DEVPATH | cut -d/ -f10)
			fi
			drive_serial=$(smartctl -a /dev/${drive_letter} | grep -i "Serial Number:" | sed -e 's/Serial Number://' -e 's/Serial number://' -e 's/ //g')
			get_transformed_storcli_output
			CONTROLLER=$(cat /run/oci-hdd-cache | jq -r --arg sn "${drive_serial}" '. | map(select(.SN == $sn)) | first | .Controller')
			PORT=$(cat /run/oci-hdd-cache | jq -r --arg sn "${drive_serial}" '. | map(select(.SN == $sn)) | first | .Port' | sed -e 's/ //g')
			case "${CONTROLLER}" in
			0)
				case "${PORT}" in
				"0"|"0(path0)")	echo "sdc"; exit 0 ;;
				"1"|"1(path0)")	echo "sdd"; exit 0 ;;
				"2"|"2(path0)")	echo "sde"; exit 0 ;;
				"3"|"3(path0)")	echo "sdf"; exit 0 ;;
				"4"|"4(path0)")	echo "sdg"; exit 0 ;;
				"5"|"5(path0)")	echo "sdh"; exit 0 ;;
				"6"|"6(path0)")	echo "sdi"; exit 0 ;;
				"7"|"7(path0)")	echo "sdj"; exit 0 ;;
				"8"|"8(path0)")	logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
				esac
			;;
			1)
				case "${PORT}" in
				"0"|"0(path0)")	echo "sdk"; exit 0 ;;
				"1"|"1(path0)")	echo "sdl"; exit 0 ;;
				"2"|"2(path0)")	echo "sdm"; exit 0 ;;
				"3"|"3(path0)")	echo "sdn"; exit 0 ;;
				"4"|"4(path0)")	echo "sdo"; exit 0 ;;
				"5"|"5(path0)")	echo "sdp"; exit 0 ;;
				"6"|"6(path0)")	echo "sdq"; exit 0 ;;
				"7"|"7(path0)")	echo "sdr"; exit 0 ;;
				"8"|"8(path0)")	logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
				esac
			;;
			2)
				case "${PORT}" in
				"0"|"0(path0)")	echo "sds"; exit 0 ;;
				"1"|"1(path0)")	echo "sdt"; exit 0 ;;
				"2"|"2(path0)")	echo "sdu"; exit 0 ;;
				"3"|"3(path0)")	echo "sdv"; exit 0 ;;
				"4"|"4(path0)")	echo "sdw"; exit 0 ;;
				"5"|"5(path0)")	echo "sdx"; exit 0 ;;
				"6"|"6(path0)")	echo "sdy"; exit 0 ;;
				"7"|"7(path0)")	echo "sdz"; exit 0 ;;
				"8"|"8(path0)")	logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
				esac
			;;
			*) logger -t "udev" "Device $DEVPATH detected but not supported"; exit 1 ;;
			esac
		;;
		esac
	;;
	*)
		logger -t "udev" "Lenovo chassis not supported (yet), exit."
		exit 1
	;;
	esac
;;
*)
	logger -t "udev" "Chassis not supported, exit."
	exit 1
;;
esac
