mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-08-26 00:26:40 +00:00
Merge pull request #7740 from VersatusHPC/fix/getinstdisk-modern-devices
fix(getinstdisk): rank direct attached disks ahead of RAID volumes
This commit is contained in:
@@ -201,22 +201,26 @@ if [ -z "$install_disk" ]; then
|
||||
|
||||
# Sort disks by DRIVER type
|
||||
case "$disk_driver" in
|
||||
"ata_piix"*|"PMC MaxRAID"|"ahci"|"megaraid_sas")
|
||||
"ata_piix"*|"ahci")
|
||||
echo "$disk $disk_data" >> "$tmpfile""$file_pre""firstchoicedisks"
|
||||
echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre firstchoicedisks"
|
||||
;;
|
||||
"mptsas"|"mpt2sas"|"mpt3sas")
|
||||
"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"
|
||||
;;
|
||||
*)
|
||||
"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_data" >> "$tmpfile""$file_pre""fourthchoicedisks"
|
||||
echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre fourthchoicedisks"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for seq in first second third; do
|
||||
for seq in first second third fourth; do
|
||||
if [ -s $tmpfile$file_pre${seq}choicedisks ]; then
|
||||
install_file="$tmpfile$file_pre${seq}choicedisks"
|
||||
break
|
||||
|
||||
@@ -201,22 +201,26 @@ if [ -z "$install_disk" ]; then
|
||||
|
||||
# Sort disks by DRIVER type
|
||||
case "$disk_driver" in
|
||||
"ata_piix"*|"PMC MaxRAID"|"ahci"|"megaraid_sas")
|
||||
"ata_piix"*|"ahci")
|
||||
echo "$disk $disk_data" >> "$tmpfile""$file_pre""firstchoicedisks"
|
||||
echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre firstchoicedisks"
|
||||
;;
|
||||
"mptsas"|"mpt2sas"|"mpt3sas")
|
||||
"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"
|
||||
;;
|
||||
*)
|
||||
"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_data" >> "$tmpfile""$file_pre""fourthchoicedisks"
|
||||
echo "[get_install_disk] Add disk: $disk $disk_data into $file_pre fourthchoicedisks"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for seq in first second third; do
|
||||
for seq in first second third fourth; do
|
||||
if [ -s $tmpfile$file_pre${seq}choicedisks ]; then
|
||||
install_file="$tmpfile$file_pre${seq}choicedisks"
|
||||
break
|
||||
|
||||
@@ -56,7 +56,7 @@ 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 secondchoicedisks"
|
||||
cmd:cat /tmp/__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__fr_$$NO | grep "into wwn thirdchoicedisks"
|
||||
check:output=~sda 0x500a0751036d9e61
|
||||
check:output=~sdb 0x500a0751036d9c24
|
||||
check:output=~sdc 0x500a0751036d9e7a
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use FindBin;
|
||||
use File::Spec;
|
||||
use File::Temp qw(tempdir);
|
||||
use Test::More;
|
||||
|
||||
my $repo_root = File::Spec->catdir( $FindBin::Bin, '..', '..' );
|
||||
my $script_dir = File::Spec->catdir( $repo_root, 'xCAT-server', 'share', 'xcat', 'install', 'scripts' );
|
||||
|
||||
# The RHEL 10 installer includes its own copy of the script, so both carry the
|
||||
# same selection order and both are exercised here.
|
||||
my @scripts = map { File::Spec->catfile( $script_dir, $_ ) } qw(getinstdisk getinstdisk.rhels10);
|
||||
plan skip_all => 'getinstdisk not found' if grep { !-r $_ } @scripts;
|
||||
our $script;
|
||||
|
||||
sub slurp {
|
||||
open( my $fh, '<', $_[0] ) or die "Unable to read $_[0]: $!";
|
||||
my $c = do { local $/; <$fh> };
|
||||
close($fh);
|
||||
return $c;
|
||||
}
|
||||
|
||||
# The script reads /proc/partitions and writes under /tmp, so each scenario
|
||||
# runs a copy with those paths moved into its own sandbox, and a stub udevadm
|
||||
# serves the device properties from fixture files.
|
||||
sub run_scenario {
|
||||
my (%disk) = @_;
|
||||
my $sandbox = tempdir( CLEANUP => 1 );
|
||||
my $fixdir = "$sandbox/fix";
|
||||
my $bindir = "$sandbox/bin";
|
||||
mkdir $fixdir;
|
||||
mkdir $bindir;
|
||||
|
||||
my $body = slurp($script);
|
||||
$body =~ s{/proc/partitions}{$sandbox/partitions}g;
|
||||
$body =~ s{/tmp/xcat\.install_disk}{$sandbox/xcat.install_disk}g;
|
||||
$body =~ s{/tmp/xcat\.getinstalldisk}{$sandbox/xcat.getinstalldisk}g;
|
||||
$body =~ s{/dev/md/Volume0}{$sandbox/md/Volume0}g;
|
||||
$body =~ s{"/dev/xvda"}{"$sandbox/xvda"}g;
|
||||
open( my $sh, '>', "$sandbox/getinstdisk" ) or die $!;
|
||||
print $sh $body;
|
||||
close($sh);
|
||||
|
||||
open( my $parts, '>', "$sandbox/partitions" ) or die $!;
|
||||
print $parts "major minor #blocks name\n\n";
|
||||
my $minor = 0;
|
||||
for my $name ( sort keys %disk ) {
|
||||
printf $parts " 8 %5d 524288000 %s\n", $minor++, $name;
|
||||
}
|
||||
close($parts);
|
||||
|
||||
for my $name ( sort keys %disk ) {
|
||||
my %attr = %{ $disk{$name} };
|
||||
open( my $props, '>', "$fixdir/$name.props" ) or die $!;
|
||||
print $props "ID_WWN=$attr{wwn}\n" if $attr{wwn};
|
||||
print $props "DEVTYPE=disk\n";
|
||||
close($props);
|
||||
open( my $attrs, '>', "$fixdir/$name.attrs" ) or die $!;
|
||||
print $attrs qq{ ATTRS{size}=="1024000000"\n};
|
||||
print $attrs qq{ DRIVERS=="$attr{driver}"\n} if $attr{driver};
|
||||
my @models = $attr{models} ? @{ $attr{models} } : ( $attr{model} ? $attr{model} : () );
|
||||
print $attrs qq{ ATTRS{model}=="$_"\n} for @models;
|
||||
close($attrs);
|
||||
}
|
||||
|
||||
open( my $udev, '>', "$bindir/udevadm" ) or die $!;
|
||||
print $udev <<'UDEV';
|
||||
#!/bin/sh
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
--name=*) name=${a#--name=} ;;
|
||||
esac
|
||||
done
|
||||
name=${name#/dev/}
|
||||
case "$*" in
|
||||
*--query=property*) cat "$FIXDIR/$name.props" 2>/dev/null ;;
|
||||
*--attribute-walk*) cat "$FIXDIR/$name.attrs" 2>/dev/null ;;
|
||||
esac
|
||||
exit 0
|
||||
UDEV
|
||||
close($udev);
|
||||
chmod 0755, "$bindir/udevadm";
|
||||
|
||||
local $ENV{FIXDIR} = $fixdir;
|
||||
local $ENV{PATH} = "$bindir:$ENV{PATH}";
|
||||
local $ENV{MASTER_IP} = '';
|
||||
system("sh $sandbox/getinstdisk >$sandbox/log 2>&1");
|
||||
my $chosen = -r "$sandbox/xcat.install_disk" ? slurp("$sandbox/xcat.install_disk") : '';
|
||||
chomp $chosen;
|
||||
return $chosen;
|
||||
}
|
||||
|
||||
# Every scenario asserts against both copies of the script.
|
||||
sub selects {
|
||||
my ( $expected, $name, %disk ) = @_;
|
||||
for my $candidate (@scripts) {
|
||||
local $script = $candidate;
|
||||
my $variant = ( File::Spec->splitpath($candidate) )[2];
|
||||
is( run_scenario(%disk), $expected, "$name ($variant)" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
# A direct attached disk wins over a RAID volume when both are present. The
|
||||
# RAID volume sorts first by name, so the choice comes from the driver group.
|
||||
selects( '/dev/sdb', 'the direct attached disk wins over the RAID volume',
|
||||
sda => { driver => 'megaraid_sas' },
|
||||
sdb => { driver => 'ahci' } );
|
||||
|
||||
# A server with only RAID volumes still selects one.
|
||||
selects( '/dev/sda', 'a RAID volume is selected when nothing better exists',
|
||||
sda => { driver => 'megaraid_sas' } );
|
||||
|
||||
# A SAS host adapter loses to a direct attached disk, and still wins over a
|
||||
# driver with no group of its own.
|
||||
selects( '/dev/sdb', 'the direct attached disk wins over the host adapter',
|
||||
sda => { driver => 'mpt3sas' },
|
||||
sdb => { driver => 'ahci' } );
|
||||
|
||||
selects( '/dev/sda', 'the host adapter wins over an unknown driver',
|
||||
sda => { driver => 'mpt3sas' },
|
||||
sdb => { driver => 'virtio_blk' } );
|
||||
|
||||
# A driverless NVMe device still gets selected from the last group.
|
||||
selects( '/dev/nvme0n1', 'an NVMe device is selected from the last group',
|
||||
nvme0n1 => {} );
|
||||
|
||||
# No usable disk falls back to the documented default.
|
||||
selects( '/dev/sda', 'no disks fall back to the default' );
|
||||
|
||||
done_testing();
|
||||
Reference in New Issue
Block a user