b95cbb14b1
As part of the blueprint root-device-hints Ironic will pass some to the deploy ramdisk some hints about which disk device it should pick to be root device (the one where the image will be deployed on). Before the deploy ramdisk would pick the first device it finds, but as the machine could have more than one SATA, SCSI or IDE disk controllers the order in which their corresponding device nodes are added is arbitrary causing devices like /dev/sda and /dev/sdb switching around on each boot time. Plus, as people are adding support to build RAID arrays in Ironic we need a way to tell it to use the just created device to be the root device. The list of hints that could be passed to the deploy ramdisk so it finds the right disk is: * wwn (STRING): unique storage identifier * serial (STRING): disk serial number * model (STRING): device identifier * vendor (STRING): device vendor * size (INT): The size of the disk in GB If not hints are passed, the deploy ramdisk will continue to do what it did before to find the disk. Change-Id: I8425f593e1a610af5a3697988702603ff218f2de
115 lines
2.7 KiB
Text
115 lines
2.7 KiB
Text
CHECK_SIZE=false
|
|
CHECK_MODEL=false
|
|
CHECK_VENDOR=false
|
|
CHECK_UUID=false
|
|
CHECK_WWN=false
|
|
CHECK_HCTL=false
|
|
CHECK_SERIAL=false
|
|
|
|
|
|
# URL/Percent decode a text
|
|
function urldecode() {
|
|
local encoded="${1//+/ }"
|
|
printf '%b' "${encoded//%/\x}"
|
|
}
|
|
|
|
|
|
# Lowercase and url decode the values
|
|
function normalize() {
|
|
echo `urldecode "${1,,}"`
|
|
}
|
|
|
|
|
|
function _exec_lsblk() {
|
|
lsblk -Pbio $2 /dev/$1 | head -n 1 | grep -Po "(?<=^$2=).*" | tr "\"" " "
|
|
}
|
|
|
|
|
|
# Get the block device size in GiB
|
|
function get_size() {
|
|
echo $(( (512 * $(cat /sys/block/$1/size) ) / 2**30))
|
|
}
|
|
|
|
|
|
function get_model() {
|
|
local file
|
|
file=/sys/block/$1/device/model
|
|
if [ -f $file ]; then
|
|
normalize "$(cat $file)"
|
|
fi
|
|
}
|
|
|
|
|
|
function get_vendor() {
|
|
local file
|
|
file=/sys/block/$1/device/vendor
|
|
if [ -f $file ]; then
|
|
normalize "$(cat $file)"
|
|
fi
|
|
}
|
|
|
|
|
|
function get_wwn() {
|
|
normalize "$(_exec_lsblk "$1" WWN)"
|
|
}
|
|
|
|
|
|
function get_serial() {
|
|
normalize "$(_exec_lsblk "$1" SERIAL)"
|
|
}
|
|
|
|
|
|
# Parse all the hints from the Kernel cmdline and set the CHECK_*
|
|
# variables
|
|
function parse_hints() {
|
|
IFS=',' read -ra H <<< "$ROOT_DEVICE"
|
|
for i in "${H[@]}"; do
|
|
case "$i" in
|
|
size=*)
|
|
CHECK_SIZE="${i#size=}"
|
|
;;
|
|
model=*)
|
|
CHECK_MODEL=`normalize "${i#model=}"`
|
|
;;
|
|
vendor=*)
|
|
CHECK_VENDOR=`normalize "${i#vendor=}"`
|
|
;;
|
|
wwn=*)
|
|
CHECK_WWN=`normalize "${i#wwn=}"`
|
|
;;
|
|
serial=*)
|
|
CHECK_SERIAL=`normalize "${i#serial=}"`
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
|
|
function get_root_device() {
|
|
# Parse the hints
|
|
parse_hints
|
|
|
|
for DEV in /sys/block/* ; do
|
|
DEV_NAME=${DEV##*/}
|
|
DEV_PATH=/dev/$DEV_NAME
|
|
|
|
# Ignore loop and ram devices
|
|
[[ $DEV_NAME = *loop* || $DEV_NAME = *ram* ]] && continue || :
|
|
|
|
# Find out if it's a CDROM
|
|
TYPE=/sys/block/$DEV_NAME/device/type
|
|
[[ -f $TYPE ]] && (( $(cat "$TYPE") == 5 )) && continue || :
|
|
|
|
[[ $CHECK_SIZE != false && $(get_size "$DEV_NAME") != $CHECK_SIZE ]] && continue || :
|
|
[[ $CHECK_MODEL != false && $(get_model "$DEV_NAME") != $CHECK_MODEL ]] && continue || :
|
|
[[ $CHECK_VENDOR != false && $(get_vendor "$DEV_NAME") != $CHECK_VENDOR ]] && continue || :
|
|
[[ $CHECK_SERIAL != false && $(get_serial "$DEV_NAME") != $CHECK_SERIAL ]] && continue || :
|
|
[[ $CHECK_WWN != false && $(get_wwn "$DEV_NAME") != $CHECK_WWN ]] && continue || :
|
|
|
|
# A device that matches all hints was found
|
|
echo "$DEV_PATH"
|
|
break
|
|
done
|
|
}
|