#!/bin/bash

set -e
#set -x

myscript=$(basename $0)

if [ $(id -u) -ne 0 ]; then
	echo "$myscript needs root: please use sudo."
	exit 1
fi

PRODUCT_NAME=$(dmidecode -s system-product-name)


# Make a CSV file of VD (Megacli Virtual Disk) and the PD (Megacli Physical Drives) they use
# and "guess" the matching device name (by using a counter).
megacli_vd_list2 () {
	VD_LIST2=$(mktemp)
	F_PDINFO=$(mktemp)

	echo "Vd,Pd,Drive,Vdstate,Slot" >${VD_LIST2}

	if [ -x /usr/bin/storcli_x64 ] || [ -x /usr/bin/storcli64 ] ; then
#	if false ; then
		if [ -x /usr/bin/storcli64 ] ; then
			STORCLI=/usr/bin/storcli64
		elif [ -x /usr/bin/storcli_x64 ] ; then
			STORCLI=/usr/bin/storcli_x64
		else
			echo "Cannot find storcli"
			exit 1
		fi
		COUNT_REAL=0

		ALL_CTRLS=$(${STORCLI} /call show J | jq '.["Controllers"][]["Command Status"]["Controller"]' -r | tr '\n' ' ')
		MY_DISK_COUNT=0
		OLD_DG="blah"
		COUNT_REAL=0
		for CTL_NUM in ${ALL_CTRLS} ; do
			# List non-JBOD first
			for SLOTNUM in $(${STORCLI} /c${CTL_NUM}/eall/sall show J | jq -r '.[][0]["Response Data"]["Drive Information"][] | select (.Type != "JBOD") | .["EID:Slt"]') ; do
				if [ "${PRODUCT_NAME}" = MZ01-CE1-00 ] ; then
					LETTER_VD_NUM=$(( ${COUNT_REAL} + 2 ))
					VD_NUM=$(echo ${SLOTNUM} | cut -d: -f2)
				else
					DG=$(${STORCLI} /c${CTL_NUM}/eall/sall show J | jq -r '.[][0]["Response Data"]["Drive Information"][] | select (."EID:Slt" == "'${SLOTNUM}'") | .["DG"]')
					if [ "${DG}" = "-" ] ; then
						DG=$(echo "${SLOTNUM}" | cut -d: -f2)
					fi
					VD_NUM=$(( ${COUNT_REAL} + ${DG} ))
					LETTER_VD_NUM=${VD_NUM}
				fi
				SLOT=$(echo ${SLOTNUM} | cut -d: -f2)
				case ${LETTER_VD_NUM} in
				0) D=sda ;;
				1) D=sdb ;;
				2) D=sdc ;;
				3) D=sdd ;;
				4) D=sde ;;
				5) D=sdf ;;
				6) D=sdg ;;
				7) D=sdh ;;
				8) D=sdi ;;
				9) D=sdj ;;
				10) D=sdk ;;
				11) D=sdl ;;
				12) D=sdm ;;
				13) D=sdn ;;
				14) D=sdo ;;
				15) D=sdp ;;
				16) D=sdq ;;
				17) D=sdr ;;
				18) D=sds ;;
				19) D=sdt ;;
				20) D=sdu ;;
				21) D=sdv ;;
				22) D=sdw ;;
				23) D=sdx ;;
				24) D=sdy ;;
				25) D=sdz ;;
				esac
				VD_STATE=$(${STORCLI} /c${CTL_NUM}/eall/sall show J | jq -r '.[][0]["Response Data"]["Drive Information"][] | select (."EID:Slt" == "'${SLOTNUM}'") | .["State"]')
				echo ${VD_NUM},${SLOT},${D},${VD_STATE},${CTL_NUM}:${SLOTNUM}  >>${VD_LIST2}
				if [ "${PRODUCT_NAME}" = MZ01-CE1-00 ] ; then
					COUNT_REAL=$((${COUNT_REAL} + 1))
				else
					if [ "${DG}" != "${OLD_DG}" ] ; then
						COUNT_REAL=$((${COUNT_REAL} + 1))
					fi
					OLD_DG=$DG
				fi
			done

			# List JBOD next
			for SLOTNUM in $(${STORCLI} /c${CTL_NUM}/eall/sall show J | jq -r '.[][0]["Response Data"]["Drive Information"][] | select (.Type == "JBOD") | .["EID:Slt"]') ; do
				VD_NUM=${COUNT_REAL}
				SLOT=$(echo ${SLOTNUM} | cut -d: -f2)
				case ${COUNT_REAL} in
				0) D=sda ;;
				1) D=sdb ;;
				2) D=sdc ;;
				3) D=sdd ;;
				4) D=sde ;;
				5) D=sdf ;;
				6) D=sdg ;;
				7) D=sdh ;;
				8) D=sdi ;;
				9) D=sdj ;;
				10) D=sdk ;;
				11) D=sdl ;;
				12) D=sdm ;;
				13) D=sdn ;;
				14) D=sdo ;;
				15) D=sdp ;;
				16) D=sdq ;;
				17) D=sdr ;;
				18) D=sds ;;
				19) D=sdt ;;
				20) D=sdu ;;
				21) D=sdv ;;
				22) D=sdw ;;
				23) D=sdx ;;
				24) D=sdy ;;
				25) D=sdz ;;
				esac
				VD_STATE=$(${STORCLI} /call/eall/sall show J | jq -r '.[][0]["Response Data"]["Drive Information"][] | select (."EID:Slt" == "'${SLOTNUM}'") | .["State"]')
				echo ${VD_NUM},${SLOT},${D},${VD_STATE},${SLOTNUM} >>${VD_LIST2}
				COUNT_REAL=$((${COUNT_REAL} + 1))
			done
		done
		return
	else
		megacli -LdPdInfo -a0 -NoLog | grep -E '^Virtual Drive:|^Slot Number:|^State' >${F_PDINFO}
		COUNT_REAL=-1
		while read line ; do
			# If the line contains : (ie: semicolumn) then it can be parsed
			if echo ${line} | grep -q -E "^Virtual Drive:" ; then
				VD_NUM=$(echo ${line} | sed "s/^Virtual Drive: //" | cut -d' ' -f1)
				COUNT_REAL=$((${COUNT_REAL} + 1))
			fi
			if echo ${line} | grep -q -E "^State" ; then
				VD_STATE=$(echo ${line} | cut -d: -f2 | cut -d' ' -f2)
			fi
			if echo ${line} | grep -q -E "^Slot Number:" ; then
				SLOT=$(echo "${line}" | sed "s/Slot Number: //")
				if [ "${PRODUCT_NAME}" = "ThinkSystem SR665" ] ; then
					COUNT=$((${COUNT_REAL} + 2))
				else
					COUNT=${COUNT_REAL}
				fi
				case ${COUNT} in
				0) D=sda ;;
				1) D=sdb ;;
				2) D=sdc ;;
				3) D=sdd ;;
				4) D=sde ;;
				5) D=sdf ;;
				6) D=sdg ;;
				7) D=sdh ;;
				8) D=sdi ;;
				9) D=sdj ;;
				10) D=sdk ;;
				11) D=sdl ;;
				12) D=sdm ;;
				13) D=sdn ;;
				14) D=sdo ;;
				15) D=sdp ;;
				16) D=sdq ;;
				17) D=sdr ;;
				18) D=sds ;;
				19) D=sdt ;;
				20) D=sdu ;;
				21) D=sdv ;;
				22) D=sdw ;;
				23) D=sdx ;;
				24) D=sdy ;;
				25) D=sdz ;;
				esac
				echo ${VD_NUM},${SLOT},${D},${VD_STATE} >>${VD_LIST2}
			fi
		done <${F_PDINFO}
		rm -f ${F_PDINFO}
	fi
}

