ff988ac45c
This patch is extending the root device hints to also look at ID_WWN_WITH_EXTENSION and ID_WWN_VENDOR_EXTENSION from udev. Prior to this patch the bash ramdisk only cared about ID_WWN but in some systems in some platforms with a RAID controller, this ID can be same even if they are different disks (see bug 1516641). Related-Bug: #1516641 Change-Id: I45b3910d03d164d880b32169b91e94e88812e183
139 lines
3.5 KiB
Plaintext
139 lines
3.5 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 "\"" " "
|
|
}
|
|
|
|
|
|
function _exec_scsi_id() {
|
|
/lib/udev/scsi_id --whitelisted --export -d $1 | grep $2 | cut -d "=" -f 2
|
|
}
|
|
|
|
|
|
# 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_wwn_with_extension() {
|
|
normalize "$(_exec_scsi_id "$1" ID_WWN_WITH_EXTENSION)"
|
|
}
|
|
|
|
|
|
function get_wwn_vendor_extension() {
|
|
normalize "$(_exec_scsi_id "$1" ID_WWN_VENDOR_EXTENSION)"
|
|
}
|
|
|
|
|
|
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=}"`
|
|
;;
|
|
wwn_with_extension=*)
|
|
CHECK_WWN_WITH_EXT=`normalize "${i#wwn_with_extension=}"`
|
|
;;
|
|
wwn_vendor_extension=*)
|
|
CHECK_WWN_VENDOR_EXT=`normalize "${i#wwn_vendor_extension=}"`
|
|
;;
|
|
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 || :
|
|
[[ $CHECK_WWN_WITH_EXT!= false && $(get_wwn_with_extension "$DEV_NAME") != $CHECK_WWN_WITH_EXT ]] && continue || :
|
|
[[ $CHECK_WWN_VENDOR_EXT != false && $(get_wwn_vendor_extension "$DEV_NAME") != $CHECK_WWN_VENDOR_EXT ]] && continue || :
|
|
|
|
# A device that matches all hints was found
|
|
echo "$DEV_PATH"
|
|
break
|
|
done
|
|
}
|