mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-08-28 17:46:40 +00:00
27aaa960fa
The scan wrote each disk into a file named after the identifier it reported, wwn, path or neither, and read back the groups of one such file only. Two disks that reported different identifiers therefore never competed on their driver group: a disk without a WWN was dropped as soon as another disk reported one, and when the last disk scanned reported a WWN the readback opened the WWN files alone. A direct attached boot disk that reports no WWN thus lost to a RAID volume that reports one, which is the case the driver groups exist to decide. Write every disk into the file of its driver group and keep the identifier as the sort key inside that group, ranked so that a WWN sorts ahead of a path and a path ahead of no identifier. The driver group now decides first for every disk, the identifier still decides between disks of one group, and no disk is dropped from the scan.
258 lines
9.5 KiB
Bash
258 lines
9.5 KiB
Bash
#!/bin/sh
|
|
|
|
#-----------------------------------------------------------
|
|
#
|
|
# Get proper disk to install OS
|
|
#
|
|
# 1. Check all partitions listed in /proc/partitions, whether
|
|
# there is a disk that had OS installed. If there is, add it to
|
|
# the disk array.
|
|
# 2. If there is no disk that had OS installed found
|
|
# in Step 1, then check all disks in
|
|
# /proc/partitions file. Sort them by driver type, then by WWN/PATH
|
|
# select the first one.
|
|
# 3. If no disks selected in Steps 1 or 2, then
|
|
# select the default disk: /dev/sda.
|
|
#
|
|
# Output: Install disk name written to /tmp/xcat.install_disk
|
|
#
|
|
#-----------------------------------------------------------
|
|
|
|
install_disk=""
|
|
install_disk_file="/tmp/xcat.install_disk"
|
|
|
|
tmpdir="/tmp/xcat.getinstalldisk"
|
|
mkdir -p $tmpdir
|
|
|
|
has_awk=$(find /usr/* -name "awk")
|
|
|
|
utolcmd="sed -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
|
|
|
|
tmpfile="$tmpdir/getinstalldisk_"
|
|
|
|
if [ -z "$install_disk" ]; then
|
|
|
|
echo "[get_install_disk]Contents of /proc/partitions:"
|
|
cat /proc/partitions
|
|
echo ""
|
|
|
|
# Get all partitions and disks from /proc/partitions file
|
|
if [ -z "$has_awk" ]; then
|
|
entries=$(cat /proc/partitions | sed 's/ */ /g' | cut -d " " -f5 | grep -v "name" | grep -E '^(x?v|s|h)d|^nvme')
|
|
else
|
|
entries=$(awk -F ' ' '{print $4}' /proc/partitions | grep -v "name" | grep -E '^(x?v|s|h)d|^nvme')
|
|
fi
|
|
|
|
# Classify entries by DEVTYPE
|
|
for entry in $entries; do
|
|
DEVSIZE=$(udevadm info --attribute-walk --name=$entry|grep \{size\}| sed -e 's/[^"]*"//' -e 's/"//'|tail -n 1)
|
|
if [ -z "$DEVSIZE" -o $DEVSIZE -lt 262144 ]; then
|
|
# ignore small devices, that are likely remote media or similar
|
|
echo "[get_install_disk] Skipping partition $entry. Size too small: $DEVSIZE"
|
|
continue
|
|
fi
|
|
|
|
if [ -z "$has_awk" ]; then
|
|
dev_type=$(udevadm info --query=property --name=/dev/$entry | grep -i "DEVTYPE" | cut -d "=" -f2 | $utolcmd)
|
|
else
|
|
dev_type=$(udevadm info --query=property --name=/dev/$entry | grep -i "DEVTYPE" | awk -F = '{print $2}' | $utolcmd)
|
|
fi
|
|
|
|
if [ "$dev_type" = "disk" ]; then
|
|
disks=$disks"$entry "
|
|
elif [ "$dev_type" = "partition" ]; then
|
|
partitions=$partitions"$entry "
|
|
fi
|
|
done
|
|
|
|
mount_dir=$tmpdir"/xcat.getinstalldisk.mount"
|
|
mkdir -p $mount_dir;
|
|
|
|
disk_array=""
|
|
umount_rc=0
|
|
|
|
for partition in $partitions; do
|
|
echo "[get_install_disk]Check the partition $partition."
|
|
|
|
if [ -e "$tmpfile${partition%%[0-9]*}" ]; then
|
|
echo "[get_install_disk] The disk ${partition%%[0-9]*} had OS installed, check next partition."
|
|
continue
|
|
fi
|
|
|
|
# Get partition's fs_type
|
|
if [ -z "$has_awk" ]; then
|
|
fs_type=$(udevadm info --query=property --name=/dev/$partition | grep -i "FS_TYPE" | cut -d "=" -f2)
|
|
else
|
|
fs_type=$(udevadm info --query=property --name=/dev/$partition | grep -i "FS_TYPE" | awk -F = '{print $2}')
|
|
fi
|
|
|
|
rc=255
|
|
|
|
# Mount partition based on fs type, if fs_type is "swap", do not mount it, jump to next partition.
|
|
if [ -z "$fs_type" ]; then
|
|
mount /dev/$partition $mount_dir
|
|
rc=$?
|
|
elif [ "$fs_type" != "swap" ]; then
|
|
mount -t $fs_type /dev/$partition $mount_dir
|
|
rc=$?
|
|
fi
|
|
|
|
# Check whether mount successfully
|
|
if [ $rc -eq 0 ]; then
|
|
echo "[get_install_disk] Partition $partition mount success."
|
|
|
|
ker_dir=$mount_dir
|
|
if [ -d "$mount_dir/boot" ]; then
|
|
ker_dir="$mount_dir/boot"
|
|
fi
|
|
|
|
# If there is kernel file, add partition's disk into disk_array
|
|
# It seems the kernel file in ubuntu and sles are named like vmlinux, but in RH it is called vmlinuz
|
|
# To check both vmlinux and vmlinuz, use regular expression "vmlinu*" to match them
|
|
for i in $(find $ker_dir -maxdepth 1 -name "vmlinu*"); do
|
|
case $partition in
|
|
nvme*)
|
|
# Expected nvme partition format example: nvme0n1p1
|
|
disk_part=${partition%%p*}
|
|
;;
|
|
*)
|
|
# Expected sd partition format example: sda1
|
|
disk_part=${partition%%[0-9]*}
|
|
;;
|
|
esac
|
|
touch "$tmpfile$disk_part"
|
|
disk_array=$disk_array"$disk_part "
|
|
echo "[get_install_disk] The partition $partition has kernel file."
|
|
break
|
|
done
|
|
|
|
umount -l $mount_dir || echo "[get_install_disk] $partition umount failed."
|
|
if [ $? -ne 0 ]; then
|
|
# Preserve a umount failure RC
|
|
umount_rc=$?
|
|
fi
|
|
else
|
|
echo "[get_install_disk] Partition $partition mount failed or the partition is swap."
|
|
fi
|
|
done
|
|
|
|
# If disk_array is not empty, make disks equal disk_array for next step to sort
|
|
if [ "$disk_array" ]; then
|
|
disks=$disk_array
|
|
echo "[get_install_disk]The disks which have kernel:"
|
|
echo "[get_install_disk] $disks"
|
|
echo ""
|
|
fi
|
|
|
|
if [ $umount_rc -eq 0 ]; then
|
|
rmdir $mount_dir;
|
|
else
|
|
# Do not remove $mount_dir if there was a umount failure, as it might wipe out
|
|
# the contents of a still mounted disk
|
|
echo "[get_install_disk]There was a umount failure earlier, not removing $mount_dir"
|
|
fi
|
|
|
|
for file in $tmpfile*; do
|
|
rm $file;
|
|
done
|
|
|
|
disk_data=""
|
|
disk_rank=""
|
|
|
|
# Check disks which had installed OS, or check all disks in /proc/partitions
|
|
for disk in $disks; do
|
|
# Get disk's information: WWN, PATH and DRIVER
|
|
disk_info=$(udevadm info --query=property --name=$disk)
|
|
output_for_wwn=$(IFS= ;echo $disk_info | grep '\<ID_WWN\>' | cut -d "=" -f2)
|
|
disk_wwn=$(echo $output_for_wwn | $utolcmd)
|
|
output_for_path=$(IFS= ;echo $disk_info | grep DEVPATH | cut -d "=" -f2)
|
|
disk_path=$(echo $output_for_path | $utolcmd)
|
|
disk_driver=$(udevadm info --attribute-walk --name=$disk | grep DRIVERS| grep -v '""'| grep -v '"sd"'|
|
|
\head -n 1| sed -e 's/[^"]*"//' -e 's/"//' | $utolcmd)
|
|
|
|
echo "[get_install_disk]The disk $disk information: "
|
|
echo "[get_install_disk] disk_wwn=$disk_wwn"
|
|
echo "[get_install_disk] disk_path=$disk_path"
|
|
echo "[get_install_disk] disk_driver=$disk_driver"
|
|
|
|
# Rank the identifier. A disk that reports a WWN sorts ahead of one
|
|
# that reports only a path, and that one ahead of a disk with neither,
|
|
# but the rank decides only among disks of the same driver group.
|
|
if [ "$disk_wwn" ]; then
|
|
disk_rank="0"
|
|
disk_data=$disk_wwn
|
|
elif [ "$disk_path" ]; then
|
|
disk_rank="1"
|
|
disk_data=$disk_path
|
|
else
|
|
disk_rank="2"
|
|
disk_data=""
|
|
fi
|
|
|
|
# Sort disks by DRIVER type
|
|
case "$disk_driver" in
|
|
"ata_piix"*|"ahci")
|
|
echo "$disk $disk_rank$disk_data" >> "$tmpfile""firstchoicedisks"
|
|
echo "[get_install_disk] Add disk: $disk $disk_data into firstchoicedisks"
|
|
;;
|
|
"PMC MaxRAID"|"megaraid_sas")
|
|
echo "$disk $disk_rank$disk_data" >> "$tmpfile""secondchoicedisks"
|
|
echo "[get_install_disk] Add disk: $disk $disk_data into secondchoicedisks"
|
|
;;
|
|
"mptsas"|"mpt2sas"|"mpt3sas")
|
|
echo "$disk $disk_rank$disk_data" >> "$tmpfile""thirdchoicedisks"
|
|
echo "[get_install_disk] Add disk: $disk $disk_data into thirdchoicedisks"
|
|
;;
|
|
*)
|
|
echo "$disk $disk_rank$disk_data" >> "$tmpfile""fourthchoicedisks"
|
|
echo "[get_install_disk] Add disk: $disk $disk_data into fourthchoicedisks"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
for seq in first second third fourth; do
|
|
if [ -s $tmpfile${seq}choicedisks ]; then
|
|
install_file="$tmpfile${seq}choicedisks"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ "$install_file" ] && [ -s $install_file ]; then
|
|
install_disk=/dev/$(cat $install_file | grep -v "^$" | sort -k 2 -b | cut -d " " -f1 | head -n 1)
|
|
echo "[get_install_disk]The install_disk is $install_disk by DRIVER, then by identifier."
|
|
fi
|
|
|
|
for file in $tmpfile*; do
|
|
rm $file;
|
|
done
|
|
fi
|
|
rm -rf $tmpdir;
|
|
|
|
# Auto-sense an Intel RSTe/VROC software RAID and use it if no other install
|
|
# disk was found, before falling back to the hard-coded default below.
|
|
if [ -z "$install_disk" ] && [ -b /dev/md/Volume0_0 ]; then
|
|
install_disk="/dev/md/Volume0_0"
|
|
elif [ -z "$install_disk" ] && [ -b /dev/md/Volume0 ]; then
|
|
install_disk="/dev/md/Volume0"
|
|
fi
|
|
|
|
# Enable boot in Xen VM
|
|
if [ -z "$install_disk" ] && [ -b "/dev/xvda" ]; then
|
|
install_disk="/dev/xvda"
|
|
echo "[get_install_disk]Choosing default install_disk $install_disk."
|
|
fi
|
|
|
|
# Cannot find proper disk for OS install, select the default one "/dev/sda"
|
|
if [ -z "$install_disk" ]; then
|
|
install_disk="/dev/sda"
|
|
echo "[get_install_disk]Choosing default install_disk $install_disk."
|
|
# The installer scripts that include this one define msgutil_r, except
|
|
# the subiquity path
|
|
if command -v msgutil_r >/dev/null 2>&1; then
|
|
msgutil_r "$MASTER_IP" "warn" "Disk detection failed, defaulting to $install_disk" "/var/log/xcat/xcat.log" "$log_label"
|
|
fi
|
|
fi
|
|
|
|
# Output the result to $install_disk_file
|
|
echo $install_disk > $install_disk_file
|