megacli_vd_list () {
	megacli_vd_list2
	VD_LIST=$(mktemp)
	echo "Vd,Pd,Drive,Vdstate,Slot" >${VD_LIST}
#	cat ${VD_LIST2} | q -d, -H "SELECT * FROM - ORDER BY vd" >>${VD_LIST}
	cat ${VD_LIST2} | q -d, -H "SELECT * FROM -" >>${VD_LIST}
	rm -f ${VD_LIST2}
}

# Make a CSV file of the PD (Megacli Physical Disks) and their properties
megacli_pd_list2 () {
	PD_LIST2=$(mktemp -t ${myscript}_pd-list.XXXXXX)

	echo "Slot,Model,Serial,Size,State,Spun,Firmware" >${PD_LIST2}
	if [ -x /usr/bin/storcli_x64 ] || [ -x /usr/bin/storcli64 ] ; then
		if [ -x /usr/bin/storcli64 ] ; then
			STORCLI=/usr/bin/storcli64
		elif [ -x /usr/bin/storcli_x64 ] ; then
			STORCLI=/usr/bin/storcli_x64
		else
			echo "Cannot find storcli"
			exit 1
		fi
		ALL_CTRLS=$(${STORCLI} /call show J | jq '.["Controllers"][]["Command Status"]["Controller"]' -r | tr '\n' ' ')
		for CTL_NUM in ${ALL_CTRLS} ; do
			PD_LIST2_TMP=$(mktemp -t ${myscript}_pdlist-tmp.XXXXXX)
			for STORCLI_DRIVE in $(${STORCLI} /call/eall/sall show all nolog J | jq -r '.["Controllers"]['${CTL_NUM}']["Response Data"]|to_entries[]|.key' | grep -v "Detailed Information" | awk '{print $2}') ; do
				DRIVE_INFO=$(mktemp -t ${myscript}_storcli-drive-info.XXXXXX)
				${STORCLI} ${STORCLI_DRIVE} show all J | jq -r '.["Controllers"][0]["Response Data"]["Drive '${STORCLI_DRIVE}'"]' >${DRIVE_INFO}
				DRIVE_DETAILED_INFO=$(mktemp -t ${myscript}_storcli-drive-detailed-info.XXXXXX)
				${STORCLI} ${STORCLI_DRIVE} show all J | jq -r '.["Controllers"][0]["Response Data"]["Drive '${STORCLI_DRIVE}' - Detailed Information"]'>${DRIVE_DETAILED_INFO}
				
				if echo "${STORCLI_DRIVE}" | grep -q -E '^/c[0-9]+/e[0-9]+/s[0-9]+$' ; then
					SLOT_ENCL=$(echo "${STORCLI_DRIVE}" | cut -d/ -f3 | sed 's/e//')
					SLOT_SLOT=$(echo "${STORCLI_DRIVE}" | cut -d/ -f4 | sed 's/s//')
					SLOT_NUM_REAL=${SLOT_ENCL}:${SLOT_SLOT}
				else
					SLOT_NUM_REAL=$(cat ${DRIVE_INFO} | jq -r '.[]["DID"]')
				fi
				MODEL=$(cat ${DRIVE_INFO} | jq -r '.[]["Model"]' | sed -e 's/[ \t]*$//')
				SERIAL=$(cat ${DRIVE_DETAILED_INFO} | jq -r '.["Drive '${STORCLI_DRIVE}' Device attributes"]["SN"]' | sed -e 's/[ \t]*$//')
				SIZE=$(cat ${DRIVE_DETAILED_INFO} | jq -r '.["Drive '${STORCLI_DRIVE}' Device attributes"]["Raw size"]')
				STATE=$(cat ${DRIVE_INFO} | jq -r '.[]["State"]')
				SPUN=$(cat ${DRIVE_INFO} | jq -r '.[]["Sp"]')
				FW=$(cat ${DRIVE_DETAILED_INFO} | jq -r '.["Drive '${STORCLI_DRIVE}' Device attributes"]["Firmware Revision"]')
				
				echo "\"${CTL_NUM}:${SLOT_NUM_REAL}\",\"${MODEL}\",\"${SERIAL}\",\"${SIZE}\",\"${STATE}\",\"${SPUN}\",\"${FW}\"" >>${PD_LIST2_TMP}
				rm -f ${DRIVE_INFO}
			done
			cat ${PD_LIST2_TMP} | sort >>${PD_LIST2}
			rm -f ${PD_LIST2_TMP}
			set +x
		done
		return
	fi

	ENCLOSURE=$(megacli -EncInfo -aALL -NoLog | awk '/Device ID/ {print $4}' | head -n 1)

	for SLOT_NUM_REAL in $(megacli -pdlist -a0 -NoLog | grep "Slot Number:" | cut -d':' -f2 | awk '{print $1}') ; do
		if [ "${PRODUCT_NAME}" = "ThinkSystem SR665" ] ; then
			case "${SLOT_NUM_REAL}" in
			0|1|2|3|4|5|6|7|8|9|10|11)
				SLOT_NUM=${SLOT_NUM_REAL}
			;;
			24)	SLOT_NUM=12	;;
			25)	SLOT_NUM=13	;;
			26)	SLOT_NUM=14	;;
			27)	SLOT_NUM=15	;;
			*)	SLOT_NUM=${SLOT_NUM_REAL}	;;
			esac
		else
			SLOT_NUM=${SLOT_NUM_REAL}
		fi
		SMT_OUT=$(mktemp)
		smartctl -a -d megaraid,${SLOT_NUM} /dev/sda >${SMT_OUT} || true
		MODEL=$(cat ${SMT_OUT} | grep -E "^Device Model|^Product" | sed -e 's/^Device Model:     //' -e 's/^Product:              //')
		SERIAL=$(cat ${SMT_OUT} | grep "^Serial [nN]umber" | sed 's/^Serial [nN]umber:[ ]*//')
		SIZE=$(cat ${SMT_OUT} | grep "^User Capacity:" | cut -d'[' -f2 | cut -d']' -f1)
		FW=$(cat ${SMT_OUT} | grep -m1 -e "^Revision:" -e "^Firmware Version" | awk '{ print $NF }')
		rm -f ${SMT_OUT}
		FULL_STATE=$(megacli -PDInfo -PhysDrv [${ENCLOSURE}:${SLOT_NUM_REAL}] -aALL -NoLog | grep -E '^Firmware state: ' | sed 's/Firmware state: //')
		STATE=$(echo ${FULL_STATE} | cut -d, -f1)
		SPUN=$(echo ${FULL_STATE} | cut -d, -f2 | awk '{$1=$1;print}')
		echo "\"${SLOT_NUM_REAL}\",\"${MODEL}\",\"${SERIAL}\",\"${SIZE}\",\"${STATE}\",\"${SPUN}\",\"${FW}\"" >>${PD_LIST2}
	done
