Code drop for the enhancement of driver enjection to initrd (port back from 2.8 branch) 1. support both stateful and stateless; 2. support to take drivers from osupdatedistro; 3. support the allupdate and updateonly in netdrivers attribute
This commit is contained in:
parent
b892b556d3
commit
b84251a03f
100
xCAT-client/pods/man1/geninitrd.1.pod
Normal file
100
xCAT-client/pods/man1/geninitrd.1.pod
Normal file
@ -0,0 +1,100 @@
|
||||
=head1 NAME
|
||||
|
||||
B<genimage> - Generate an initrd (initial ramfs) which to be used for statefull install or stateless netboot.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<geninitrd> <imagename>
|
||||
|
||||
B<geninitrd> [B<-h> | B<--help>]
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Generate the initrd for the osimage: B<imagename> which is an xCAT object of I<osimage> type.
|
||||
|
||||
B<Diskfull Osimage>
|
||||
|
||||
=over 2
|
||||
|
||||
If the B<imagename> is a statefull one (The provmethod attribute for the osimage is 'install'),
|
||||
this command is used to rebuild the initrd to inject the new drivers from driver rpms or
|
||||
'update distro' and copy the rebuilt initrd and new kernel (If there's new kernel in 'update
|
||||
distro') to the directory I</tftpboot/xcat/<imagename>>.
|
||||
|
||||
If the initrd has been rebuilt by geninitrd, when run nodeset, the I<--noupdateinitrd> option
|
||||
should be used to skip the rebuilding of initrd to improve the performance.
|
||||
|
||||
Three attributes of osimage object can be used to specify the Driver RPM location and Driver names
|
||||
for injecting new drviers to initrd.
|
||||
|
||||
B<netdrivers> - comma separated driver names that need to be injected to the initrd.
|
||||
The postfix '.ko' can be ignored. The netdrivers attribute must be set to specify the new driver list.
|
||||
If you want to load all the drivers from the driver rpms, using the keyword allupdate.
|
||||
|
||||
B<driverupdatesrc> - comma separated driver rpm packages (full path should be specified)
|
||||
|
||||
B<osupdatename> - comma separated 'osdistroupdate' object. Each 'osdistroupdate' object specifies a
|
||||
Linux distro update. When run geninitrd, 'kernel-*.rpm' will be searched from osdistroupdate.dirpath
|
||||
to get all the rpm packages and then search the drivers from the rpm packages.
|
||||
|
||||
Refer to the doc: https://sourceforge.net/apps/mediawiki/xcat/index.php?title=Using_Linux_Driver_Update_Disk
|
||||
|
||||
=back
|
||||
|
||||
B<Stateless Osimage>
|
||||
|
||||
=over 2
|
||||
|
||||
If the B<imagename> is a stateless one (The provmethod attribute for the osimage is 'netboot'),
|
||||
this command is used to generate the initrd from the rootimg which generated by 'genimage' command.
|
||||
So the 'genimage' must be run once before running the geninitrd command.
|
||||
|
||||
Two attributes of osimage object can be used to specify the Driver RPM location and Driver names
|
||||
for injecting new drviers to initrd.
|
||||
|
||||
B<netdrivers> - comma separated driver names that need to be injected to the initrd.
|
||||
The postfix '.ko' can be ignored. The netdrivers attribute must be set to specify the new driver list.
|
||||
If you want to load all the drivers from the driver rpms, using the keyword allupdate.
|
||||
|
||||
B<driverupdatesrc> - comma separated driver rpm packages (full path should be specified)
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 Parameters
|
||||
|
||||
I<imagename> specifies the name of an os image definition to be used. The specification for the image is storted in the I<osimage> table and I<linuximage> table.
|
||||
|
||||
|
||||
=head1 RETURN VALUE
|
||||
|
||||
0 The command completed successfully.
|
||||
|
||||
1 An error has occurred.
|
||||
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
=over 3
|
||||
|
||||
=item 1
|
||||
To generate initrd for the osimage B<myimagename>:
|
||||
|
||||
geninitrd myimagename
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 FILES
|
||||
|
||||
/opt/xcat/bin/geninitrd
|
||||
|
||||
/opt/xcat/bin/genimage
|
||||
|
||||
/opt/xcat/share/xcat/netboot/<OS>/genimage
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<geninitrd(1)|geninitrd.1>, L<genimage(1)|genimage.1>
|
@ -6,6 +6,8 @@ B<nodeset> - set the boot state for a noderange
|
||||
|
||||
B<nodeset> [I<noderange>] [I<boot>|I<install>|I<stat>|I<iscsiboot>|I<netboot>|I<statelite>|I<offline>|I<runcmd=bmcsetup>|I<osimage[=<imagename>>]]
|
||||
|
||||
B<nodeset> I<noderange> [I<osimage=<imagename>> I<--noupdateinitrd>]
|
||||
|
||||
B<nodeset> [I<-h>|I<--help>|I<-v>|I<--version>]
|
||||
|
||||
=head1 B<Description>
|
||||
@ -67,6 +69,11 @@ Cleanup the current pxe/tftp boot configuration files for the nodes requested
|
||||
|
||||
Prepare server for installing a node using the specified os image. The os image is defined in the I<osimage> table and I<linuximage> table. If the <imagename> is omitted, the os image name will be obtained from I<nodetype.provmethod> for the node.
|
||||
|
||||
=item B<--noupdateinitrd>
|
||||
|
||||
Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drviers to initrd. But, the geninitrd command
|
||||
should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of nodeset command.
|
||||
|
||||
=item B<runimage>=<task>>
|
||||
|
||||
If you would like to run a task after deployment, you can define that task with this attribute.
|
||||
|
@ -172,6 +172,7 @@ sub mknetboot
|
||||
my $nodes = @{$req->{node}};
|
||||
my @args = @{$req->{arg}} if(exists($req->{arg}));
|
||||
my @nodes = @{$req->{node}};
|
||||
my $noupdateinitrd = $req->{'noupdateinitrd'};
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
#my $sitetab = xCAT::Table->new('site');
|
||||
my $linuximagetab;
|
||||
@ -520,7 +521,7 @@ sub mknetboot
|
||||
}
|
||||
}
|
||||
|
||||
if ($docopy) {
|
||||
if ($docopy && !$noupdateinitrd) {
|
||||
mkpath("$tftppath");
|
||||
if (-f "$rootimgdir/hypervisor") {
|
||||
copy("$rootimgdir/hypervisor", "$tftppath");
|
||||
@ -1576,7 +1577,8 @@ sub mksysclone
|
||||
}
|
||||
}
|
||||
|
||||
# copy postscripts
|
||||
# copy postscripts, the xCAT scripts may update, but the image is captured long time ago
|
||||
# should update the scripts at each nodeset
|
||||
my $script1 = "configefi";
|
||||
my $script2 = "updatenetwork";
|
||||
my $pspath = "$installroot/sysclone/scripts/post-install/";
|
||||
@ -2428,6 +2430,7 @@ sub insert_dd {
|
||||
my @rpm_list;
|
||||
my @driver_list;
|
||||
my $Injectalldriver;
|
||||
my $updatealldriver;
|
||||
|
||||
my @rpm_drivers;
|
||||
|
||||
@ -2472,6 +2475,9 @@ sub insert_dd {
|
||||
if (/^allupdate$/) {
|
||||
$Injectalldriver = 1;
|
||||
next;
|
||||
} elsif (/^updateonly$/) {
|
||||
$updatealldriver = 1;
|
||||
next;
|
||||
}
|
||||
unless (/\.ko$/) {
|
||||
s/$/.ko/;
|
||||
@ -2482,7 +2488,7 @@ sub insert_dd {
|
||||
chomp(@dd_list);
|
||||
chomp(@rpm_list);
|
||||
|
||||
unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) {
|
||||
unless (@dd_list || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
|
||||
return ();
|
||||
}
|
||||
|
||||
@ -2493,7 +2499,7 @@ sub insert_dd {
|
||||
# dracut + drvier rpm
|
||||
# !dracut + driver rpm
|
||||
# !dracut + driver disk
|
||||
if (!<$install_dir/$os/$arch/Packages/dracut*> || (@rpm_list && ($Injectalldriver || @driver_list))) {
|
||||
if (!<$install_dir/$os/$arch/Packages/dracut*> || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
|
||||
mkpath "$dd_dir/initrd_img"; # The dir for the new initrd
|
||||
|
||||
# unzip the initrd image
|
||||
@ -2512,19 +2518,26 @@ sub insert_dd {
|
||||
} elsif ( grep (/LZMA compressed data/, @format)) {
|
||||
$initrdfmt = "lzma";
|
||||
} else {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Could not handle the format of the initrd.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return ();
|
||||
# check whether it can be handled by xz
|
||||
$cmd = "xz -t $img";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Could not handle the format of the initrd.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return ();
|
||||
} else {
|
||||
$initrdfmt = "lzma";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($initrdfmt eq "gzip") {
|
||||
$cmd = "gunzip -c $img > $dd_dir/initrd";
|
||||
} elsif ($initrdfmt eq "lzma") {
|
||||
if (! -x "/usr/bin/lzma") {
|
||||
if (! -x "/usr/bin/xz") {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "The format of initrd for the target node is \'lzma\', but this management node has not lzma command.";
|
||||
push @{$rsp->{data}}, "The format of initrd for the target node is \'lzma\', but this management node has not xz command.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return ();
|
||||
}
|
||||
@ -2549,13 +2562,12 @@ sub insert_dd {
|
||||
}
|
||||
|
||||
my $new_kernel_ver;
|
||||
if (@rpm_list && ($Injectalldriver || @driver_list)) {
|
||||
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
|
||||
# Extract the files from rpm to the tmp dir
|
||||
mkpath "$dd_dir/rpm";
|
||||
foreach my $rpm (@rpm_list) {
|
||||
if (-r $rpm) {
|
||||
$cmd = "cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum";
|
||||
#$cmd = "rpm -i --quiet --nodeps --force --ignorearch --ignoreos --nosignature --root $dd_dir/rpm $rpm";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
@ -2572,17 +2584,17 @@ sub insert_dd {
|
||||
# and copy it to the /tftpboot
|
||||
my @new_kernels = <$dd_dir/rpm/boot/vmlinuz*>;
|
||||
foreach my $new_kernel (@new_kernels) {
|
||||
if (-r $new_kernel && $new_kernel =~ /\/vmlinuz-(.*(x86_64|ppc64))$/) {
|
||||
$new_kernel_ver = $1;
|
||||
$cmd = "/bin/mv -f $new_kernel $kernelpath";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $kernelpath.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
if (-r $new_kernel && $new_kernel =~ /\/vmlinuz-(.*(x86_64|ppc64|el\d+))$/) {
|
||||
$new_kernel_ver = $1;
|
||||
$cmd = "/bin/mv -f $new_kernel $kernelpath";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $kernelpath.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver
|
||||
# Change it back to xxx.ko here
|
||||
@ -2613,7 +2625,7 @@ sub insert_dd {
|
||||
# For dracut mode, only copy the drivers from rpm packages to the /lib/modules/<kernel>
|
||||
# The driver disk will be handled that append the whole disk to the orignial initrd
|
||||
|
||||
if (@rpm_list && ($Injectalldriver || @driver_list)) {
|
||||
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
|
||||
# Copy the firmware to the rootimage
|
||||
if (-d "$dd_dir/rpm/lib/firmware") {
|
||||
if (! -d "$dd_dir/initrd_img/lib/firmware") {
|
||||
@ -2628,14 +2640,15 @@ sub insert_dd {
|
||||
}
|
||||
}
|
||||
|
||||
# if the new kernel from update distro is not existed in initrd, copy all the modules for the new kernel to initrd
|
||||
if ((! -r "$dd_dir/initrd_img/lib/modules/$new_kernel_ver") && (-r "$dd_dir/rpm/lib/modules/$new_kernel_ver")) {
|
||||
$cmd = "/bin/cp -rf $dd_dir/rpm/lib/modules/$new_kernel_ver $dd_dir/initrd_img/lib/modules/";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not copy $dd_dir/rpm/lib/modules/$new_kernel_ver to $dd_dir/initrd_img/lib/modules.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
# get the name list for all drivers in the original initrd if 'netdrivers=updateonly'
|
||||
# then only the drivers in this list will be updated from the drvier rpms
|
||||
if ($updatealldriver) {
|
||||
$driver_name = "\*\.ko";
|
||||
@all_real_path = ();
|
||||
find(\&get_all_path, <$dd_dir/initrd_img/lib/modules/*>);
|
||||
foreach my $real_path (@all_real_path) {
|
||||
my $driver = basename($real_path);
|
||||
push @driver_list, $driver;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2643,9 +2656,19 @@ sub insert_dd {
|
||||
# Figure out the kernel version
|
||||
my @kernelpaths = <$dd_dir/initrd_img/lib/modules/*>;
|
||||
my @kernelvers;
|
||||
if ($new_kernel_ver) {
|
||||
push @kernelvers, $new_kernel_ver;
|
||||
}
|
||||
|
||||
# if new kernel is used, remove all the original kernel directories
|
||||
foreach (@kernelpaths) {
|
||||
if (basename($_) =~ /^[\d\.]+/) {
|
||||
push @kernelvers, basename($_);
|
||||
my $kernelv = basename($_);
|
||||
if ($kernelv =~ /^[\d\.]+/) {
|
||||
if ($new_kernel_ver) {
|
||||
rmtree ("$dd_dir/initrd_img/lib/modules/$kernelv");
|
||||
} else {
|
||||
push @kernelvers, $kernelv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2655,6 +2678,7 @@ sub insert_dd {
|
||||
}
|
||||
if (@driver_list) {
|
||||
foreach my $driver (@driver_list) {
|
||||
$driver =~ s/\.gz$//;
|
||||
$driver_name = $driver;
|
||||
@all_real_path = ();
|
||||
find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
|
||||
@ -2698,7 +2722,7 @@ sub insert_dd {
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not generate the depdency for the drivers in the initrd.";
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not generate the drivers depdency for $kernelver in the initrd.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
@ -2817,7 +2841,7 @@ sub insert_dd {
|
||||
}
|
||||
|
||||
# Merge the drviers from rpm packages to the initrd
|
||||
if (@rpm_list && ($Injectalldriver || @driver_list)) {
|
||||
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
|
||||
# Copy the firmware to the rootimage
|
||||
if (-d "$dd_dir/rpm/lib/firmware") {
|
||||
if (! -d "$dd_dir/initrd_img/lib") {
|
||||
@ -2837,18 +2861,44 @@ sub insert_dd {
|
||||
mkpath ("$dd_dir/modules/$new_kernel_ver/$arch/");
|
||||
}
|
||||
|
||||
# get the name list for all drivers in the original initrd if 'netdrivers=updateonly'
|
||||
# then only the drivers in this list will be updated from the drvier rpms
|
||||
if ($updatealldriver) {
|
||||
$driver_name = "\*\.ko";
|
||||
@all_real_path = ();
|
||||
find(\&get_all_path, <$dd_dir/modules/*>);
|
||||
foreach my $real_path (@all_real_path) {
|
||||
my $driver = basename($real_path);
|
||||
push @driver_list, $driver;
|
||||
}
|
||||
}
|
||||
|
||||
# Copy the drivers to the initrd
|
||||
# Figure out the kernel version
|
||||
my @kernelpaths = <$dd_dir/modules/*>;
|
||||
my @kernelvers;
|
||||
if ($new_kernel_ver) {
|
||||
push @kernelvers, $new_kernel_ver;
|
||||
}
|
||||
foreach (@kernelpaths) {
|
||||
push @kernelvers, basename($_);
|
||||
my $kernelv = basename($_);
|
||||
if ($kernelv =~ /^[\d\.]+/) {
|
||||
if ($new_kernel_ver) {
|
||||
rmtree ("$dd_dir/modules/$kernelv");
|
||||
} else {
|
||||
push @kernelvers, $kernelv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $kernelver (@kernelvers) {
|
||||
unless (-d "$dd_dir/rpm/lib/modules/$kernelver") {
|
||||
next;
|
||||
}
|
||||
# create path for the new kernel in the modules package
|
||||
unless (-d "$dd_dir/modules/$kernelver") {
|
||||
mkpath ("$dd_dir/modules/$kernelver/$arch/");
|
||||
}
|
||||
# find the $kernelver/$arch dir in the $dd_dir/modules
|
||||
my $arch4modules;
|
||||
foreach (<$dd_dir/modules/$kernelver/*>) {
|
||||
@ -2924,13 +2974,23 @@ sub insert_dd {
|
||||
if (-d $ma) {
|
||||
mkpath "$dd_dir/depmod/lib/modules/$mk";
|
||||
xCAT::Utils->runcmd("/bin/cp -rf $ma/* $dd_dir/depmod/lib/modules/$mk", -1);
|
||||
$cmd = "depmod -b $dd_dir/depmod/";
|
||||
$cmd = "depmod -b $dd_dir/depmod/ $mk";
|
||||
#$cmd = "depmod -b $dd_dir/depmod/";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not generate the depdency for the drivers in the initrd.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
# remove the .ko postfix from the driver name for rh5
|
||||
$cmd = "/bin/sed ".'s/\.ko//g'." $dd_dir/depmod/lib/modules/$mk/modules.dep > $dd_dir/depmod/lib/modules/$mk/modules.dep1; mv -f $dd_dir/depmod/lib/modules/$mk/modules.dep1 $dd_dir/depmod/lib/modules/$mk/modules.dep";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not generate the depdency for the drivers in the initrd.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
|
||||
if (-f "$dd_dir/depmod/lib/modules/$mk/modules.dep") {
|
||||
copy ("$dd_dir/depmod/lib/modules/$mk/modules.dep", "$dd_dir/initrd_img/modules/modules.dep");
|
||||
}
|
||||
@ -3004,7 +3064,7 @@ sub insert_dd {
|
||||
if ($initrdfmt eq "gzip") {
|
||||
$cmd = "cd $dd_dir/initrd_img; find .|cpio -H newc -o|gzip -9 -c - > $dd_dir/initrd.img";
|
||||
} elsif ($initrdfmt eq "lzma") {
|
||||
$cmd = "cd $dd_dir/initrd_img; find .|cpio -H newc -o|lzma -C crc32 -9 > $dd_dir/initrd.img";
|
||||
$cmd = "cd $dd_dir/initrd_img; find .|cpio -H newc -o|xz --format=lzma -C crc32 -9 > $dd_dir/initrd.img";
|
||||
}
|
||||
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
@ -3072,13 +3132,25 @@ sub insert_dd {
|
||||
|
||||
my $rsp;
|
||||
if (@dd_list) {
|
||||
push @{$rsp->{data}}, "Inserted the driver update disk:".join(',',@inserted_dd).".";
|
||||
push @{$rsp->{data}}, "The driver update disk:".join(',',@inserted_dd)." have been injected to initrd.";
|
||||
}
|
||||
if (@driver_list) {
|
||||
push @{$rsp->{data}}, "Inserted the drivers:".join(',', sort(@rpm_drivers))." from driver packages.";
|
||||
} elsif (@rpm_list && ($Injectalldriver || @driver_list)) {
|
||||
push @{$rsp->{data}}, "Inserted the drivers from driver packages:".join(',', sort(@rpm_list)).".";
|
||||
# remove the duplicated names
|
||||
my %dnhash;
|
||||
foreach (@rpm_drivers) {
|
||||
$dnhash{$_} = 1;
|
||||
}
|
||||
@rpm_drivers = keys %dnhash;
|
||||
|
||||
if (@rpm_list) {
|
||||
if (@rpm_drivers) {
|
||||
push @{$rsp->{data}}, "The drivers:".join(',', sort(@rpm_drivers))." from ".join(',', sort(@rpm_list))." have been injected to initrd.";
|
||||
} elsif ($Injectalldriver) {
|
||||
push @{$rsp->{data}}, "All the drivers from :".join(',', sort(@rpm_list))." have been injected to initrd.";
|
||||
} else {
|
||||
push @{$rsp->{data}}, "No driver was injected to initrd.";
|
||||
}
|
||||
}
|
||||
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
|
||||
return @inserted_dd;
|
||||
|
@ -10,6 +10,7 @@ use xCAT::SvrUtils;
|
||||
use xCAT::Table;
|
||||
#use Data::Dumper;
|
||||
use File::Path;
|
||||
use File::Copy;
|
||||
use Getopt::Long;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
@ -169,6 +170,7 @@ sub process_request {
|
||||
$otherpkglist = $ref_linuximage_tab->{'otherpkglist'};
|
||||
$postinstall_filename = $ref_linuximage_tab->{'postinstall'};
|
||||
$destdir = $ref_linuximage_tab->{'rootimgdir'};
|
||||
$rootimg_dir = $ref_linuximage_tab->{'rootimgdir'};
|
||||
$driverupdatesrc = $ref_linuximage_tab->{'driverupdatesrc'};
|
||||
|
||||
# TODO: how can we do if the user specifies one wrong value to the following attributes?
|
||||
@ -363,6 +365,31 @@ sub process_request {
|
||||
# print FILE "\n";
|
||||
#}
|
||||
#close FILE;
|
||||
|
||||
# update the generated initrd to /tftpboot/xcat so that don't need to rerun nodeset to update them
|
||||
if (($::RUNCMD_RC == 0) && $imagename) {
|
||||
my $tftpdir = "/tftpboot";
|
||||
my @siteents = xCAT::TableUtils->get_site_attribute("tftpdir");
|
||||
if ($#siteents >= 0)
|
||||
{
|
||||
$tftpdir = $siteents[0];
|
||||
}
|
||||
my $tftppath = "$tftpdir/xcat/osimage/$imagename";
|
||||
|
||||
my $installdir = "/install";
|
||||
@siteents = xCAT::TableUtils->get_site_attribute("installdir");
|
||||
if ($#siteents >= 0)
|
||||
{
|
||||
$installdir = $siteents[0];
|
||||
}
|
||||
|
||||
unless (-d $tftppath) {
|
||||
mkpath $tftppath;
|
||||
}
|
||||
copy("$rootimg_dir/initrd-stateless.gz", "$tftppath");
|
||||
copy("$rootimg_dir/initrd-statelite.gz", "$tftppath");
|
||||
copy("$rootimg_dir/kernel", "$tftppath");
|
||||
}
|
||||
|
||||
#parse the output and save the image data to osimage and linuximage table
|
||||
save_image_data($callback, $doreq, $tempfile);
|
||||
|
@ -7,6 +7,7 @@ BEGIN
|
||||
|
||||
use strict;
|
||||
use lib "$::XCATROOT/lib/perl";
|
||||
use File::Path;
|
||||
use File::Copy;
|
||||
use xCAT::MsgUtils;
|
||||
use xCAT::TableUtils;
|
||||
@ -25,8 +26,28 @@ sub preprocess_request
|
||||
my $req = shift;
|
||||
my $callback = shift;
|
||||
|
||||
unless (defined ($req->{arg}) && $req->{arg}->[0]) {
|
||||
xCAT::MsgUtils->message("E", {error=>["An osimage name needs to be specified."], errorcode=>["1"]}, $callback);
|
||||
my $usage = sub {
|
||||
my $callback = shift;
|
||||
xCAT::MsgUtils->message("I", {data=>["Usage: geninitrd <imagename> [-h | --help]"]}, $callback);
|
||||
};
|
||||
|
||||
my $osimage;
|
||||
if (defined ($req->{arg})) {
|
||||
foreach (@{$req->{arg}}) {
|
||||
if (/^-/) {
|
||||
$usage->($callback);
|
||||
return;
|
||||
}else {
|
||||
$osimage = $_;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$usage->($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
unless ($osimage) {
|
||||
$usage->($callback);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -45,10 +66,11 @@ sub process_request
|
||||
{
|
||||
my $req = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
|
||||
if ($req->{command}->[0] eq 'geninitrd')
|
||||
{
|
||||
return geninitrd($req, $callback);
|
||||
return geninitrd($req, $callback, $doreq);
|
||||
}
|
||||
|
||||
}
|
||||
@ -56,6 +78,7 @@ sub process_request
|
||||
sub geninitrd {
|
||||
my $req = shift;
|
||||
my $callback = shift;
|
||||
my $doreq = shift;
|
||||
|
||||
my $osimage = $req->{arg}->[0];
|
||||
|
||||
@ -68,7 +91,7 @@ sub geninitrd {
|
||||
return;
|
||||
}
|
||||
|
||||
my $oient = $osimagetab->getAttribs({imagename => $osimage}, 'osvers', 'osarch', 'osupdatename');
|
||||
my $oient = $osimagetab->getAttribs({imagename => $osimage}, 'provmethod', 'osvers', 'osarch', 'osupdatename');
|
||||
unless ($oient && $oient->{'osvers'} && $oient->{'osarch'} ) {
|
||||
xCAT::MsgUtils->message("E", {error=>["The osimage [$osimage] was not defined or [osvers, osarch] attributes were not set."], errorcode=>["1"]}, $callback);
|
||||
return;
|
||||
@ -83,7 +106,7 @@ sub geninitrd {
|
||||
return;
|
||||
}
|
||||
|
||||
my $lient = $linuximagetab->getAttribs({imagename => $osimage}, 'pkgdir', 'driverupdatesrc', 'netdrivers');
|
||||
my $lient = $linuximagetab->getAttribs({imagename => $osimage}, 'rootimgdir', 'pkgdir', 'driverupdatesrc', 'netdrivers');
|
||||
unless ($lient && $lient->{'pkgdir'}) {
|
||||
xCAT::MsgUtils->message("E", {error=>["The osimage [$osimage] was not defined or [pkgdir] attribute was not set."], errorcode=>["1"]}, $callback);
|
||||
return;
|
||||
@ -92,6 +115,27 @@ sub geninitrd {
|
||||
$driverupdatesrc = $lient->{'driverupdatesrc'};
|
||||
$netdrivers = $lient->{'netdrivers'};
|
||||
|
||||
# if the provmethod equals 'netboot', call the genimage --onlyinitrd directly
|
||||
if ($oient->{'provmethod'} && ($oient->{'provmethod'} eq "netboot" || $oient->{'provmethod'} eq "statelite")) {
|
||||
if ($lient->{'rootimgdir'}) {
|
||||
unless (-d $lient->{'rootimgdir'}."/rootimg/lib/modules") {
|
||||
xCAT::MsgUtils->message("E", {error=>["The genimage should be run before running geninitrd."], errorcode=>["1"]}, $callback);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
xCAT::MsgUtils->message("E", {error=>["The rootimgdir attribute for the osimage should be set."], errorcode=>["1"]}, $callback);
|
||||
return;
|
||||
}
|
||||
my @output = `genimage $osimage --onlyinitrd`;
|
||||
xCAT::MsgUtils->message("I", {data=>\@output}, $callback);
|
||||
#$doreq->({ command => ['genimage'],
|
||||
# arg => [$osimage, '--onlyinitrd'] }, $callback);
|
||||
return;
|
||||
} elsif (!$oient->{'provmethod'} || $oient->{'provmethod'} ne "install") {
|
||||
xCAT::MsgUtils->message("E", {error=>["The attribute [provmethod] for osimage [$osimage] must be set to install, netboot or statelite."], errorcode=>["1"]}, $callback);
|
||||
return;
|
||||
}
|
||||
|
||||
# get the path list of the osdistroupdate
|
||||
if ($oient->{'osupdatename'}) {
|
||||
my @osupdatenames = split (/,/, $oient->{'osupdatename'});
|
||||
@ -127,6 +171,9 @@ sub geninitrd {
|
||||
$tftpdir = $t_entry;
|
||||
}
|
||||
my $tftppath = "$tftpdir/xcat/osimage/$osimage";
|
||||
unless (-d $tftppath) {
|
||||
mkpath $tftppath;
|
||||
}
|
||||
if ($arch =~ /x86/) {
|
||||
if ($osvers =~ /(^ol[0-9].*)|(centos.*)|(rh.*)|(fedora.*)|(SL.*)/) {
|
||||
$kernelpath = "$tftppath/vmlinuz";
|
||||
|
@ -55,6 +55,7 @@ sub mknetboot
|
||||
my $globaltftpdir = "/tftpboot";
|
||||
my $nodes = @{$req->{node}};
|
||||
my @nodes = @{$req->{node}};
|
||||
my $noupdateinitrd = $req->{'noupdateinitrd'};
|
||||
my $ostab = xCAT::Table->new('nodetype');
|
||||
#my $sitetab = xCAT::Table->new('site');
|
||||
my $linuximagetab;
|
||||
@ -404,7 +405,7 @@ sub mknetboot
|
||||
}
|
||||
}
|
||||
|
||||
if ($docopy) {
|
||||
if ($docopy && !$noupdateinitrd) {
|
||||
mkpath("$tftppath");
|
||||
copy("$rootimgdir/kernel", "$tftppath");
|
||||
if ($statelite) {
|
||||
@ -1689,6 +1690,7 @@ sub insert_dd () {
|
||||
my @rpm_list;
|
||||
my @driver_list;
|
||||
my $Injectalldriver;
|
||||
my $updatealldriver;
|
||||
|
||||
my @rpm_drivers;
|
||||
|
||||
@ -1734,6 +1736,9 @@ sub insert_dd () {
|
||||
if (/^allupdate$/) {
|
||||
$Injectalldriver = 1;
|
||||
next;
|
||||
} elsif (/^updateonly$/) {
|
||||
$updatealldriver = 1;
|
||||
next;
|
||||
}
|
||||
unless (/\.ko$/) {
|
||||
s/$/.ko/;
|
||||
@ -1744,7 +1749,7 @@ sub insert_dd () {
|
||||
chomp(@dd_list);
|
||||
chomp(@rpm_list);
|
||||
|
||||
unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) {
|
||||
unless (@dd_list || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
|
||||
return ();
|
||||
}
|
||||
|
||||
@ -1757,7 +1762,7 @@ sub insert_dd () {
|
||||
# Unzip the original initrd
|
||||
# This only needs to be done for ppc or handling the driver rpm
|
||||
# For the driver disk against x86, append the driver disk to initrd directly
|
||||
if ($arch =~/ppc/ || (@rpm_list && ($Injectalldriver || @driver_list))) {
|
||||
if ($arch =~/ppc/ || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
|
||||
if ($arch =~ /ppc/) {
|
||||
$cmd = "gunzip --quiet -c $pkgdir/1/suseboot/initrd64 > $dd_dir/initrd";
|
||||
} elsif ($arch =~ /x86/) {
|
||||
@ -1782,7 +1787,7 @@ sub insert_dd () {
|
||||
}
|
||||
|
||||
# Start to load the drivers from rpm packages
|
||||
if (@rpm_list && ($Injectalldriver || @driver_list)) {
|
||||
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
|
||||
# Extract the files from rpm to the tmp dir
|
||||
mkpath "$dd_dir/rpm";
|
||||
my $new_kernel_ver;
|
||||
@ -1802,19 +1807,19 @@ sub insert_dd () {
|
||||
}
|
||||
|
||||
# get the new kernel if it exists in the update distro
|
||||
my @new_kernels = <$dd_dir/rpm/boot/vmlinuz*>;
|
||||
my @new_kernels = <$dd_dir/rpm/boot/vmlinu*>;
|
||||
foreach my $new_kernel (@new_kernels) {
|
||||
if (-r $new_kernel && $new_kernel =~ /\/vmlinuz-(.*(x86_64|ppc64))$/) {
|
||||
$new_kernel_ver = $1;
|
||||
$cmd = "/bin/mv -f $new_kernel $dd_dir/rpm/newkernel";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $dd_dir/rpm/newkernel.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
if (-r $new_kernel && $new_kernel =~ /\/vmlinu[zx]-(.*(x86_64|ppc64|default))$/) {
|
||||
$new_kernel_ver = $1;
|
||||
$cmd = "/bin/mv -f $new_kernel $dd_dir/rpm/newkernel";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $dd_dir/rpm/newkernel.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver
|
||||
# Change it back to xxx.ko here
|
||||
@ -1851,14 +1856,45 @@ sub insert_dd () {
|
||||
# if the new kernel from update distro is not existed in initrd, create the path for it
|
||||
if (! -r "$dd_dir/initrd_img/lib/modules/$new_kernel_ver/") {
|
||||
mkpath ("$dd_dir/initrd_img/lib/modules/$new_kernel_ver/");
|
||||
# link the /modules to this new kernel dir
|
||||
unlink "$dd_dir/initrd_img/modules";
|
||||
$cmd = "/bin/ln -sf lib/modules/$new_kernel_ver/initrd $dd_dir/initrd_img/modules";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update failed. Could not create link to the new kernel dir.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
# get the name list for all drivers in the original initrd if 'netdrivers=updateonly'
|
||||
# then only the drivers in this list will be updated from the drvier rpms
|
||||
if ($updatealldriver) {
|
||||
$driver_name = "\*\.ko";
|
||||
@all_real_path = ();
|
||||
find(\&get_all_path, <$dd_dir/initrd_img/lib/modules/*>);
|
||||
foreach my $real_path (@all_real_path) {
|
||||
my $driver = basename($real_path);
|
||||
push @driver_list, $driver;
|
||||
}
|
||||
}
|
||||
|
||||
# Copy the drivers to the rootimage
|
||||
# Figure out the kernel version
|
||||
my @kernelpaths = <$dd_dir/initrd_img/lib/modules/*>;
|
||||
my @kernelvers;
|
||||
if ($new_kernel_ver) {
|
||||
push @kernelvers, $new_kernel_ver;
|
||||
}
|
||||
foreach (@kernelpaths) {
|
||||
push @kernelvers, basename($_);
|
||||
my $kernelv = basename($_);
|
||||
if ($kernelv =~ /^[\d\.]+/) {
|
||||
if ($new_kernel_ver) {
|
||||
rmtree ("$dd_dir/initrd_img/lib/modules/$kernelv");
|
||||
} else {
|
||||
push @kernelvers, $kernelv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $kernelver (@kernelvers) {
|
||||
@ -1871,7 +1907,6 @@ sub insert_dd () {
|
||||
$driver_name = $driver;
|
||||
@all_real_path = ();
|
||||
find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
|
||||
#if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) {
|
||||
# NOTE: for the initrd of sles that the drivers are put in the /lib/modules/$kernelver/initrd/
|
||||
foreach my $real_path (@all_real_path) {
|
||||
if ($real_path && $real_path =~ m!$dd_dir/rpm/lib/modules/$kernelver/!) {
|
||||
@ -1895,8 +1930,7 @@ sub insert_dd () {
|
||||
$driver_name = "\*\.ko";
|
||||
@all_real_path = ();
|
||||
find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
|
||||
foreach $real_path (@all_real_path) {
|
||||
#if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) {
|
||||
foreach my $real_path (@all_real_path) {
|
||||
# NOTE: for the initrd of sles that the drivers are put in the /lib/modules/$kernelver/initrd/
|
||||
if ($real_path && $real_path =~ m!$dd_dir/rpm/lib/modules/$kernelver/!) {
|
||||
if (! -d "$dd_dir/initrd_img/lib/modules/$kernelver/initrd") {
|
||||
@ -1928,34 +1962,32 @@ sub insert_dd () {
|
||||
}
|
||||
}
|
||||
} # end of loading drivers from rpm packages
|
||||
}
|
||||
|
||||
# Create the dir for driver update disk
|
||||
mkpath("$dd_dir/initrd_img/cus_driverdisk");
|
||||
# Create the dir for driver update disk
|
||||
mkpath("$dd_dir/initrd_img/cus_driverdisk");
|
||||
|
||||
# insert the driver update disk into the cus_driverdisk dir
|
||||
foreach my $dd (@dd_list) {
|
||||
copy($dd, "$dd_dir/initrd_img/cus_driverdisk");
|
||||
}
|
||||
# insert the driver update disk into the cus_driverdisk dir
|
||||
foreach my $dd (@dd_list) {
|
||||
copy($dd, "$dd_dir/initrd_img/cus_driverdisk");
|
||||
}
|
||||
|
||||
# Repack the initrd
|
||||
# In order to avoid the runcmd add the '2>&1' at end of the cpio
|
||||
# cmd, the echo cmd is added at the end
|
||||
$cmd = "cd $dd_dir/initrd_img; find . -print | cpio -H newc -o > $dd_dir/initrd | echo";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update disk failed. Could not pack the hacked initrd.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return ();
|
||||
}
|
||||
# Repack the initrd
|
||||
# In order to avoid the runcmd add the '2>&1' at end of the cpio
|
||||
# cmd, the echo cmd is added at the end
|
||||
$cmd = "cd $dd_dir/initrd_img; find . -print | cpio -H newc -o > $dd_dir/initrd | echo";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
if ($::RUNCMD_RC != 0) {
|
||||
my $rsp;
|
||||
push @{$rsp->{data}}, "Handle the driver update disk failed. Could not pack the hacked initrd.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return ();
|
||||
}
|
||||
|
||||
# zip the initrd
|
||||
#move ("$dd_dir/initrd.new", "$dd_dir/initrd");
|
||||
$cmd = "gzip -f $dd_dir/initrd";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
# zip the initrd
|
||||
#move ("$dd_dir/initrd.new", "$dd_dir/initrd");
|
||||
$cmd = "gzip -f $dd_dir/initrd";
|
||||
xCAT::Utils->runcmd($cmd, -1);
|
||||
|
||||
if ($arch =~/ppc/ || (@rpm_list && ($Injectalldriver || @driver_list))) {
|
||||
if ($arch =~/ppc/) {
|
||||
if (-r "$dd_dir/rpm/newkernel") {
|
||||
# if there's new kernel from update distro, then use it
|
||||
@ -1999,12 +2031,21 @@ sub insert_dd () {
|
||||
|
||||
my $rsp;
|
||||
if (@dd_list) {
|
||||
push @{$rsp->{data}}, "Inserted the driver update disk:".join(',', sort(@dd_list)).".";
|
||||
push @{$rsp->{data}}, "The driver update disk:".join(',',@dd_list)." have been injected to initrd.";
|
||||
}
|
||||
if (@driver_list) {
|
||||
push @{$rsp->{data}}, "Inserted the drivers:".join(',', sort(@rpm_drivers))." from driver packages.";
|
||||
} elsif (@rpm_list && ($Injectalldriver || @driver_list)) {
|
||||
push @{$rsp->{data}}, "Inserted the drivers from driver packages:".join(',', sort(@rpm_list)).".";
|
||||
# remove the duplicated names
|
||||
my %dnhash;
|
||||
foreach (@rpm_drivers) {
|
||||
$dnhash{$_} = 1;
|
||||
}
|
||||
@rpm_drivers = keys %dnhash;
|
||||
|
||||
if (@rpm_list) {
|
||||
if (@rpm_drivers) {
|
||||
push @{$rsp->{data}}, "The drivers:".join(',', sort(@rpm_drivers))." from ".join(',', sort(@rpm_list))." have been injected to initrd.";
|
||||
} else {
|
||||
push @{$rsp->{data}}, "No driver was injected to initrd.";
|
||||
}
|
||||
}
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user