diskimage-builder/elements/deploy-ironic/init.d/70-ironic-root-device
Lucas Alvares Gomes b95cbb14b1 Ironic: Deploy ramdisk to find the right root device
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
2015-03-13 14:09:40 +00:00

116 lines
2.7 KiB
Plaintext

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
}