#	cat ${PD_LIST2}
}

megacli_pd_list () {
	megacli_pd_list2
	PD_LIST=$(mktemp)
	echo "Slot,Model,Serial,Size,State,Spun,Firmware" >${PD_LIST}
	cat ${PD_LIST2} | q -d, -H "SELECT * FROM - ORDER BY Slot" >>${PD_LIST}
	rm -f ${PD_LIST2}
}

show_disk_output_normal_dev () {
	local dsize dmodel dserial DISK_NAME MY_SMARTCTL_TMP dfw
	local oci_sort_name=${1}

	dsize=""
	dmodel=""
	dserial=""
	DISK_NAME=$(basename $(realpath /dev/disk/oci-sort/${oci_sort_name}))
	MY_SMARTCTL_TMP=$(mktemp -t oci-hdd-maint-smartctl.XXXXXX)
	smartctl -a /dev/${DISK_NAME} >${MY_SMARTCTL_TMP} || true

	dmodel=$(cat ${MY_SMARTCTL_TMP} | grep "Device Model" | sed 's/Device Model:     //')
	if [ -z "${dmodel}" ] ; then
		dmodel=$(cat ${MY_SMARTCTL_TMP} | grep "Product:" | sed 's/Product:              //')
	fi

	dserial=$(cat ${MY_SMARTCTL_TMP} | grep "Serial Number" | sed 's/Serial Number:    //')
	if [ -z "${dserial}" ] ; then
		dserial=$(cat ${MY_SMARTCTL_TMP} | grep "Serial number:" | sed 's/Serial number:        //')
	fi

	dsize=$(cat ${MY_SMARTCTL_TMP} | grep "User Capacity" | cut -d'[' -f2 | cut -d']' -f1 | sed 's#,#.#')
	dfw=$(cat ${MY_SMARTCTL_TMP} | grep -m1 -e "^Revision:" -e "^Firmware Version" | awk '{ print $NF }')

	echo ${oci_sort_name},${DISK_NAME},$dsize,$dmodel,$dserial,$dfw
}

