diff --git a/xCAT-genesis-scripts/usr/sbin/loadmlxeth b/xCAT-genesis-scripts/usr/sbin/loadmlxeth index 3cb42b14d..d849d2a35 100755 --- a/xCAT-genesis-scripts/usr/sbin/loadmlxeth +++ b/xCAT-genesis-scripts/usr/sbin/loadmlxeth @@ -1,2 +1,12 @@ #!/bin/sh -/sbin/modprobe mlx4_en + +load_mellanox_ethernet() +{ + xcat_modprobe=$1 + xcat_mlx_status=1 + "$xcat_modprobe" mlx4_en && xcat_mlx_status=0 + "$xcat_modprobe" mlx5_core && xcat_mlx_status=0 + return "$xcat_mlx_status" +} + +load_mellanox_ethernet "${1:-/sbin/modprobe}" diff --git a/xCAT-server/share/xcat/netboot/imgutils/imgutils.pm b/xCAT-server/share/xcat/netboot/imgutils/imgutils.pm index 903baf453..af1610b27 100644 --- a/xCAT-server/share/xcat/netboot/imgutils/imgutils.pm +++ b/xCAT-server/share/xcat/netboot/imgutils/imgutils.pm @@ -7,6 +7,7 @@ use strict; use warnings "all"; use File::Basename; +use File::Find; use File::Path; use Cwd qw(realpath); use xCAT::SvrUtils; @@ -211,4 +212,134 @@ sub get_package_names { return %pkgnames; } +sub default_net_drivers { + my ( $family, $arch ) = @_; + + my %drivers = ( + rh => { + x86 => [qw(tg3 bnx2 bnx2x e1000 e1000e igb mlx_en mlx5_core virtio_net be2net)], + x86_64 => [qw(tg3 bnx2 bnx2x e1000 e1000e igb mlx_en mlx5_core virtio_net be2net)], + aarch64 => [qw(tg3 bnx2 bnx2x e1000e igb mlx_en mlx5_core virtio_net)], + ppc64 => [qw(e1000 e1000e igb ibmveth ehea)], + s390x => [qw(qdio ccwgroup)], + }, + sles => { + x86 => [qw(tg3 bnx2 bnx2x e1000 e1000e virtio_net virtio_balloon igb mlx4_en mlx5_core be2net)], + x86_64 => [qw(tg3 bnx2 bnx2x e1000 e1000e virtio_net virtio_balloon igb mlx4_en mlx5_core be2net)], + ppc64 => [qw(tg3 e1000 e1000e igb ibmveth ehea be2net)], + s390x => [qw(qdio ccwgroup qeth qeth_l2 qeth_l3)], + }, + ubuntu => { + x86 => [qw(tg3 bnx2 bnx2x e1000 e1000e igb mlx_en mlx5_core virtio_net overlay)], + x86_64 => [qw(tg3 bnx2 bnx2x e1000 e1000e igb mlx_en mlx5_core virtio_net overlay)], + ppc64el => [qw(tg3 bnx2 bnx2x e1000 e1000e igb ibmveth ehea mlx_en mlx4_en mlx5_core virtio_net overlay)], + ppc64 => [qw(e1000 e1000e igb ibmveth ehea)], + s390x => [qw(qdio ccwgroup)], + }, + ); + + return () if !exists($drivers{$family}) || !exists($drivers{$family}{$arch}); + return @{ $drivers{$family}{$arch} }; +} + +sub _kernel_module_name { + my $path = shift; + my $name = basename($path); + + $name =~ s/\.ko(?:\.(?:gz|xz|zst))?$//x; + $name =~ tr/-/_/; + return $name; +} + +sub target_kernel_module_availability { + my ( $rootimg_dir, $kernelver, @modules ) = @_; + my %requested = map { _kernel_module_name($_) => 1 } @modules; + my %available = map { $_ => 0 } keys %requested; + my $module_root = "$rootimg_dir/lib/modules/$kernelver"; + + my $modules_dep = "$module_root/modules.dep"; + if (open(my $dep_fh, '<', $modules_dep)) { + while (my $line = <$dep_fh>) { + my ($path) = split /:/x, $line, 2; + my $name = _kernel_module_name($path); + if ($requested{$name} && -f "$module_root/$path") { + $available{$name} = 1; + } + } + close($dep_fh); + } + + my $modules_builtin = "$module_root/modules.builtin"; + if (open(my $builtin_fh, '<', $modules_builtin)) { + while (my $path = <$builtin_fh>) { + chomp($path); + my $name = _kernel_module_name($path); + $available{$name} = 1 if $requested{$name}; + } + close($builtin_fh); + } + + if (-d $module_root && grep { !$available{$_} } keys %requested) { + find( + { + no_chdir => 1, + wanted => sub { + return if !-f $File::Find::name; + return if $File::Find::name !~ /\.ko(?:\.(?:gz|xz|zst))?$/x; + my $name = _kernel_module_name($File::Find::name); + $available{$name} = 1 if $requested{$name}; + }, + }, + $module_root, + ); + } + + return %available; +} + +sub resolve_mellanox_default_net_drivers { + my ( $rootimg_dir, $kernelver, $requested_drivers, @default_drivers ) = @_; + my @drivers; + my %seen; + my $has_mellanox_drivers = grep { + _kernel_module_name($_) =~ /^mlx(?:_en|4_en|5_core)$/x + } (@{$requested_drivers}, @default_drivers); + if (!$has_mellanox_drivers) { + return grep { !$seen{$_}++ } (@{$requested_drivers}, @default_drivers); + } + + my %available = target_kernel_module_availability( + $rootimg_dir, + $kernelver, + qw(mlx_en mlx4_en mlx5_core), + ); + + # Keep unavailable explicit requests, except for the historical mlx4 alias. + foreach my $driver (@{$requested_drivers}) { + my $name = _kernel_module_name($driver); + if ($name eq 'mlx_en' + && !$available{'mlx_en'} + && $available{'mlx4_en'}) + { + $driver =~ s/mlx_en/mlx4_en/; + } + push @drivers, $driver; + } + + foreach my $driver (@default_drivers) { + my $name = _kernel_module_name($driver); + if ($name eq 'mlx_en') { + if (!$available{'mlx_en'}) { + next if !$available{'mlx4_en'}; + $driver =~ s/mlx_en/mlx4_en/; + } + } elsif ($name eq 'mlx4_en' || $name eq 'mlx5_core') { + next if !$available{$name}; + } + push @drivers, $driver; + } + + return grep { !$seen{$_}++ } @drivers; +} + 1; diff --git a/xCAT-server/share/xcat/netboot/rh/genimage b/xCAT-server/share/xcat/netboot/rh/genimage index 9e3ba2409..e556dd602 100755 --- a/xCAT-server/share/xcat/netboot/rh/genimage +++ b/xCAT-server/share/xcat/netboot/rh/genimage @@ -293,6 +293,7 @@ unless ($osver and $profile) { } my @ndrivers; +my @default_ndrivers = imgutils::default_net_drivers('rh', $arch); if ($netdriver) { foreach (split /,/, $netdriver) { if (/^allupdate$/) { @@ -310,18 +311,7 @@ if ($netdriver) { } } -# Add the default driver list -if ($arch eq 'x86' or $arch eq 'x86_64') { - push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; -} elsif ($arch eq 'aarch64') { - push @ndrivers, qw/tg3 bnx2 bnx2x e1000e igb mlx_en virtio_net/; -} elsif ($arch eq 'ppc64') { - push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; -} elsif ($arch eq 's390x') { - push @ndrivers, qw/qdio ccwgroup/; -} - -foreach (@ndrivers) { +foreach (@ndrivers, @default_ndrivers) { unless (/\.ko$/) { s/$/.ko/; } @@ -744,6 +734,12 @@ if (-e "$rootimg_dir/boot/vmlinux-$kernelver") { } # Load driver update disk, and copy them to the root image +@ndrivers = imgutils::resolve_mellanox_default_net_drivers( + $rootimg_dir, + $kernelver, + \@ndrivers, + @default_ndrivers, +); my @dd_drivers = &load_dd(); # Push the drivers into the @ndrivers base on the order @@ -759,11 +755,6 @@ if (@new_order) { @ndrivers = (@new_order, @ndrivers); } -if (-d "$rootimg_dir/lib/modules/$kernelver/kernel/drivers/net/ethernet/mellanox/mlx4") { - for (@ndrivers) { - s/mlx_en/mlx4_en/; - } -} open($moddeps, "<", "$rootimg_dir/lib/modules/$kernelver/modules.dep"); my @moddeps = <$moddeps>; my @checkdeps = @ndrivers; diff --git a/xCAT-server/share/xcat/netboot/sles/genimage b/xCAT-server/share/xcat/netboot/sles/genimage index 5d01e9ed8..a8dc6d611 100755 --- a/xCAT-server/share/xcat/netboot/sles/genimage +++ b/xCAT-server/share/xcat/netboot/sles/genimage @@ -187,6 +187,7 @@ unless ($osver and $profile) { exit 1; } my @ndrivers; +my @default_ndrivers = imgutils::default_net_drivers('sles', $arch); if ($netdriver) { foreach (split /,/, $netdriver) { @@ -210,16 +211,7 @@ if ($netdriver) { } } -# Add the default driver list -if ($arch eq 'x86' or $arch eq 'x86_64') { - push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e virtio_net virtio_balloon igb mlx4_en be2net/; -} elsif ($arch eq 'ppc64') { - push @ndrivers, qw/tg3 e1000 e1000e igb ibmveth ehea be2net/; -} elsif ($arch eq "s390x") { - push @ndrivers, qw/qdio ccwgroup qeth qeth_l2 qeth_l3/; -} - -foreach (@ndrivers) { +foreach (@ndrivers, @default_ndrivers) { unless (/\.ko$/) { s/$/.ko/; } @@ -921,6 +913,12 @@ unless (-e "$rootimg_dir/usr/bin/keyctl") { umount(); # Load driver update disk, and copy them to the root image +@ndrivers = imgutils::resolve_mellanox_default_net_drivers( + $rootimg_dir, + $kernelver, + \@ndrivers, + @default_ndrivers, +); my @dd_drivers = &load_dd(); # Push the drivers into the @ndrivers base on the order @@ -950,12 +948,6 @@ if ($osver_host >= 12) { push @ndrivers, ("ibmvscsic.ko", "ata_piix.ko", "pcieport.ko"); } -if (-f "$rootimg_dir/lib/modules/$kernelver/kernel/drivers/net/ethernet/mellanox/mlx4/mlx4_en.ko") { - for (@ndrivers) { - s/mlx_en/mlx4_en/; - } -} - open($moddeps, "<", "$rootimg_dir/lib/modules/$kernelver/modules.dep"); my @moddeps = <$moddeps>; my @checkdeps = @ndrivers; diff --git a/xCAT-server/share/xcat/netboot/ubuntu/genimage b/xCAT-server/share/xcat/netboot/ubuntu/genimage index de9350a4f..fc1e58b96 100755 --- a/xCAT-server/share/xcat/netboot/ubuntu/genimage +++ b/xCAT-server/share/xcat/netboot/ubuntu/genimage @@ -193,20 +193,13 @@ unless ($osver and $profile) { } my @ndrivers; +my @default_ndrivers; if ($netdriver) { if (($updates{'netdrivers'} ne $netdriver) and ($tempfile)) { $updates{'netdrivers'} = $netdriver; } } else { - if ($arch eq 'x86' or $arch eq 'x86_64') { - @ndrivers = qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net overlay/; - } elsif ($arch eq 'ppc64el') { - @ndrivers = qw/tg3 bnx2 bnx2x e1000 e1000e igb ibmveth ehea mlx_en mlx4_en virtio_net overlay/; - } elsif ($arch eq 'ppc64') { - @ndrivers = qw/e1000 e1000e igb ibmveth ehea/; - } elsif ($arch eq 's390x') { - @ndrivers = qw/qdio ccwgroup/; - } + @default_ndrivers = imgutils::default_net_drivers('ubuntu', $arch); } foreach (split /,/, $netdriver) { unless (/\.ko$/) { @@ -216,7 +209,7 @@ foreach (split /,/, $netdriver) { push @ndrivers, $_; } -foreach (@ndrivers) { +foreach (@ndrivers, @default_ndrivers) { unless (/\.ko$/) { s/$/.ko/; } @@ -751,6 +744,12 @@ if (-e "$rootimg_dir/boot/vmlinux-$kernelver") { } # Load driver update disk, and copy them to the root image +@ndrivers = imgutils::resolve_mellanox_default_net_drivers( + $rootimg_dir, + $kernelver, + \@ndrivers, + @default_ndrivers, +); my @dd_drivers = &load_dd(); # Push the drivers into the @ndrivers base on the order