diff --git a/xCAT-server/share/xcat/install/scripts/getinstdisk b/xCAT-server/share/xcat/install/scripts/getinstdisk index bb345a632..64236b2fc 100644 --- a/xCAT-server/share/xcat/install/scripts/getinstdisk +++ b/xCAT-server/share/xcat/install/scripts/getinstdisk @@ -38,9 +38,9 @@ if [ -z "$install_disk" ]; then # 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 '^[s|h|v]d|nvme') + 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 '^[s|h|v]d|nvme') + entries=$(awk -F ' ' '{print $4}' /proc/partitions | grep -v "name" | grep -E '^(x?v|s|h)d|^nvme') fi # Classify entries by DEVTYPE @@ -156,10 +156,8 @@ if [ -z "$install_disk" ]; then rm $file; done - has_wwn=0 - has_path=0 - file_pre="" disk_data="" + disk_rank="" # Check disks which had installed OS, or check all disks in /proc/partitions for disk in $disks; do @@ -177,59 +175,51 @@ if [ -z "$install_disk" ]; then echo "[get_install_disk] disk_path=$disk_path" echo "[get_install_disk] disk_driver=$disk_driver" - # Check whether there is WWN, PATH information + # 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 - has_wwn=1 - file_pre="wwn" + disk_rank="0" disk_data=$disk_wwn - elif [ $has_wwn -eq 1 ]; then - echo "[get_install_disk] The disk $disk has no wwn info." - echo "[get_install_disk] There is another disk with wwn info, so don't record this disk." - continue; elif [ "$disk_path" ]; then - has_path=1 - file_pre="path" + disk_rank="1" disk_data=$disk_path - elif [ $has_path -eq 1 ]; then - echo "[get_install_disk] The disk $disk has no wwn or path info." - echo "[get_install_disk] There is another disk with path info, so don't record this disk." - continue; else - file_pre="other" - disk_data="" + disk_rank="2" + disk_data="" fi # Sort disks by DRIVER type case "$disk_driver" in "ata_piix"*|"ahci") - echo "$disk $disk_data" >> "$tmpfile""$file_pre""firstchoicedisks" - echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre firstchoicedisks" + 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_data" >> "$tmpfile""$file_pre""secondchoicedisks" - echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre secondchoicedisks" + 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_data" >> "$tmpfile""$file_pre""thirdchoicedisks" - echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre thirdchoicedisks" + echo "$disk $disk_rank$disk_data" >> "$tmpfile""thirdchoicedisks" + echo "[get_install_disk] Add disk: $disk $disk_data into thirdchoicedisks" ;; *) - echo "$disk $disk_data" >> "$tmpfile""$file_pre""fourthchoicedisks" - echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre fourthchoicedisks" + 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$file_pre${seq}choicedisks ]; then - install_file="$tmpfile$file_pre${seq}choicedisks" + 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 sorting $file_pre and DRIVER." + echo "[get_install_disk]The install_disk is $install_disk by DRIVER, then by identifier." fi for file in $tmpfile*; do diff --git a/xCAT-test/autotest/testcase/get_install_disk/fresh_install_disk b/xCAT-test/autotest/testcase/get_install_disk/fresh_install_disk index c75af50c8..8d7756a5e 100644 --- a/xCAT-test/autotest/testcase/get_install_disk/fresh_install_disk +++ b/xCAT-test/autotest/testcase/get_install_disk/fresh_install_disk @@ -56,11 +56,11 @@ check:output=~0x500a0751036d9e61 check:output=~0x500a0751036d9e83 check:output=~0x500a0751036d9e7a check:output=~0x500a0751036d9c24 -cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "into wwn thirdchoicedisks" +cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "into thirdchoicedisks" check:output=~sda 0x500a0751036d9e61 check:output=~sdb 0x500a0751036d9c24 check:output=~sdc 0x500a0751036d9e7a check:output=~sdd 0x500a0751036d9e83 -cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "by sorting wwn and DRIVER" +cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "by DRIVER, then by identifier" check:output=~sdb end diff --git a/xCAT-test/autotest/testcase/get_install_disk/reinstall_disk b/xCAT-test/autotest/testcase/get_install_disk/reinstall_disk index 8e096114f..dc3b3b396 100644 --- a/xCAT-test/autotest/testcase/get_install_disk/reinstall_disk +++ b/xCAT-test/autotest/testcase/get_install_disk/reinstall_disk @@ -35,7 +35,7 @@ check:rc==0 check:output=~booted cmd:xdsh $$CN "scp /var/log/xcat/xcat.log root@$$MN:/tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_before_re_$$NO" -cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "by sorting wwn and DRIVER" +cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "by DRIVER, then by identifier" check:output=~sdb cmd:chdef $$CN status= @@ -72,9 +72,9 @@ cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep " check:output=~The disk sdb information cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "disk_wwn=" check:output=~0x500a0751036d9c24 -cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "into wwn" -check:output=~sdb 0x500a0751036d9c24 into wwn -cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "by sorting wwn and DRIVER" +cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "0x500a0751036d9c24 into" +check:output=~sdb 0x500a0751036d9c24 into +cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "by DRIVER, then by identifier" check:output=~sdb end diff --git a/xCAT-test/unit/getinstdisk_selection.t b/xCAT-test/unit/getinstdisk_selection.t index cb4dfa55d..00f040548 100644 --- a/xCAT-test/unit/getinstdisk_selection.t +++ b/xCAT-test/unit/getinstdisk_selection.t @@ -55,6 +55,7 @@ sub run_scenario { my %attr = %{ $disk{$name} }; open( my $props, '>', "$fixdir/$name.props" ) or die $!; print $props "ID_WWN=$attr{wwn}\n" if $attr{wwn}; + print $props "DEVPATH=$attr{path}\n" if $attr{path}; print $props "DEVTYPE=disk\n"; close($props); open( my $attrs, '>', "$fixdir/$name.attrs" ) or die $!; @@ -130,6 +131,40 @@ selects( '/dev/nvme0n1', 'an NVMe device is selected from the last group', # No usable disk falls back to the documented default. selects( '/dev/sda', 'no disks fall back to the default' ); +# The driver group decides before the identifier. A disk that reports no WWN +# used to be dropped when another disk reported one, or to be ignored because +# the readback only opened the files of the last identifier class seen. +selects( '/dev/sdb', 'the direct attached disk wins when only the RAID volume reports a WWN', + sda => { driver => 'megaraid_sas', wwn => '0x5000cca0aaaa0001' }, + sdb => { driver => 'ahci' } ); + +selects( '/dev/sda', 'the direct attached disk wins when it is scanned first without a WWN', + sda => { driver => 'ahci' }, + sdb => { driver => 'megaraid_sas', wwn => '0x5000cca0aaaa0002' } ); + +# Within one driver group the identifier decides, and a disk that reports one +# is preferred, because that name is stable across reboots. +selects( '/dev/sdb', 'the disk with a WWN wins inside the group', + sda => { driver => 'ahci' }, + sdb => { driver => 'ahci', wwn => '0x5000cca0bbbb0001' } ); + +selects( '/dev/sdb', 'the lower WWN wins inside the group', + sda => { driver => 'ahci', wwn => '0x5000cca0bbbb0002' }, + sdb => { driver => 'ahci', wwn => '0x5000cca0bbbb0001' } ); + +selects( '/dev/sda', 'a path is preferred over no identifier at all', + sda => { driver => 'ahci', path => '/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda' }, + sdb => { driver => 'ahci' } ); + +# A Xen guest presents xvd names. The scan has to see them, because the +# fallback below it would take the first one without looking. +selects( '/dev/xvda', 'a Xen disk is scanned rather than assumed', + xvda => { driver => 'vbd' } ); + +selects( '/dev/xvdb', 'the better driver group wins among Xen disks', + xvda => { driver => 'vbd' }, + xvdb => { driver => 'ahci' } ); + # Every installer includes the one script, which carries the fallbacks and the # logging that the separate RHEL 10 copy used to hold on its own. my $common = slurp( $scripts[0] );