show_disk_status () {
	if [ "${PRODUCT_NAME}" = "ProLiant DL345 Gen11" ] ; then
		echo "oci_name,current_name,Size,Model,Serial,Firmware"
		if ! [ -d /dev/disk/oci-sort ] ; then
			echo "Error: no /dev/disk/oci-sort."
			exit 1
		fi
		for ociname in $(ls -v /dev/disk/oci-sort/) ; do
			show_disk_output_normal_dev ${ociname}
		done
	elif [ "${PRODUCT_NAME}" != "ThinkSystem SR665" ] && lshw -class storage -json 2>/dev/null | jq -r '.[]["id"]' | grep -q "raid" ; then
		# Make a VD list CSV with output: vd,pd,drive
		megacli_vd_list
		# Make PD list CSV with output: Slot,Model,Serial,Size,State,Spun
		megacli_pd_list
		# LEFT JOIN both with a single q command
		(echo "PD,VD,VDState,Drive,Model,Serial,Size,State,Spun,Firmware";q -H -d, "SELECT pd.Slot, vd.Vd, pd.State, vd.Drive, pd.Model, pd.Serial, pd.Size, vd.Vdstate, pd.Spun, pd.Firmware FROM ${PD_LIST} pd JOIN ${VD_LIST} vd ON (vd.Slot = pd.Slot)")
		# rm both temp CSV files
		rm ${VD_LIST}
		rm ${PD_LIST}
	else
#		echo "No raid card"
		if [ -d /dev/disk/oci-sort ] ; then
			echo "oci_name,current_name,Size,Model,Serial,Firmware"
			for ociname in $(ls -v /dev/disk/oci-sort/) ; do
				show_disk_output_normal_dev ${ociname}
			done
		else
			echo "devname,Logical_ID,Size,Model,Serial,Firmware"
			for i in $(ls -v /dev/disk/by-path/ | grep -v part | grep -v usb) ; do
				dsize=""
				dmodel=""
				dserial=""
				LOGICAL_ID=$(echo $i | cut -d: -f3)
				DISK_NAME=$(basename $(realpath /dev/disk/by-path/$i))

				MY_SMARTCTL_TMP=$(mktemp -t oci-hdd-maint-smartctl.XXXXXX)
				if [ ""$(lsscsi -g | grep /dev/${DISK_NAME} | awk '{print $3}') = "HPE" ] ; then
					DEVID=$(lsscsi | grep /dev/${DISK_NAME} | cut -d] -f1 | cut -d: -f4)
					SMARTCTL_MINUS_D_OPT="-d cciss,${DEVID}"
				else
					SMARTCTL_MINUS_D_OPT=""
				fi
				smartctl ${SMARTCTL_MINUS_D_OPT} -a /dev/${DISK_NAME} >${MY_SMARTCTL_TMP} || true

				dmodel=$(cat ${MY_SMARTCTL_TMP} | grep "Device Model" | sed 's/Device Model:     //')
				if [ -z "${dmodel}" ] ; then
					dmodel=$(cat ${MY_SMARTCTL_TMP} | grep "Product:" | sed 's/Product:              //')
				fi
				dserial=$(cat ${MY_SMARTCTL_TMP} | grep "Serial Number" | sed 's/Serial Number:    //')
				if [ -z "${dserial}" ] ; then
					dserial=$(cat ${MY_SMARTCTL_TMP} | grep "Serial number:" | sed 's/Serial number:        //')
				fi
				dsize=$(cat ${MY_SMARTCTL_TMP} | grep "User Capacity" | cut -d'[' -f2 | cut -d']' -f1 | sed 's#,#.#')
				dfw=$(cat ${MY_SMARTCTL_TMP} | grep -m1 -e "^Revision:" -e "^Firmware Version" | awk '{ print $NF }')
				echo ${DISK_NAME},${LOGICAL_ID},$dsize,$dmodel,$dserial,$dfw
				rm ${MY_SMARTCTL_TMP}
			done
		fi
	fi
}

wait_until_mounted () {
	local MOUNT_POINT TIMESTAMP_TIMEOUT
	MOUNT_POINT=${1}

	TIMESTAMP_TIMEOUT=$(date -d "now + 30 sec" +%s)
	while ! mountpoint -q "${MOUNT_POINT}"  && [ $(date +%s) -lt "${TIMESTAMP_TIMEOUT}" ] ; do
		sleep 1
	done
	if ! mountpoint -q "${MOUNT_POINT}" ; then
		echo "Device not mounted after the mount command and 30 seconds timeout: exiting."
		exit 1
	fi
}

replace_disk () {
	# Fix duplicate fstab lines
	if [ -n ""$(uniq -D /etc/fstab) ] ; then
		TMPFILE_DUP=$(mktemp -t $(basefile $0)-fix-dup-lines.XXXXXX)
		awk '!seen[$0]++' /etc/fstab >${TMPFILE_DUP}
		cat ${TMPFILE_DUP} >/etc/fstab
		rm -f ${TMPFILE_DUP}
	fi

	OLD_DISK=$1
	if [ -d /dev/disk/oci-sort ] ; then
		REALDISK=$(basename $(realpath /dev/disk/oci-sort/${OLD_DISK}))
	else
		REALDISK=${OLD_DISK}
	fi
	OLD_UUID=$(cat /etc/fstab | grep -m1 /srv/node/${OLD_DISK} | awk '{print $1}' | sed -e 's/[#]*UUID=//')

	echo "===> Checking new disk firmware version"
	# Check FW release first
	# No RAID case first.
	if [ "${PRODUCT_NAME}" != "ThinkSystem SR665" ] && ! lshw -class storage -json 2>/dev/null | jq -r '.[]["id"]' | grep -q "raid" ; then
		if [ -x /usr/bin/disk-firmware-updater ] ; then
			disk-firmware-updater $REALDISK
		else
			echo "disk-firmware-installer not installed"
		fi

		# rm -f ${MY_SMARTCTL_TMP}
	fi

	echo "===> Formating /dev/${REALDISK} (for /srv/node/${OLD_DISK}) with UUID ${OLD_UUID}"
	mkfs.xfs -f -m uuid=${OLD_UUID} /dev/${REALDISK}
	echo "===> Uncommenting from fstab"
	sed -i "s/[#]*UUID=${OLD_UUID}/UUID=${OLD_UUID}/" /etc/fstab
	echo "===> Reloading systemd after fstab edit"
	systemctl daemon-reload
	echo "===> Mounting /srv/node/${OLD_DISK}"
	mount "/srv/node/${OLD_DISK}"

	wait_until_mounted "/srv/node/${OLD_DISK}"

	echo "===> Changing disk's owner"
	chown swift:swift "/srv/node/${OLD_DISK}"
	echo "===> Truncating /var/log/kern-legacy.log"
	if [ -e /var/log/kern-legacy.log ] ; then
		echo -n "" >/var/log/kern-legacy.log
	fi
}

usage () {
	echo "                 -l : list devices (columns output)"
	echo "               -csv : list devices (csv output)"
	echo "            -s <ID> : setup RAID device"
	echo "        -y <ID/sdX> : prepare disk for removal for HDD in slot <ID> or /dev/sdX"
	echo "                      (ie: megacli or hdparm commands)"
	echo "            -u <ID> : stop blinking LED for HDD in slot <ID>"
	echo "-r <replacement-hdd>: format and mount <replacement-hdd>"
	echo "         -pdlist-csv: output physical disks list in CSV format"
	echo "             -pdlist: output physical disks in table format"
	echo "         -vdlist-csv: output virtual disks in CSV format"
	echo "             -vdlist: output virtual disks in table format"
	exit 1
}

if [ "${1}" = "-pdlist-csv" ] ; then
	megacli_pd_list
	cat ${PD_LIST}
	rm -f ${PD_LIST}
	exit 0
fi

if [ "${1}" = "-pdlist" ] ; then
	megacli_pd_list
	cat ${PD_LIST} | csvlook --blanks -I
	rm -f ${PD_LIST}
	exit 0
fi

if [ "${1}" = "-vdlist-csv" ] ; then
	megacli_vd_list
	cat ${VD_LIST}
	rm -f ${VD_LIST}
	exit 0
fi

if [ "${1}" = "-vdlist" ] ; then
	megacli_vd_list
	cat ${VD_LIST} | csvlook --blanks -I
	rm -f ${VD_LIST}
	exit 0
fi

if [ "${1}" = "-csv" ] ; then
	show_disk_status
	exit 0
else
	case ${1} in
	"-h")
		usage
		;;
	"-s")
		if [ -z "${2}" ] ; then
			usage
		fi
		if [ ""$(lshw -class storage -json 2>/dev/null | jq -r '.[]["id"]' | head -n1) = "raid" ] ; then
			echo "Setting up RAID for device ${2}..."
			megacli -DiscardPreservedCache -Lall -a0
			megacli -CfgLdAdd -r0[32:${2}] WB RA Direct -a0
		else
			echo "Didn't detect hardware RAID"
			exit 1
		fi
		;;
	"-l")
		$0 -csv | csvlook --blanks -I
		case "${PRODUCT_NAME}" in
		"PowerEdge R720xd")
			echo "HDD (PD) disposition:"
			echo "Col1,Col2,Col3,Col4
0,3,6,9
1,4,7,10
2,5,8,11" | csvlook --blanks -I
		;;
		"PowerEdge R740xd")
			echo "HDD disposition:"
			echo "Col1,Col2,Col3,Col4
sda,sdd,sdg,sdj
sdb,sde,sdh,sdk
sdc,sdf,sdi,sdl" | csvlook --blanks -I
		;;
		"CL2800 Gen10")
			echo "HDD disposition:"
			echo "Col1,Col2,Col3,Col4
sda,sdb,sdc,sdd
sdg,sdh,sdi,sdj
sdk,sdl,sdm,sdn" | csvlook --blanks -I
			echo "Sometimes, with inverted cabling:"
			echo "Col1,Col2,Col3,Col4
sdg,sdh,sdi,sdj
sdk,sdl,sdm,sdn
sda,sdb,sdc,sdd" | csvlook --blanks -I
		;;
		"ProLiant DL345 Gen11")
			echo "HDD disposition (oci_name, front panel):"
			echo "Box,Bay1,Bay2,Bay3,Bay4
1,sda,sdb,sdc,sdd
2,sde,sdf,sdg,sdh
3,sdi,sdj,sdk,sdl" | csvlook --blanks -I
			echo "HDD disposition (oci_name, back panel):"
			echo "Box,Bay1,Bay2,Bay3,Bay4
8,sdm,sdn,sdo,sdp" | csvlook --blanks -I
		;;
		"ProLiant DL385 Gen10 Plus")
			echo "HDD disposition (oci_name, front panel):"
			echo "Col1,Col2,Col3,Col4
sdc,sdd,sde,sdf
sdg,sdh,sdi,sdj
sdk,sdl,sdm,sdn" | csvlook --blanks -I
			echo "SSD disposition (oci_name, back panel):"
			echo "---------------------------------------"
			echo "sda"
			echo "sdb"
		;;
		# See https://thinksystem.lenovofiles.com/help/topic/7D2W/sr665_setup_guide.pdf
		# page 45 and 64
		"ThinkSystem SR665")
			echo "HDD disposition (oci_name, front panel):"
			echo "Col1,Col2,Col3,Col4
sdc,sdf,sdi,sdl
sdd,sdg,sdj,sdm
sde,sdh,sdk,sdn" | csvlook --blanks -I
			echo "HDD disposition (oci_name, back panel):"
			echo "Col1,Col2,Col3,Col4
sdo,sdp,sdq,sdr" | csvlook --blanks -I
		;;
		"MZ01-CE1-00")
			echo 'HDD disposition (oci_name):
  / sde / sdf | sdd \ sdc \
 / sdi /  sdj | sdh  \ sdg \
-------d-r-a-w-e-r---0-------
  / sdm / sdn | sdl \ sdk \
 / sdq /  sdr | sdp  \ sdo \
-------d-r-a-w-e-r---1-------
  / sdu / sdv | sdt \ sds \
 / sdy /  sdz | sdx  \ sdw \
-------d-r-a-w-e-r---2-------
System drive slots (seen from back):
sda (left), sdb (right)'
		;;
		*)
		;;
		esac
		exit 0
		;;
	"-r")
		if [ -z "${2}" ] ; then
			usage
		fi
#		if [ -z "${3}" ] ; then
#			usage
#		fi
		replace_disk ${2}
		;;
	"-y")
		if [ ""$(lshw -class storage -json 2>/dev/null | jq -r '.[]["id"]' | head -n1) = "raid" ] ; then
			ENCLOSURE=$(megacli -EncInfo -aALL -NoLog | awk '/Device ID/ {print $4}')
			case ${2} in
			0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63)
				echo "Powering off the drive in slot ${2}"
				megacli -PDOffline -PhysDrv [${ENCLOSURE}:${2}] -aall
				echo "Prepare the drive in slot ${2} for removal"
				megacli -PDPrpRmv -PhysDrv [${ENCLOSURE}:${2}] -aall
				echo "Making the LED of HDD ${2} blink."
				megacli -PdLocate -start -PhysDrv [${ENCLOSURE}:${2}] -aall
				exit 0
			;;
			*)
				echo "HDD slot not recognized: exiting."
				exit 1
			;;
			esac
		else
			if [ -d /dev/disk/oci-sort ] ; then
				hdparm -y /dev/${2} || true
			else
				case ${2} in
				sda|sdb|sdc|sdd|sde|sdf|sdg|sdh|sdi|sdj|sdk|sdl|sdm|sdn|sdo|sdp|sdq|sdr|sds|sdt|sdu|sdv|sdw|sdx|sdy|sdz)
					echo "Force ${2} to immediately enter the low power consumption standby mode, usually causing it to spin down."
					hdparm -y /dev/${2} || true
					VENDOR=$(dmidecode -s system-manufacturer)
					if [ "${VENDOR}" = "Dell Inc." ] && [ $(racadm get storage.Controller.1 | grep -i NonRAID | cut -d= -f2 | cut -d'#' -f1) = NonRAID.Integrated.1-1 ] ; then
						case ${2} in
						sda) ID="Disk.Bay.0:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdb) ID="Disk.Bay.1:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdc) ID="Disk.Bay.2:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdd) ID="Disk.Bay.3:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sde) ID="Disk.Bay.4:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdf) ID="Disk.Bay.5:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdg) ID="Disk.Bay.6:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdh) ID="Disk.Bay.7:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdi) ID="Disk.Bay.8:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdj) ID="Disk.Bay.9:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdk) ID="Disk.Bay.10:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdl) ID="Disk.Bay.11:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdm) ID="Disk.Bay.12:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdn) ID="Disk.Bay.13:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdo) ID="Disk.Bay.14:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdp) ID="Disk.Bay.15:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdq) ID="Disk.Bay.16:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdr) ID="Disk.Bay.17:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sds) ID="Disk.Bay.18:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdt) ID="Disk.Bay.19:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdu) ID="Disk.Bay.20:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdv) ID="Disk.Bay.21:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdw) ID="Disk.Bay.22:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdx) ID="Disk.Bay.23:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdy) ID="Disk.Bay.24:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						sdz) ID="Disk.Bay.25:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
						*) exit 0;;
						esac
						racadm storage blink:${ID}
					fi
					exit 0
				;;
				*)
					echo "HDD name not recognized: exiting."
					exit 1
				;;
				esac
			fi
		fi
		;;
	"-u")
		if [ -d /dev/disk/oci-sort ] ; then
			echo "not supported with this hardware"
		else
			if [ ""$(lshw -class storage -json 2>/dev/null | jq -r '.[]["id"]' | head -n1) = "raid" ] ; then
				ENCLOSURE=$(megacli -EncInfo -aALL -NoLog | awk '/Device ID/ {print $4}')
				case ${2} in
				0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56|57|58|59|60|61|62|63)
					echo "Stop the blinking of the LED of HDD ${2}."
					megacli -PdLocate -stop -PhysDrv [${ENCLOSURE}:${2}] -aall
					exit 0
				;;
				*)
					echo "HDD slot not recognized: exiting."
					exit 1
				;;
				esac
			else
				VENDOR=$(dmidecode -s system-manufacturer)
				if [ "${VENDOR}" = "Dell Inc." ] && [ $(racadm get storage.Controller.1 | grep -i NonRAID | cut -d= -f2 | cut -d'#' -f1) = NonRAID.Integrated.1-1 ] ; then
					case ${2} in
					sda) ID="Disk.Bay.0:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdb) ID="Disk.Bay.1:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdc) ID="Disk.Bay.2:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdd) ID="Disk.Bay.3:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sde) ID="Disk.Bay.4:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdf) ID="Disk.Bay.5:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdg) ID="Disk.Bay.6:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdh) ID="Disk.Bay.7:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdi) ID="Disk.Bay.8:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdj) ID="Disk.Bay.9:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdk) ID="Disk.Bay.10:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdl) ID="Disk.Bay.11:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdm) ID="Disk.Bay.12:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdn) ID="Disk.Bay.13:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdo) ID="Disk.Bay.14:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdp) ID="Disk.Bay.15:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdq) ID="Disk.Bay.16:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdr) ID="Disk.Bay.17:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sds) ID="Disk.Bay.18:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdt) ID="Disk.Bay.19:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdu) ID="Disk.Bay.20:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdv) ID="Disk.Bay.21:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdw) ID="Disk.Bay.22:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdx) ID="Disk.Bay.23:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdy) ID="Disk.Bay.24:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					sdz) ID="Disk.Bay.25:Enclosure.Internal.0-1:NonRAID.Integrated.1-1" ;;
					*) exit 0;;
					esac
					racadm storage unblink:${ID}
					exit 0
				else
					echo "This is not possible for non-raid config."
					exit 1
				fi
			fi
		fi
		;;
	*)
		usage
		;;
	esac
fi
