2008-05-24 17:29:40 +00:00
#!/usr/bin/env perl
2009-09-24 18:51:53 +00:00
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
2008-05-24 17:29:40 +00:00
use File::Basename;
use File::Path;
2010-09-27 09:09:50 +00:00
use File::Copy qw/copy cp mv move/;
2008-05-24 17:29:40 +00:00
use File::Find;
use Getopt::Long;
2008-09-11 22:03:01 +00:00
use Cwd qw(realpath);
2010-08-23 08:00:51 +00:00
use File::Temp qw/mkdtemp/;
2010-07-09 06:19:30 +00:00
2010-12-13 06:59:31 +00:00
use FindBin;
use lib "$FindBin::Bin/../imgutils";
2010-07-09 06:19:30 +00:00
use imgutils;
2008-05-24 17:29:40 +00:00
#use strict;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
my $prinic; #TODO be flexible on node primary nic
my $othernics; #TODO be flexible on node primary nic
my $netdriver;
my @yumdirs;
2009-09-24 18:51:53 +00:00
my $arch;
2008-05-24 17:29:40 +00:00
my %libhash;
my @filestoadd;
my $profile;
my $osver;
my $pathtofiles=dirname($0);
2008-09-11 22:03:01 +00:00
my $fullpath=realpath($pathtofiles);
2008-05-24 17:29:40 +00:00
my $name = basename($0);
my $onlyinitrd=0;
2012-10-22 08:47:48 +00:00
#that this method of calling genimage is no longer used
2008-05-24 17:29:40 +00:00
if ($name =~ /geninitrd/) {
$onlyinitrd=1;
}
my $rootlimit;
my $tmplimit;
my $installroot = "/install";
2011-03-28 07:39:59 +00:00
my $kerneldir;
2010-09-17 09:54:47 +00:00
my $kernelver = "";
my $basekernelver;
2008-09-11 22:03:01 +00:00
my $customdir=$fullpath;
$customdir =~ s/.*share\/xcat/$installroot\/custom/;
2009-09-24 18:51:53 +00:00
my $imagename;
my $pkglist;
my $srcdir;
my $destdir;
my $srcdir_otherpkgs;
my $otherpkglist;
my $postinstall_filename;
my $rootimg_dir;
2010-01-26 12:10:16 +00:00
my $mode;
2010-03-05 06:54:52 +00:00
my $permission; #the permission works only for statelite mode currently
2011-06-24 16:22:15 +00:00
my $krpmver;
2012-03-27 19:28:49 +00:00
my $tempfile;
my $prompt;
2013-04-24 07:57:24 +00:00
my $timezone; #the TIMEZONE of the stateless and statelite node
2008-05-24 17:29:40 +00:00
sub xdie {
system("rm -rf /tmp/xcatinitrd.$$");
die @_;
}
2008-09-10 14:59:34 +00:00
#-- fetch current version form CVS (overwrite locally changed versions)
# if (opendir(CVS,"$pathtofiles/CVS")){
# close CVS;
# my $cvsout = qx/cd $pathtofiles; cvs update -C 2>&1/;
# chomp $cvsout;
# if ( $cvsout ne "cvs update: Updating ." ) {
# print "Difference of local copy from CVS detected\n";
# print $cvsout,"\n";
# print "Trying to re-run $name\n";
# print("$pathtofiles/$name ",join(" ",@ARGV),"\n");
# exec("$pathtofiles/$name",@ARGV);
# }
# }
2008-05-24 17:29:40 +00:00
$SIG{INT} = $SIG{TERM} = sub { xdie "Interrupted" };
GetOptions(
'a=s' => \$arch,
'p=s' => \$profile,
'o=s' => \$osver,
'n=s' => \$netdriver,
'i=s' => \$prinic,
'r=s' => \$othernics,
'l=s' => \$rootlimit,
't=s' => \$tmplimit,
2010-01-26 12:10:16 +00:00
'k=s' => \$kernelver,
2011-05-26 16:24:17 +00:00
'g=s' => \$krpmver,
2011-07-07 16:10:53 +00:00
'permission=s' => \$permission,
'kerneldir=s' => \$kerneldir,
2013-04-24 07:57:24 +00:00
'timezone=s' => \$timezone,
2012-03-27 19:28:49 +00:00
'tempfile=s' =>\$tempfile, #internal flag
2011-07-07 16:10:53 +00:00
'pkglist=s' => \$pkglist, #internal flag
'srcdir=s' => \$srcdir, #internal flag
'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag
'otherpkglist=s' => \$otherpkglist, #internal flag
'postinstall=s' => \$postinstall_filename, #internal flag
'rootimgdir=s' => \$destdir, #internal flag
2012-07-05 14:59:08 +00:00
'driverupdatesrc=s' => \$driverupdatesrc, #internal flag
2012-03-27 20:59:36 +00:00
'interactive' =>\$prompt,
2012-10-22 08:47:48 +00:00
'onlyinitrd' =>\$onlyinitrd,
2011-07-07 16:10:53 +00:00
);
if (@ARGV > 0) {
2009-09-24 18:51:53 +00:00
$imagename=$ARGV[0];
2011-07-07 16:10:53 +00:00
}
2009-09-24 18:51:53 +00:00
2011-07-07 16:10:53 +00:00
my %updates_os = (); # the hash for updating osimage table
my %updates = (); # the hash for updating linuximage table
2011-06-24 16:22:15 +00:00
2010-03-05 06:54:52 +00:00
2010-09-17 09:54:47 +00:00
$permission = "755" unless ($permission);
2012-03-27 19:28:49 +00:00
$updates{'permission'} = $permission if ($tempfile);
2010-03-05 06:54:52 +00:00
2010-09-17 09:54:47 +00:00
unless ($arch) {
2009-10-13 11:39:37 +00:00
$arch = `uname -m`;
2009-09-24 18:51:53 +00:00
chomp($arch);
2010-09-17 09:54:47 +00:00
$arch = "x86" if ($arch =~ /i.86$/);
2009-09-24 18:51:53 +00:00
}
2010-09-17 09:54:47 +00:00
$srcdir="$installroot/$osver/$arch" unless ($srcdir);
2012-03-27 19:28:49 +00:00
$updates{'pkgdir'} = $srcdir if ($tempfile);
2012-12-21 07:56:14 +00:00
#$srcdir = $srcdir . "/1";
2009-09-24 18:51:53 +00:00
2010-09-17 09:54:47 +00:00
$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs);
2012-03-27 19:28:49 +00:00
$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile);
2010-09-17 09:54:47 +00:00
$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir);
2012-03-27 19:28:49 +00:00
$updates{'rootimgdir'} = $destdir if ($tempfile);
2009-09-24 18:51:53 +00:00
$rootimg_dir="$destdir/rootimg";
2011-05-26 16:24:17 +00:00
if ($kernelver && (!$krpmver)) {
2011-07-07 16:10:53 +00:00
print "The -g flag for the rpm version of kernel packages needs to be specified when kernel version has been specified.\n";
exit 1;
2011-05-26 16:24:17 +00:00
}
2011-03-28 07:39:59 +00:00
$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels";
2012-03-27 19:28:49 +00:00
#$updates{'kerneldir'} = $kerneldir if ($tempfile);
2009-09-24 18:51:53 +00:00
2010-09-17 18:12:25 +00:00
unless ($osver and $profile) {
2011-07-07 16:10:53 +00:00
usage();
exit 1;
2008-05-24 17:29:40 +00:00
}
my @ndrivers;
2010-09-17 09:54:47 +00:00
if ($netdriver) {
2012-10-16 05:58:29 +00:00
foreach (split /,/,$netdriver) {
if (/^allupdate$/) {
next;
}
unless (/\.ko$/) {
s/$/.ko/;
}
next if (/^$/);
# Do not include qeth module here
# This module is included later on
unless ( $_ =~ m/qeth/i ) {
push @ndrivers, $_;
}
}
2012-03-27 19:28:49 +00:00
if ( ($updates{'netdrivers'} ne $netdriver) and $tempfile ) {
2010-09-17 09:54:47 +00:00
$updates{'netdrivers'} = $netdriver;
}
2012-10-16 05:58:29 +00:00
}
# Use the default list if not specified
unless (@ndrivers) {
2010-09-17 09:54:47 +00:00
if ($arch eq 'x86' or $arch eq 'x86_64') {
2012-08-02 06:08:50 +00:00
@ndrivers = qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en be2net/;
2010-09-17 09:54:47 +00:00
} elsif ($arch eq 'ppc64') {
2012-08-17 09:07:37 +00:00
@ndrivers = qw/tg3 e1000 e1000e igb ibmveth ehea be2net/;
2010-09-17 09:54:47 +00:00
} elsif ($arch eq "s390x") {
2010-10-04 16:12:34 +00:00
@ndrivers = qw/qdio ccwgroup qeth qeth_l2 qeth_l3/;
2010-09-17 09:54:47 +00:00
}
}
2011-07-27 09:02:10 +00:00
foreach (@ndrivers) {
unless (/\.ko$/) {
s/$/.ko/;
}
}
2008-05-26 16:11:24 +00:00
unless (grep /af_packet/,@ndrivers) {
2011-07-07 16:10:53 +00:00
unshift(@ndrivers,"af_packet.ko");
2008-05-26 16:11:24 +00:00
}
2008-05-24 17:29:40 +00:00
2009-02-18 13:43:11 +00:00
my $osver_host;
if(`grep VERSION /etc/SuSE-release` =~ /VERSION = (\d+)/) {
$osver_host=$1;
} else {
$osver_host=11;
}
2009-09-24 18:51:53 +00:00
unless ($onlyinitrd) {
2010-09-17 09:54:47 +00:00
# now, let's handle the extra packages
unless ($imagename) {
$otherpkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "otherpkgs.pkglist");
unless ($otherpkglist) { $otherpkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "otherpkgs.pkglist"); }
2012-03-27 19:28:49 +00:00
$updates{'otherpkglist'} = $otherpkglist if ($tempfile and $otherpkglist);
2010-03-19 21:12:56 +00:00
}
my %extra_hash=();
2010-09-17 09:54:47 +00:00
%extra_hash=imgutils::get_package_names($otherpkglist) if ($otherpkglist);
2008-09-09 23:52:04 +00:00
2010-09-17 09:54:47 +00:00
# prepare the chroot environment for the root image
2008-09-09 23:52:04 +00:00
2010-09-17 09:54:47 +00:00
mkpath "$rootimg_dir/etc";
mkpath "$rootimg_dir/dev";
#system "mount -o bind /dev $rootimg_dir/dev";
unless ( -e "$rootimg_dir/dev/zero") {
2010-01-26 12:10:16 +00:00
system "mknod $rootimg_dir/dev/zero c 1 5";
}
2010-09-17 09:54:47 +00:00
unless ( -e "$rootimg_dir/dev/null") {
2010-01-26 12:10:16 +00:00
system "mknod $rootimg_dir/dev/null c 1 3"; #that's neccessary for SLES11
}
2010-09-17 09:54:47 +00:00
2011-02-17 07:13:23 +00:00
unless ( -e "$rootimg_dir/dev/random") {
system "mknod $rootimg_dir/dev/random c 1 8"; #that's neccessary for SLES11
}
unless ( -e "$rootimg_dir/dev/urandom") {
system "mknod $rootimg_dir/dev/urandom c 1 9"; #that's neccessary for SLES11
}
for (my $i = 0; $i <= 12; $i++)
{
unless ( -e "$rootimg_dir/dev/tty$i") {
system "mknod $rootimg_dir/dev/tty$i c 4 $i"; #that's neccessary for SLES11
}
}
2010-09-17 09:54:47 +00:00
open($fd,">>","$rootimg_dir/etc/fstab"); # TODO: is it necessary?
2008-05-24 17:29:40 +00:00
print $fd "#Dummy fstab for rpm postscripts to see\n";
close($fd);
2012-03-27 19:28:49 +00:00
my $non_interactive;
if (!$prompt) { $non_interactive="--non-interactive --no-gpg-checks"; }
2010-09-17 09:54:47 +00:00
2009-02-18 13:43:11 +00:00
if($osver_host == 11) {#zypper in SLES11 is different
2012-12-21 07:56:14 +00:00
system("rm -rf $rootimg_dir/etc/zypp/repos.d/$osver-*.repo");
my @pkgdirs = split(",", $srcdir);
my $dir;
my $i = 0;
# To support multiple paths for osimage.pkgdir
foreach $dir (@pkgdirs) {
if( -d "$dir/1") {
$dir .= "/1";
}
system("zypper -R $rootimg_dir $non_interactive ar file:$dir $osver-$i");
$i++;
2011-06-27 03:46:29 +00:00
}
2012-12-21 07:56:14 +00:00
#if(-e "$rootimg_dir/etc/zypp/repos.d/$osver.repo") {
# system("rm -rf $rootimg_dir/etc/zypp/repos.d/$osver.repo");
#}
#system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir $osver");
#if(-e "$rootimg_dir/etc/zypp/repos.d/${osver}sdk.repo") {
# system("rm -rf $rootimg_dir/etc/zypp/repos.d/${osver}sdk.repo");
#}
2011-06-27 03:46:29 +00:00
my $srcdir_sdk = "$installroot/$osver/$arch/sdk1";
2011-07-19 03:28:44 +00:00
if ( -e "$srcdir_sdk") {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir_sdk ${osver}sdk");
2011-07-19 03:28:44 +00:00
}
2011-07-07 16:10:53 +00:00
2009-02-12 12:04:51 +00:00
}else {
2012-12-21 07:56:14 +00:00
$srcdir = $srcdir . "/1";
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive sa file:$srcdir");
2009-02-12 12:04:51 +00:00
}
2008-09-09 23:52:04 +00:00
2011-05-26 16:24:17 +00:00
# Add the rep for kernel packages
if ($kernelver) {
if (! -d $kerneldir) {
print "Cannot find the directory for the kernel at $kerneldir.\n";
exit 1;
}
if ($osver_host == 11) {
if (-e "$rootimg_dir/etc/zypp/repos.d/$kernelver.repo") {
system("rm -rf $rootimg_dir/etc/zypp/repos.d/$kernelver.repo");
}
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive ar file:$kerneldir $kernelver");
2011-05-26 16:24:17 +00:00
} else {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive sa file:$kerneldir");
2011-05-26 16:24:17 +00:00
}
}
2011-10-18 07:08:12 +00:00
2009-07-02 20:24:27 +00:00
#remove the old repository for extra packages
2011-10-18 07:08:12 +00:00
if ($osver_host == 11) {
2012-03-27 19:28:49 +00:00
my $result=`zypper -R $rootimg_dir $non_interactive lr |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`;
2011-10-18 07:08:12 +00:00
if ($result =~ /\S/) {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive rr $result");
2011-10-18 07:08:12 +00:00
}
} else {
2012-03-27 19:28:49 +00:00
my $result=`zypper -R $rootimg_dir $non_interactive sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`;
2011-10-18 07:08:12 +00:00
if ($result =~ /\S/) {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive sd $result");
2011-10-18 07:08:12 +00:00
}
2009-07-02 20:24:27 +00:00
}
#add the new repository for extra packages
2010-03-22 16:14:06 +00:00
my %extrapkgnames;
2009-07-02 20:24:27 +00:00
if($osver_host == 11) { #SLES11
2011-07-07 16:10:53 +00:00
if(-e "$rootimg_dir/etc/zypp/repos.d/otherpkg.repo") {
system("rm -rf $rootimg_dir/etc/zypp/repos.d/otherpkg.repo");
}
2009-07-02 20:24:27 +00:00
}
my $index=1;
2010-03-22 16:14:06 +00:00
my $pass;
2013-07-17 02:55:13 +00:00
foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) {
2010-03-22 16:14:06 +00:00
foreach (keys(%{$extra_hash{$pass}})) {
2011-10-10 07:46:18 +00:00
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;}
2009-09-24 18:51:53 +00:00
my $whole_path="$srcdir_otherpkgs/$_";
2009-07-02 20:24:27 +00:00
if (-r "$srcdir_otherpkgs/$_/repodata/repomd.xml") {
if($osver_host == 11) {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir_otherpkgs/$_ otherpkg$index");
2009-07-02 20:24:27 +00:00
}else {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive sa file:$srcdir_otherpkgs/$_");
2009-07-02 20:24:27 +00:00
}
} else {
if($osver_host == 11) {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive ar -t Plaindir file:$srcdir_otherpkgs/$_ otherpkg$index");
2009-07-02 20:24:27 +00:00
}else {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive sa -t Plaindir file:$srcdir_otherpkgs/$_");
2009-07-02 20:24:27 +00:00
}
}
$index++;
2010-03-22 16:14:06 +00:00
my $pa=$extra_hash{$pass}{$_};
$extrapkgnames{$pass} .= " " . join(' ', @$pa);
}
2008-09-09 23:52:04 +00:00
}
2009-09-24 18:51:53 +00:00
#-- add custom repositories to the image
#TODO: should we add the support to otherpkgs for this? we have too many list files and it seems only SLES supports this
2010-09-17 09:54:47 +00:00
# not sure, but it is convenient
2009-09-24 18:51:53 +00:00
my $repolist;
2010-07-09 06:19:30 +00:00
$repolist = imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "repolist");
2010-09-17 09:54:47 +00:00
unless ($repolist) {
2010-07-09 06:19:30 +00:00
$repolist = imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "repolist");
2010-04-09 03:18:56 +00:00
}
2009-04-08 07:37:35 +00:00
if ( -r "$repolist") {
2008-09-10 14:38:27 +00:00
print "Reading custom repositories\n";
open($repoconfig,"<","$repolist");
while (<$repoconfig>) {
chomp;
next if /^\s*#/;
2009-09-24 18:51:53 +00:00
my ($repotype,$repourl,$repoalias) = split m/\|/;
2011-10-18 07:08:12 +00:00
if($osver_host == 11) {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive ar $repourl $repoalias");
2011-10-18 07:08:12 +00:00
}else {
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive sa $repourl $repoalias");
2011-10-18 07:08:12 +00:00
}
2008-09-10 14:38:27 +00:00
}
}
2010-03-09 17:25:45 +00:00
# Refresh the zypper cache in case there is still old data out there
2012-03-27 19:28:49 +00:00
system("zypper -R $rootimg_dir $non_interactive refresh");
2010-03-09 17:25:45 +00:00
2009-09-24 18:51:53 +00:00
#my $yumcmd = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir --disablerepo=* ";
2008-05-24 17:29:40 +00:00
#$yumcmd .= "install ";
2009-09-24 18:51:53 +00:00
#mkpath("$rootimg_dir/var/lib/yum");
2009-02-12 12:04:51 +00:00
my $yumcmd;
2009-02-18 13:43:11 +00:00
if($osver =~ /sles11/ && $osver_host == 11) {
2012-10-15 06:40:00 +00:00
$yumcmd = "zypper -R $rootimg_dir $non_interactive install -l --no-recommends "; #add -l for SLES11
2009-02-12 12:04:51 +00:00
}else {
2012-03-27 19:28:49 +00:00
$yumcmd = "zypper -R $rootimg_dir $non_interactive install ";
2009-09-24 18:51:53 +00:00
}
2010-03-19 21:12:56 +00:00
2010-03-22 16:14:06 +00:00
#install packages from pkglist file
2010-03-19 21:12:56 +00:00
my $pkgnames;
2010-09-17 09:54:47 +00:00
unless ($imagename) {
$pkglist = imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "pkglist");
unless ($pkglist) { $pkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "pkglist"); }
2009-02-12 12:04:51 +00:00
}
2008-09-11 22:03:01 +00:00
2010-09-17 09:54:47 +00:00
if ($pkglist) {
2012-03-27 19:28:49 +00:00
$updates{'pkglist'} = $pkglist if ($tempfile);
2010-09-17 09:54:47 +00:00
} else {
2008-05-24 17:29:40 +00:00
print "Unable to find package list for $profile!";
2009-02-16 22:12:03 +00:00
exit 1;
2008-05-24 17:29:40 +00:00
}
2008-09-11 22:03:01 +00:00
2010-07-09 09:36:36 +00:00
my %pkg_hash=imgutils::get_package_names($pkglist);
2010-03-19 21:12:56 +00:00
my $index=1;
2013-07-17 02:55:13 +00:00
foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) {
2010-03-22 16:14:06 +00:00
$pkgnames = "";
2011-07-07 16:10:53 +00:00
$group_pkgnames = "";
2010-03-22 16:14:06 +00:00
foreach (keys(%{$pkg_hash{$pass}})) {
2011-10-10 07:46:18 +00:00
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;}
2010-03-24 08:47:35 +00:00
my $pa=$pkg_hash{$pass}{$_};
2011-05-26 16:24:17 +00:00
# replace the kernel package with the name has the specific version
my @npa = ();
2011-07-07 16:10:53 +00:00
my @npa_group = ();
2011-05-26 16:24:17 +00:00
foreach my $p (@$pa) {
2011-07-18 09:02:33 +00:00
if ($p =~ /^kernel/ && $kernelver) {
2011-05-26 16:24:17 +00:00
# get all files in $srcdir and $kerneldir
my @alldirs = ("$srcdir", "$kerneldir");
my @allrpms = ();
foreach my $dir (@alldirs) {
my @files = `find $dir -name *.rpm`;
push @allrpms, @files;
}
2011-07-18 09:02:33 +00:00
my @kernelpkgs = ();
if ($p =~ /^kernel$/) {
@kernelpkgs = ("kernel-default","kernel-default-base");
} elsif ($p =~ /^kernel-ppc64$/) {
@kernelpkgs = ($p, $p."-base");
} else {
@kernelpkgs = ($p);
}
2011-05-26 16:24:17 +00:00
foreach my $kern (@kernelpkgs) {
my @rpm = grep /$kern-$krpmver/, @allrpms;
if (!@rpm) {
print "Cannot find the kernel package with the versioin $krpmver.\n";
exit 1;
}
2013-04-26 02:10:57 +00:00
my $kernelname = "$kern-".$krpmver;
2011-05-26 16:24:17 +00:00
push @npa, $kernelname;
}
2011-07-07 16:10:53 +00:00
} else {
if($p =~ s/^@//)
{
push @npa_group, $p;
}
else
{
push @npa, $p;
}
2011-05-26 16:24:17 +00:00
}
}
2012-04-02 17:35:34 +00:00
if (@npa) {
$pkgnames .= " " . join(' ', @npa);
}
if (@npa_group) {
$group_pkgnames .= " " . join(' ', @npa_group);
}
2010-03-22 16:14:06 +00:00
}
2011-10-10 07:46:18 +00:00
my $envlist;
if(exists $pkg_hash{$pass}{ENVLIST}){
$envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}});
}
2012-04-02 17:35:34 +00:00
if($pkgnames)
2011-07-07 16:10:53 +00:00
{
2011-11-11 06:36:51 +00:00
print "$envlist $yumcmd $pkgnames\n";
$rc = system("$envlist $yumcmd $pkgnames");
2011-07-07 16:10:53 +00:00
$rc = $rc >> 8;
if (($rc) && ($rc != '104')) {
print "zypper invocation failed with rc: $rc\n";
exit 1;
2011-07-06 09:15:36 +00:00
}
2011-07-07 16:10:53 +00:00
}
2012-04-02 17:35:34 +00:00
if($group_pkgnames)
2011-07-07 16:10:53 +00:00
{
2011-10-18 07:08:12 +00:00
print "$envlist $yumcmd -t pattern $group_pkgnames\n";
$rc = system("$envlist $yumcmd -t pattern $group_pkgnames");
2012-10-15 06:40:00 +00:00
$rc = $rc >> 8;
if (($rc) && ($rc != '104')) {
print "zypper invocation failed with rc: $rc\n";
exit 1;
}
2011-07-07 16:10:53 +00:00
}
2012-10-15 06:40:00 +00:00
}
2009-04-23 19:12:33 +00:00
2013-07-17 02:55:13 +00:00
foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) {
2013-04-01 12:11:05 +00:00
my $index=1;
#remove the old repository for extra packages
if ($osver_host == 11) {
my $result=`zypper -R $rootimg_dir $non_interactive lr |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`;
if ($result =~ /\S/) {
system("zypper -R $rootimg_dir $non_interactive rr $result");
}
} else {
my $result=`zypper -R $rootimg_dir $non_interactive sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`;
if ($result =~ /\S/) {
system("zypper -R $rootimg_dir $non_interactive sd $result");
}
}
foreach (keys(%{$extra_hash{$pass}})) {
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;}
if (-r "$srcdir_otherpkgs/$_/repodata/repomd.xml") {
if($osver_host == 11) {
system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir_otherpkgs/$_ otherpkg$index");
} else {
system("zypper -R $rootimg_dir $non_interactive sa file:$srcdir_otherpkgs/$_");
}
} else {
if($osver_host == 11) {
system("zypper -R $rootimg_dir $non_interactive ar -t Plaindir file:$srcdir_otherpkgs/$_ otherpkg$index");
}else {
system("zypper -R $rootimg_dir $non_interactive sa -t Plaindir file:$srcdir_otherpkgs/$_");
}
}
$index++;
}
# Refresh the zypper cache in case there is still old data out there
system("zypper -R $rootimg_dir $non_interactive refresh");
2010-03-22 16:14:06 +00:00
#remove the packages that are specified in the otherpkgs.list files with leading '-'
2011-10-10 07:46:18 +00:00
my $envlist;
if(exists $extra_hash{$pass}{ENVLIST}){
$envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}});
}
2012-03-27 19:28:49 +00:00
my $yumcmd_remove= "zypper -R $rootimg_dir $non_interactive remove ";
2010-03-22 16:14:06 +00:00
if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) {
my $pa=$extra_hash{$pass}{'PRE_REMOVE'};
my $rm_packges= join(' ', @$pa);
if ($rm_packges) {
2011-10-10 07:46:18 +00:00
print "$envlist $yumcmd_remove $rm_packges";
$rc = system("$envlist $yumcmd_remove $rm_packges");
2010-03-22 16:14:06 +00:00
}
2009-10-06 20:21:11 +00:00
}
2010-03-22 16:14:06 +00:00
#add extra packages in the list
if ($extrapkgnames{$pass}) {
2013-04-01 12:11:05 +00:00
print "$envlist $yumcmd $extrapkgnames{$pass}\n";
2011-10-10 07:46:18 +00:00
$rc = system("$envlist $yumcmd $extrapkgnames{$pass}");
2010-03-31 00:51:21 +00:00
$rc = $rc >> 8;
if (($rc) && ($rc != '104')) {
2010-09-17 09:54:47 +00:00
print "zypper invocation failed with rc: $rc\n";
exit 1;
2010-03-22 16:14:06 +00:00
}
2009-04-23 19:12:33 +00:00
}
2010-03-22 16:14:06 +00:00
#remove the packages that are specified in the otherpkgs.list files with leading '--'
if (exists ($extra_hash{$pass}{'POST_REMOVE'})) {
my $pa=$extra_hash{$pass}{'POST_REMOVE'};
my $rm_packges= join(' ', @$pa);
if ($rm_packges) {
2011-10-10 07:46:18 +00:00
print "$envlist $yumcmd_remove $rm_packges";
$rc = system("$envlist $yumcmd_remove $rm_packges");
2010-03-22 16:14:06 +00:00
}
2009-10-06 20:21:11 +00:00
}
}
2010-03-08 20:46:07 +00:00
# run zypper update to update any installed rpms
# needed when running genimage again after updating software in repositories
2011-10-18 07:08:12 +00:00
my $yumcmd_update;
if ($osver_host == 11) {
2012-03-27 19:28:49 +00:00
$yumcmd_update = "zypper -R $rootimg_dir $non_interactive update ";
2011-10-18 07:08:12 +00:00
} else {
2012-03-27 19:28:49 +00:00
$yumcmd_update = "zypper -R $rootimg_dir $non_interactive update ";
2011-10-18 07:08:12 +00:00
}
2010-03-08 20:46:07 +00:00
$rc = system("$yumcmd_update");
# ignore any return code
2010-09-25 09:54:06 +00:00
postscripts(); #run 'postscripts'
}
unlink "/tmp/genimage.$$.yum.conf";
2010-09-17 09:54:47 +00:00
2010-09-25 09:54:06 +00:00
# default to the first kernel found in the install image if nothing specified explicitly.
# A more accurate guess than whatever the image build server happens to be running
# If specified, that takes precedence.
# If image has one, that is used
# If all else fails, resort to uname -r like this script did before
if ( -e "$rootimg_dir/boot/vmlinux" ) {
$basekernelver = basename(readlink "$rootimg_dir/boot/vmlinux");
if ($basekernelver eq "vmlinux") {
$basekernelver = "";
2010-09-17 09:54:47 +00:00
} else {
2010-09-25 09:54:06 +00:00
$basekernelver =~ s/vmlinu.-//;
$basekernelver =~ s/image-//;
}
}
unless ($basekernelver) {
my @KVERS = <$rootimg_dir/boot/vmlinu[xz]-*>;
# The kernel name is different on s390x, e.g. image-2.6.32.9-0.5-default
@KVERS = <$rootimg_dir/boot/image-*> if $arch eq "s390x";
foreach (@KVERS) {
s/vmlinu.-//;
s/image-//;
}
unless (scalar @KVERS) {
@KVERS = <$rootimg_dir/lib/modules/*>;
}
if (scalar @KVERS) {
foreach my $kver (@KVERS) {
unless ($kver =~ m/.gz$/) {
$basekernelver = basename($kver);
last;
2010-09-17 09:54:47 +00:00
}
}
2010-09-25 09:54:06 +00:00
}
2010-09-17 09:54:47 +00:00
2010-09-25 09:54:06 +00:00
@KVERS=<$rootimg_dir/lib/modules/*> unless (scalar @KVERS);
$basekernelver = basename(pop @KVERS) if (scalar @KVERS);
$basekernelver = `uname -r` unless ($basekernelver);
2010-09-27 09:09:50 +00:00
}
2010-09-17 09:54:47 +00:00
2010-09-27 09:09:50 +00:00
$kernelver = $basekernelver unless ($kernelver);
chomp $kernelver;
2012-03-27 19:28:49 +00:00
#$updates{kernelver} = $kernelver if ($tempfile);
2010-09-17 09:54:47 +00:00
2010-09-27 09:09:50 +00:00
# copy the kernel to $destdir
if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") {
copy("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel");
} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") {
copy("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel");
} elsif ( -e "$rootimg_dir/boot/image-$kernelver") {
copy("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel");
} else {
xdie "couldn't find the kernel file matched $kernelver in $rootimg_dir/boot !";
}
2008-09-10 14:32:35 +00:00
#-- run postinstall script
2010-09-17 09:54:47 +00:00
unless ($imagename) {
2010-07-09 06:19:30 +00:00
$postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall");
2010-09-17 09:54:47 +00:00
unless ($postinstall_filename) {
$postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall");
2009-09-24 18:51:53 +00:00
}
2009-04-23 14:13:56 +00:00
}
2013-01-16 16:27:44 +00:00
if ( $postinstall_filename ) {
2010-03-19 21:12:56 +00:00
#print "postinstall_filename=$postinstall_filename\n";
2010-09-17 09:54:47 +00:00
2012-07-02 07:27:16 +00:00
#For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level,
#because the "uname -r" only returns the version of the kernel in use
#create a temporary uname script. for every flag except for -r, it should just call the real
#uname with the same flags and return that info.
if(!( -e "$rootimg_dir/bin/orig_uname")) {
system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname");
}
my $tmpuname;
open($tmpuname,">","$rootimg_dir/bin/uname");
print $tmpuname <<EOS_UNAME;
#!/bin/sh
if [[ \$\# -eq 1 && \$1 == "-r" ]]; then
echo $kernelver
exit 0
fi
res=`/bin/orig_uname \$\*`
echo \$res
EOS_UNAME
close($tmpuname);
system("chmod +x $rootimg_dir/bin/uname");
2012-03-27 19:28:49 +00:00
$updates{'postinstall'} = $postinstall_filename if ($tempfile);
2010-09-17 09:54:47 +00:00
2013-01-16 16:27:44 +00:00
foreach my $postinstall ( split /,/, $postinstall_filename ) {
if ( !-x $postinstall ) {
print "postinstall script $postinstall is not executable\n";
exit 1;
}
my $rc = system($postinstall, $rootimg_dir,$osver,$arch,$profile);
if($rc) {
print "postinstall script $postinstall failed\n";
exit 1;
}
2009-02-18 13:43:11 +00:00
}
2013-01-16 16:27:44 +00:00
2012-07-02 07:27:16 +00:00
# restore the orig uname
system("mv $rootimg_dir/bin/orig_uname $rootimg_dir/bin/uname");
2009-02-18 13:43:11 +00:00
}
2009-04-23 14:13:56 +00:00
2011-07-07 16:10:53 +00:00
# output the changed the attributes so that it can be save into db by the caller.
# all the information has been gathered
# now, update the linuximage and osimage tables
# TODO: do statelite and stateless share the same attributes? currently, I will update both of them
#BEGIN: PLEASE DO NOT CHANGE THE FOLLOWING CODE, genimage PLUGIN NEEDS TO PARSE THR OUTPUT
2012-03-27 19:28:49 +00:00
if ($tempfile) {
open(FILE, ">>$tempfile");
2010-09-17 09:54:47 +00:00
if ($imagename) {
2011-07-07 16:10:53 +00:00
if (keys(%updates) > 0) {
2012-03-27 19:28:49 +00:00
print FILE "The output for table updates starts here\n";
print FILE "table::linuximage\n";
print FILE "imagename::$imagename\n";
2011-07-07 16:10:53 +00:00
my @a=%updates;
2012-03-27 19:28:49 +00:00
print FILE join('::',@a) . "\n";
print FILE "The output for table updates ends here\n";
2011-07-07 16:10:53 +00:00
}
2010-09-17 09:54:47 +00:00
} else {
2011-07-07 16:10:53 +00:00
$updates_os{'profile'} = $profile;
$updates_os{'imagetype'} = 'linux';
$updates_os{'provmethod'} = 'netboot';
$updates_os{'osname'} = 'Linux';
$updates_os{'osvers'} = $osver;
$updates_os{'osdistro'} = 'sles'; # not used currently
$updates_os{'osarch'} = $arch;
# update the imagename for stateless
2012-03-27 19:28:49 +00:00
print FILE "The output for table updates starts here\n";
print FILE "table::osimage\n";
print FILE "imagename::$osver-$arch-netboot-$profile\n";
2011-07-07 16:10:53 +00:00
my @a=%updates_os;
2012-03-27 19:28:49 +00:00
print FILE join('::',@a) . "\n";
print FILE "The output for table updates ends here\n";
2011-07-07 16:10:53 +00:00
2012-03-27 19:28:49 +00:00
print FILE "The output for table updates starts here\n";
print FILE "table::linuximage\n";
print FILE "imagename::$osver-$arch-netboot-$profile\n";
2011-07-07 16:10:53 +00:00
my @a=%updates;
2012-03-27 19:28:49 +00:00
print FILE join('::',@a) . "\n";
print FILE "The output for table updates ends here\n";
2011-07-07 16:10:53 +00:00
# update the imagename for statelite
$updates_os{'provmethod'} = 'statelite';
2012-03-27 19:28:49 +00:00
print FILE "The output for table updates starts here\n";
print FILE "table::osimage\n";
print FILE "imagename::$osver-$arch-statelite-$profile\n";
2011-07-07 16:10:53 +00:00
my @a=%updates_os;
2012-03-27 19:28:49 +00:00
print FILE join('::',@a) . "\n";
print FILE "The output for table updates ends here\n";
2011-07-07 16:10:53 +00:00
2012-03-27 19:28:49 +00:00
print FILE "The output for table updates starts here\n";
print FILE "table::linuximage\n";
print FILE "imagename::$osver-$arch-statelite-$profile\n";
2011-07-07 16:10:53 +00:00
my @a=%updates;
2012-03-27 19:28:49 +00:00
print FILE join('::',@a) . "\n";
print FILE "The output for table updates ends here\n";
2010-01-26 12:10:16 +00:00
}
2012-03-27 19:28:49 +00:00
close FILE;
2010-01-26 12:10:16 +00:00
}
2011-07-07 16:10:53 +00:00
#END
2010-01-26 12:10:16 +00:00
2010-09-17 09:54:47 +00:00
mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts;
2013-05-13 09:22:56 +00:00
mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount
mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log
2010-09-17 09:54:47 +00:00
mkpath "$rootimg_dir/root/.ssh"; # create place for NFS mounts for ssh; #TODO is necessary?
# this script will get the directories;
# TODO: it seems it is re-copied in liteimg.pm
unless( -r "$pathtofiles/../add-on/statelite/rc.statelite") {
print "Can't find $pathtofiles/../add-on/statelite/rc.statelite!\n";
exit;
}
system("cp $pathtofiles/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite");
2012-11-16 14:02:36 +00:00
system("cp $pathtofiles/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk");
2010-09-17 09:54:47 +00:00
# the dhcp client information stores in the directory "/var/lib/dhcpcd/"
unless(-l "$rootimg_dir/var/lib/dhcpcd") {
mkpath "$rootimg_dir/var/lib/dhcpcd/";
system("touch $rootimg_dir/var/lib/dhcpcd/dhcpcd-$prinic.info");
}
# which is different from the Redhat family
# some rpms mounts the imageroot/proc on the /proc, need to release it,
# otherwise got kernal panic when installing
# sometimes, the proc fs is not mounted, so one warning/error message will display,
# and I add one check point here.
2010-03-05 18:53:20 +00:00
my $MFD;
open MFD, "/proc/mounts";
my @lines = <MFD>;
close MFD;
2009-08-13 08:36:38 +00:00
2009-09-24 18:51:53 +00:00
my $ret = grep m{$rootimg_dir/proc}, @lines;
2009-08-13 08:36:38 +00:00
if($ret > 0) {
2010-03-05 18:53:20 +00:00
system("umount -l $rootimg_dir/proc");
2009-08-13 08:36:38 +00:00
}
2008-09-10 14:32:35 +00:00
2010-08-12 09:05:51 +00:00
# Load driver update disk, and copy them to the root image
my @dd_drivers = &load_dd();
# Push the drivers into the @ndrivers base on the order
my @new_order = ();
foreach my $dd (@dd_drivers) {
unless (grep { $_ eq $dd} @ndrivers) {
push @new_order, $dd;
}
2012-10-16 05:58:29 +00:00
print "Added driver $dd from driver update disk or driver rpm\n";
2010-08-12 09:05:51 +00:00
}
2012-10-16 05:58:29 +00:00
foreach my $driver (@ndrivers) {
print "Added driver $driver from root image\n";
}
2012-10-15 06:40:00 +00:00
if (@new_order) {
@ndrivers = (@new_order, @ndrivers);
}
2010-08-12 09:05:51 +00:00
2012-11-16 14:02:36 +00:00
# add drivers for local disk support
2013-09-25 06:05:39 +00:00
push @ndrivers, ("ext3.ko", "ext4.ko", "virtio_pci.ko", "virtio_blk.ko", "ata_piix.ko", "libata.ko", "scsi_mod.ko", "ibmvscsi.ko", "ibmvscsic.ko", "megaraid_sas.ko", "pcieport.ko", "sd_mod.ko");
2012-11-16 14:02:36 +00:00
2010-04-02 12:05:33 +00:00
open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep");
my @moddeps = <$moddeps>;
my @checkdeps = @ndrivers;
while (scalar @checkdeps) {
my $driver = pop @checkdeps;
my @lines = grep /\/$driver:/,@moddeps;
foreach (@lines) {
chomp;
s/.*://;
s/^\s*//;
my @deps = split /\s+/,$_;
my $dep;
foreach $dep (@deps) {
$dep =~ s/.*\///;
unless (grep { $_ eq $dep } @ndrivers) { #only add if not added
print "Added $dep as an autodetected depedency\n";
}
2013-09-25 06:05:39 +00:00
unshift (@checkdeps,$dep); #recursively check dependencies
unshift (@ndrivers,$dep);
2010-04-02 12:05:33 +00:00
}
}
}
close($moddeps);
2013-09-25 06:05:39 +00:00
#remove the duplicated drivers
my @fulldrivers;
foreach my $dn (@ndrivers) {
unless (grep {$_ eq $dn} @fulldrivers) {
push @fulldrivers, $dn;
}
}
@ndrivers = @fulldrivers;
2010-09-17 09:54:47 +00:00
# before mkinitrd, run depmod to generate the modules.dep
system("chroot $rootimg_dir depmod $kernelver");
my @drivers; # backup of @ndrivers
push @drivers, @ndrivers;
mkinitrd("statelite");
@ndrivers=();
push @ndrivers, @drivers;
mkinitrd("stateless");
2008-05-24 17:29:40 +00:00
2009-04-23 19:12:33 +00:00
2008-05-24 17:29:40 +00:00
sub getlibs {
2012-10-15 06:40:00 +00:00
my $file = shift;
my $liblist = `chroot $rootimg_dir ldd $file`;
if ($liblist =~ /not a dynamic executable/) {
return;
}
my @libs = split/\n/,$liblist;
my @return;
foreach (@libs) {
unless (/=>/) {
(my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3;
$lib =~ s/^\///;
$libhash{$lib}=1;
next;
}
(my $temp1,my $temp2) = split />/,$_,2;
(my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4;
unless ($temp1 =~ /\//) {
next;
}
$temp1 =~ s/^\///;
$libhash{$temp1}=1;
}
2008-05-24 17:29:40 +00:00
}
sub mkinitrd {
2010-09-17 09:54:47 +00:00
my ($mode) = @_; # statelite or stateless
if ($mode eq "statelite") {
# additional modules needed on s390x
push @ndrivers, qw{qdio.ko ccwgroup.ko qeth.ko qeth_l2.ko qeth_l3.ko} if ($arch eq "s390x");
# for nfs
This is to enable client to indicate options when mounting persistent directories on statelite(nfs/ramdisk) CNs, if not, "nolock,tcp" will be used as default options. This implementation aims for SLES11.
client can revise the statelite table to benefit from this, like:
#node,image,statemnt,mntopts,comments,disable
"935n02",,"192.168.0.244:/tmp","soft,timeo=200",,
------------------------------------------------------
Another change in sles.pm: we do insmod for net interfaces (ibmveth, ehea, etc...) after all other modules, to avoid failure when do 'netstart' during installation.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9817 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2011-06-16 03:06:56 +00:00
my @modlist = qw{sunrpc.ko lockd.ko nfs_acl.ko fscache.ko auth_rpcgss.ko exportfs.ko nfsd.ko nfs.ko};
unshift(@ndrivers, @modlist);
2010-09-17 09:54:47 +00:00
}
mkpath("/tmp/xcatinitrd.$$/bin");
2010-04-02 12:05:33 +00:00
symlink("bin","/tmp/xcatinitrd.$$/sbin");
mkpath("/tmp/xcatinitrd.$$/usr/bin");
mkpath("/tmp/xcatinitrd.$$/usr/sbin");
mkpath("/tmp/xcatinitrd.$$/usr/lib");
mkpath("/tmp/xcatinitrd.$$/usr/lib64");
mkpath("/tmp/xcatinitrd.$$/lib/firmware");
mkpath("/tmp/xcatinitrd.$$/tmp");
mkpath("/tmp/xcatinitrd.$$/var/run");
mkpath("/tmp/xcatinitrd.$$/lib64/firmware");
mkpath("/tmp/xcatinitrd.$$/lib/power6");#SLES10
mkpath("/tmp/xcatinitrd.$$/lib/power7");#SLES10
mkpath("/tmp/xcatinitrd.$$/lib/mkinitrd/bin");
mkpath("/tmp/xcatinitrd.$$/proc");
mkpath("/tmp/xcatinitrd.$$/sys");
mkpath("/tmp/xcatinitrd.$$/dev/mapper");
mkpath("/tmp/xcatinitrd.$$/sysroot");
mkpath("/tmp/xcatinitrd.$$/etc/ld.so.conf.d");
mkpath("/tmp/xcatinitrd.$$/var/lib/dhcpcd");
my $inifile;
open($inifile,">","/tmp/xcatinitrd.$$/init");
print $inifile "#!/bin/bash\n";
2010-01-26 12:10:16 +00:00
# copied from genimage for rh
# add some functions
print $inifile <<EOS1;
NEWROOT="/sysroot"
SHELL="/bin/sh"
RWDIR=".statelite"
# Define some colors
RESET="\033[0m"
RED="\033[31m"
CYAN="\033[36m"
YELLOW="\033[33m\033[1m"
GREEN="\033[32m"
PINK="\033[35m\033[1m"
MAGENTA="\033[35m"
BROWN="\033[33m"
NORMAL=\$RESET
# This function is used to mount files/directories from the .statelite directory
# over the root directory.
# This function stolen from redhat
shell() {
echo ''
echo -e "\$YELLOW Entering rescue/debug init shell."
echo -e " Exit shell to continue booting.\$RESET"
\$SHELL
}
2010-07-06 08:29:49 +00:00
2010-01-26 12:10:16 +00:00
fancydisplay () {
clear
echo -e "\$CYAN"
echo '
.. :iiii,
:tLL; .,:...,.
.j;:tLt. :. .;j: ij::::;.
:tt;:::,ii:.jEEGi :tDEEG:.ti,::::;t:
.,,,,,,,,,,,tLEEEEj: tDEEEEDtj;,,,::::::
.:,,::::::,;fDEEEEEL,. .,ijDEDDDEEGt,,,,:,ijj;
.... ..:;jDDLGDEEEGGGfjjjjjjfffLGDEEDEEDLjfGDt,:..
.iftffGDLLDEEEDDDEEDDDDEDEEGLfLjjtti:
,fii;jGDGffLjifLGLjtfffffGDEDGfji
;DEEGffDDDjiii;;ii;,tGDEGjfEEEEf.
,GEGGftiGEEEDt:,;,;;LEEDGjLEEEEEEG
;DEDGjtjfitjGGjfDGj;jLLiitfGDEGjEEDj
fGjjtfLfji;itjfGDjLDfjjjji;tGGLDEEDj
fEDGffjti;ittjjjjtjjjjt:,,iiGGGGjtf.
:fGGLfLLfLGf;i;ijffj,,tjLGDDGLfjtf,
:;tLfjiiffLGDDDGLGEEEEjfGDDGGLfjfff:
.. ,;tLLLLLL,;tijfLGGGjfDEEEEDLLGGGLLLjtjLLfi,.
.jffLLLLGGLfjj;: :,;ijLGLfjGEDDEGtfGGLfjj:.,jjLGGLti;,,;fj,
,fGGGGGGLj,. ;jGGGGLLjffftjLj;.. .,tfGGGGGGGGGGi
,jGDDDj,. :tLGLGGLGDLjt, :iLGGDDDDGLif
,LDDDL, .;LDDDDGfff, ,;iGDDj;,..
;fGGGf, ,;;;;,: tf;jL,
;.:::, Powered by xCAT ,j.:;
'
echo -e "\$RESET"
echo -e "\$YELLOW"
echo '
_________ ________________
___ __\\_ ___ \\ / _ \\__ ___/
\\ \\/ / \\ \\/ / /_\\ \\| |
> <\\ \\____/ | \\ |
/__/\\_ \\\\______ /\\____|__ /____|
\\/ \\/ \\/
'
echo -e "\$RESET"
}
EOS1
2012-10-15 06:40:00 +00:00
print $inifile "mount -t proc /proc /proc\n";
print $inifile "mount -t sysfs /sys /sys\n";
print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n";
2008-05-24 17:29:40 +00:00
print $inifile "mkdir /dev/pts\n";
print $inifile "mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts\n";
print $inifile "mkdir /dev/shm\n";
print $inifile "mkdir /dev/mapper\n";
2009-08-17 06:40:04 +00:00
print $inifile "mknod /dev/random c 1 8\n";
print $inifile "mknod /dev/urandom c 1 9\n";
2008-05-24 17:29:40 +00:00
print $inifile "mknod /dev/null c 1 3\n";
print $inifile "mknod /dev/zero c 1 5\n";
print $inifile "mknod /dev/systty c 4 0\n";
print $inifile "mknod /dev/tty c 5 0\n";
print $inifile "mknod /dev/console c 5 1\n";
print $inifile "mknod /dev/ptmx c 5 2\n";
print $inifile "mknod /dev/rtc c 10 135\n";
print $inifile "mknod /dev/tty0 c 4 0\n";
print $inifile "mknod /dev/tty1 c 4 1\n";
print $inifile "mknod /dev/tty2 c 4 2\n";
print $inifile "mknod /dev/tty3 c 4 3\n";
print $inifile "mknod /dev/tty4 c 4 4\n";
print $inifile "mknod /dev/tty5 c 4 5\n";
print $inifile "mknod /dev/tty6 c 4 6\n";
print $inifile "mknod /dev/tty7 c 4 7\n";
print $inifile "mknod /dev/tty8 c 4 8\n";
print $inifile "mknod /dev/tty9 c 4 9\n";
print $inifile "mknod /dev/tty10 c 4 10\n";
print $inifile "mknod /dev/tty11 c 4 11\n";
print $inifile "mknod /dev/tty12 c 4 12\n";
print $inifile "mknod /dev/ttyS0 c 4 64\n";
print $inifile "mknod /dev/ttyS1 c 4 65\n";
print $inifile "mknod /dev/ttyS2 c 4 66\n";
print $inifile "mknod /dev/ttyS3 c 4 67\n";
2010-01-26 12:10:16 +00:00
2011-11-21 01:52:33 +00:00
# Install modules before starting udev
# because networking modules (qeth/qeth_l2/qeth_l3) are needed
foreach (@ndrivers) {
print $inifile "insmod /lib/$_\n";
}
2011-02-17 07:13:23 +00:00
# Start udev
2011-11-21 01:52:33 +00:00
print $inifile <<EOMS;
2012-11-16 14:02:36 +00:00
PATH="\$PATH:/usr/sbin:/sbin"
export PATH
2011-02-17 07:13:23 +00:00
# Start udev to find devices attached to node
# This script can be found in /lib/mkinitrd
echo "Creating device nodes with udev"
/sbin/udevd --daemon
2011-10-18 07:08:12 +00:00
if [ -f "/sbin/udevadm" ]
then
/sbin/udevadm trigger
/sbin/udevadm settle --timeout=10
fi
2011-02-17 07:13:23 +00:00
EOMS
2011-11-21 01:52:33 +00:00
2010-09-17 09:54:47 +00:00
if($mode eq "statelite") {
print $inifile "echo debug: before netstart\n";
print $inifile "# check and see if debug is specified on command line\n";
print $inifile "grep '\(debug\)' /proc/cmdline > /dev/null && export DEBUG=1\n";
}
2010-06-16 00:09:21 +00:00
2008-05-24 17:29:40 +00:00
print $inifile <<EOMS;
2010-09-17 09:54:47 +00:00
# check the kernel parameters firstly
# if one parameter for the booting device is here, it will be used
PRINIC=$prinic
2013-06-17 15:13:41 +00:00
NODESTATUS='y'
This is to enable client to indicate options when mounting persistent directories on statelite(nfs/ramdisk) CNs, if not, "nolock,tcp" will be used as default options. This implementation aims for SLES11.
client can revise the statelite table to benefit from this, like:
#node,image,statemnt,mntopts,comments,disable
"935n02",,"192.168.0.244:/tmp","soft,timeo=200",,
------------------------------------------------------
Another change in sles.pm: we do insmod for net interfaces (ibmveth, ehea, etc...) after all other modules, to avoid failure when do 'netstart' during installation.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9817 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2011-06-16 03:06:56 +00:00
XCATMNTOPTS='nolock,tcp'
2010-09-17 09:54:47 +00:00
for i in `cat /proc/cmdline`; do
KEY=`echo \$i |awk -F= '{print \$1}'`
if [ "\$KEY" == 'netdev' ]; then
NETDEV=`echo \$i |awk -F= '{print \$2}'`
elif [ "\$KEY" == 'BOOTIF' ]; then
2010-09-22 15:08:16 +00:00
VALUE=`echo \$i |awk -F= '{print \$2}'|sed -e s/^01-// -e s/-/:/g`
BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'`
2010-09-17 09:54:47 +00:00
elif [ "\$KEY" == 'XCAT' ]; then
VALUE=`echo \$i |awk -F= '{print \$2}'`
# format: XCAT=xcatmaster:xcatdport
XCATSERVER=\$VALUE
This is to enable client to indicate options when mounting persistent directories on statelite(nfs/ramdisk) CNs, if not, "nolock,tcp" will be used as default options. This implementation aims for SLES11.
client can revise the statelite table to benefit from this, like:
#node,image,statemnt,mntopts,comments,disable
"935n02",,"192.168.0.244:/tmp","soft,timeo=200",,
------------------------------------------------------
Another change in sles.pm: we do insmod for net interfaces (ibmveth, ehea, etc...) after all other modules, to avoid failure when do 'netstart' during installation.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9817 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2011-06-16 03:06:56 +00:00
elif [ "\$KEY" == 'MNTOPTS' ]; then
VALUE=`echo \$i |awk -F\\' '{print \$2}'`
# format: MNTOPTS='nolock,time=800'
XCATMNTOPTS=\$VALUE
2010-09-17 09:54:47 +00:00
fi
2013-06-17 15:13:41 +00:00
if [ \$i == 'nonodestatus' ]; then
NODESTATUS='n'
fi
2010-09-17 09:54:47 +00:00
done
if [ -z "\$IFACE" ]; then
if [ ! -z "\$NETDEV" ]; then
IFACE=\$NETDEV
elif [ ! -z "\$BOOTIF" ]; then
IFACE=\$BOOTIF
elif [ ! -z "\$PRINIC" ]; then
IFACE=\$PRINIC
else
echo "\${RED}Couldn't find the proper booting device, switch to shell...\${RESET}"
shell
exit
fi
fi
export IFACE=\$IFACE
2012-04-10 05:14:00 +00:00
/usr/bin/touch /var/lib/dhcpcd/dhcpcd-\$IFACE.info
2011-10-18 07:08:12 +00:00
2010-09-17 09:54:47 +00:00
netstart \$IFACE
2010-01-26 12:10:16 +00:00
while ! ifconfig | grep inet; do
echo -e "\${RED}Failed to acquire address, retrying \${RESET}"
sleep 1
2010-09-17 09:54:47 +00:00
netstart \$IFACE
2010-01-26 12:10:16 +00:00
done
2012-12-12 07:50:29 +00:00
# Add a fake interface configuration file for the boot interface to skip the
# ifdown of the interface during the reboot/shutdown to skip the fs broken of
# nfs based file system
echo "STARTMODE=nfsroot" > /tmp/ifcfg-\$IFACE
2008-05-26 16:11:24 +00:00
ip addr add dev lo 127.0.0.1/8
ip link set lo up
2013-06-17 15:13:41 +00:00
XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'`
if [ -z \$XCATIPORT ]; then
XCATIPORT="3002"
fi
if [ \$NODESTATUS != 'n' ]; then
/tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting"
fi
2008-05-24 17:29:40 +00:00
cd /
for i in `cat /proc/cmdline`; do
KEY=`echo \$i |awk -F= '{print \$1}'`
if [ "\$KEY" == 'imgurl' ]; then
VALUE=`echo \$i |awk -F= '{print \$2}'`
if [ "http" == "`echo \$VALUE|awk -F: '{print \$1}'`" ]; then
#NOTE needs FT retry code to scale
#NOTE: should prob have max count
FILENAME=`echo \$VALUE|awk -F/ '{print \$NF}'`
while [ ! -r "\$FILENAME" ]; do
echo Getting \$VALUE...
if ! wget \$VALUE; then
sleep 5 #should be random, exponential for scale
rm -f \$FILENAME
fi
done
fi
2010-01-26 12:10:16 +00:00
elif [[ "\$KEY" == NFSROOT ]]; then # for NFSROOT
NFSROOT=1
VALUE=`echo \$i |awk -F= '{print \$2}'`
SERVER=`echo \$VALUE|awk -F: '{print \$1}'`
ROOTDIR=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'`
2010-02-11 02:24:48 +00:00
elif [ "\$KEY" == 'STATEMNT' ]; then
2011-01-06 06:54:06 +00:00
STATELITE=1
2010-09-17 09:54:47 +00:00
VALUE=`echo \$i |awk -F= '{print \$2}'`
2011-01-06 06:54:06 +00:00
# VALUE may be null
if [ ! -z \$VALUE ]; then
SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'`
SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'`
# may be that there is not server and just a directory.
if [ -z \$SNAPSHOTROOT ]; then
SNAPSHOTROOT=\$SNAPSHOTSERVER
SNAPSHOTSERVER=
fi
2010-09-17 09:54:47 +00:00
fi
fi
2008-05-24 17:29:40 +00:00
done
2010-01-26 12:10:16 +00:00
# show xCAT logo
fancydisplay
2011-01-06 06:54:06 +00:00
# Statelite code is here
if [ "\$STATELITE" = "1" ]; then
2010-01-26 12:10:16 +00:00
echo Setting up Statelite
mknod /dev/loop0 b 7 0
mkdir -p \$NEWROOT
2010-08-12 03:24:40 +00:00
MAXTRIES=15
2010-01-26 12:10:16 +00:00
ITER=0
ME=`hostname`
2011-01-06 06:54:06 +00:00
if [ "\$NFSROOT" = "1" ]; then
while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do
ITER=\$(expr \$ITER + 1)
if [ "\$ITER" = "\$MAXTRIES" ]; then
echo "You're dead. rpower \$ME boot to play again."
echo "Possible problems:
1. This initrd wan't created for the statelite node?
2. IS DNS set up? Maybe that's why I can't mount \${SERVER}.
3. The nfs modules aren't set right in this initial ramdisk?"
shell
exit
fi
echo -e "\${RED}Couldn't mount \$SERVER:\$ROOTDIR on \$NEWROOT \$RESET"
RS=\$(expr \$RANDOM % 30)
echo -e "Trying again in \$RS seconds"
sleep \$RS
done
else
# for statelite mode on top of the ramdisk
EOMS
2012-06-07 06:13:32 +00:00
2011-01-06 06:54:06 +00:00
print $inifile "if [ -r /rootimg-statelite.gz ]; then \n";
print $inifile "echo Setting up RAM-root tmpfs.\n";
if ($rootlimit) {
2011-06-21 02:58:55 +00:00
print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n";
2011-01-06 06:54:06 +00:00
} else {
print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT \n";
}
2010-01-26 12:10:16 +00:00
2011-01-06 06:54:06 +00:00
print $inifile <<EOMS;
cd \$NEWROOT
echo -n "Extracting root file system:"
if [ -x /bin/cpio ]; then
gzip -cd /rootimg-statelite.gz | /bin/cpio -idum
else
gzip -cd /rootimg-statelite.gz | cpio -idum
fi
echo "Done"
else
echo -e "\${RED} Couldn't find rootimg-statelite.gz for statelite semantics on top of ramdisk \${RESET}"
shell
exit
fi
fi
2010-01-26 12:10:16 +00:00
# now we need to mount the rest of the system. This is the read/write portions
#echo "Mounting Snapshot directories"
if [ ! -e "\$NEWROOT/\$RWDIR" ]
then
echo ""
echo -e "\${RED}Hmmm... this NFS root directory doesn't have a /\$RWDIR directory for me to mount a rw filesystem. You'd better create it... \${NORMAL}"
echo "."
shell
fi
while [ ! -e "\$NEWROOT/etc/init.d/statelite" ]
do
echo ""
echo -e "\${RED}Hmmm... \$NEWROOT/etc/init.d/statelite doesn't exist. Perhaps you didn't create this image with the -m statelite mode"
echo ""
shell
done
grep '\\(shell\\)' /proc/cmdline >/dev/null && shell
2010-03-05 08:00:51 +00:00
mount -t tmpfs rw -o mode=$permission \$NEWROOT/\$RWDIR
2010-01-26 12:10:16 +00:00
mkdir -p \$NEWROOT/\$RWDIR/tmpfs
2010-03-05 08:00:51 +00:00
#mount the /root/.ssh, it needs more strict permission in order for ssh work
2010-09-17 09:54:47 +00:00
#if [ ! -e "\$NEWROOT/root/.ssh" ]
#then
# mkdir -p \$NEWROOT/root/.ssh
#fi
#mount -t tmpfs -o mode=755 ssh \$NEWROOT/root/.ssh
2010-02-11 02:24:48 +00:00
2010-01-26 12:10:16 +00:00
# mount the SNAPSHOT directory here for persistent use.
if [ ! -z \$SNAPSHOTSERVER ]
then
mkdir -p \$NEWROOT/\$RWDIR/persistent
MAXTRIES=5
ITER=0
This is to enable client to indicate options when mounting persistent directories on statelite(nfs/ramdisk) CNs, if not, "nolock,tcp" will be used as default options. This implementation aims for SLES11.
client can revise the statelite table to benefit from this, like:
#node,image,statemnt,mntopts,comments,disable
"935n02",,"192.168.0.244:/tmp","soft,timeo=200",,
------------------------------------------------------
Another change in sles.pm: we do insmod for net interfaces (ibmveth, ehea, etc...) after all other modules, to avoid failure when do 'netstart' during installation.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9817 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2011-06-16 03:06:56 +00:00
while ! mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT \$NEWROOT/\$RWDIR/persistent -o nolock,\$XCATMNTOPTS
2010-01-26 12:10:16 +00:00
do
ITER=\$(expr \$ITER + 1)
if [ "\$ITER" == "\$MAXTRIES" ]
then
echo "You're dead. rpower \$ME boot to play again."
echo "Possible problems:
1. \$SNAPSHOTSERVER is not exporting \$SNAPSHOTROOT ?
2. Is DNS set up? Maybe that's why I can't mount \$SNAPSHOTSERVER."
shell
exit
fi
This is to enable client to indicate options when mounting persistent directories on statelite(nfs/ramdisk) CNs, if not, "nolock,tcp" will be used as default options. This implementation aims for SLES11.
client can revise the statelite table to benefit from this, like:
#node,image,statemnt,mntopts,comments,disable
"935n02",,"192.168.0.244:/tmp","soft,timeo=200",,
------------------------------------------------------
Another change in sles.pm: we do insmod for net interfaces (ibmveth, ehea, etc...) after all other modules, to avoid failure when do 'netstart' during installation.
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@9817 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2011-06-16 03:06:56 +00:00
echo -e "\${RED}Hmmm... Can't mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT. \${NORMAL} \$XCATMNTOPTS"
2010-01-26 12:10:16 +00:00
RS=`expr \$RANDOM % 20`
echo -e "Trying again in \$RS seconds"
sleep \$RS
done
fi
grep '\\(shell\\)' /proc/cmdline >/dev/null && shell
# have to preserve the initial DHCP request. So we link it.
# SLES uses different file to store DHCP info
if [ ! -d \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcpcd ]
then
mkdir -p \$NEWROOT/\$RWDIR/tmpfs/var/lib/dhcpcd
fi
2010-09-17 09:54:47 +00:00
cp -fp /var/lib/dhcpcd/dhcpcd-\$IFACE.info \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhcpcd/dhcpcd-\$IFACE.info
2010-01-26 12:10:16 +00:00
[ -e /etc/ntp.conf ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc && cp /etc/ntp.conf \$NEWROOT/\$RWDIR/tmpfs/etc/
[ -e /etc/resolv.conf ] && mkdir -p \$NEWROOT/\$RWDIR/tmpfs/etc && cp /etc/resolv.conf \$NEWROOT/\$RWDIR/tmpfs/etc/
# now that everything is mounted, lets do this
# hmmm, apparently I'm checking this twice... so I'd better
# be really sure the file is there.
2010-06-18 02:59:31 +00:00
while [ ! -e \$NEWROOT/etc/init.d/statelite ]
2010-01-26 12:10:16 +00:00
do
echo "\$NEWROOT/etc/init.d/statelite does not exist in image!"
shell
done
2012-11-16 14:02:36 +00:00
# try to configure the local disk
\$NEWROOT/etc/init.d/localdisk
2010-01-26 12:10:16 +00:00
# do all the mounts:
\$NEWROOT/etc/init.d/statelite
2012-11-16 14:02:36 +00:00
EOMS
# udevd needed by s390x for networking
# but for other type of machine, udevd will affect the start of devices which detected
# after the chroot, so kill it before the switching root
if ($arch ne "s390x") {
print $inifile "\n killall -9 udevd\n";
}
print $inifile <<EOMS;
2010-01-26 12:10:16 +00:00
# give the debug shell just before we go if specified!
grep '\(shell\)' /proc/cmdline > /dev/null && shell
echo 0x100 > /proc/sys/kernel/real-root-dev
export keep_old_ip=yes
export fastboot=yes
export READONLY=yes
grep '\\(shell\\)' /proc/cmdline >/dev/null && shell
mount -n --bind /dev /sysroot/dev
umount /sys
umount /proc
# sles use the standard utility to chroot
if ! exec /usr/bin/chroot \$NEWROOT /sbin/init
then
echo ""
echo -e "\${RED}Couldn't chroot. Something must be wrong with NFS root image.\${RESET}"
shell
fi
exit
fi
# end NFSROOT/Statelite code
2010-09-17 09:54:47 +00:00
if [ -r /rootimg.sfs ]; then
2008-05-24 17:29:40 +00:00
echo Setting up squashfs with ram overlay.
mknod /dev/loop0 b 7 0
mkdir -p /ro
mkdir -p /rw
mount -t squashfs /rootimg.sfs /ro
mount -t tmpfs rw /rw
mount -t aufs -o dirs=/rw:/ro mergedroot /sysroot
mkdir -p /sysroot/ro
mkdir -p /sysroot/rw
mount --move /ro /sysroot/ro
mount --move /rw /sysroot/rw
EOMS
print $inifile "elif [ -r /rootimg.gz ]; then\n";
print $inifile "echo Setting up RAM-root tmpfs.\n";
if ($rootlimit) {
2011-06-21 02:58:55 +00:00
print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT\n";
2008-05-24 17:29:40 +00:00
} else {
2011-01-06 06:54:06 +00:00
print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n";
2008-05-24 17:29:40 +00:00
}
print $inifile " cd /sysroot\n";
print $inifile " echo -n \"Extracting root filesystem:\"\n";
print $inifile " if [ -x /bin/cpio ]; then\n";
print $inifile " zcat /rootimg.gz |/bin/cpio -idum\n";
print $inifile " else\n";
print $inifile " zcat /rootimg.gz |cpio -idum\n";
print $inifile " fi\n";
print $inifile " echo Done\n";
print $inifile "else\n";
print $inifile " echo -n Failed to download image, panicing in 5...\n";
print $inifile " for i in 4 3 2 1 0; do\n";
print $inifile " /bin/sleep 1\n";
print $inifile " echo -n \$i...\n";
print $inifile " done\n";
print $inifile " echo\n";
2010-09-17 09:54:47 +00:00
print $inifile <<EOMS;
echo "You're dead. rpower nodename reset to play again.
2008-05-24 17:29:40 +00:00
2010-09-17 09:54:47 +00:00
* Did you packimage with -m cpio or -m squashfs?
2008-05-24 17:29:40 +00:00
* If using -m squashfs did you include aufs.ko with geninitrd?
e.g.: -n tg3,squashfs,aufs,loop
"
2010-09-17 09:54:47 +00:00
sleep 5
2008-05-24 17:29:40 +00:00
EOMS
print $inifile " exit\n";
print $inifile "fi\n";
2012-11-16 14:02:36 +00:00
# udevd needed by s390x for networking
# but for other type of machine, udevd will affect the start of devices which detected
# after the chroot, so kill it before the switching root
if ($arch ne "s390x") {
print $inifile "killall -9 udevd\n";
}
2008-05-24 17:29:40 +00:00
print $inifile "cd /\n";
2013-05-13 09:22:56 +00:00
print $inifile "\$NEWROOT/etc/init.d/localdisk\n"; # to run the localdisk
2011-01-06 06:54:06 +00:00
print $inifile "mkdir \$NEWROOT/var/lib/dhcpcd/\n"; #neccessary for SLES11, not sure for SLES10
print $inifile "cp /var/lib/dhcpcd/* \$NEWROOT/var/lib/dhcpcd/\n";
print $inifile "cp /etc/resolv.conf \$NEWROOT/etc/\n";
print $inifile "cp /etc/HOSTNAME \$NEWROOT/etc/\n";
print $inifile "mknod \$NEWROOT/dev/console c 5 1\n";
print $inifile "exec /lib/mkinitrd/bin/run-init -c /dev/console \$NEWROOT /sbin/init\n";
2008-05-24 17:29:40 +00:00
close($inifile);
open($inifile,">"."/tmp/xcatinitrd.$$/bin/netstart");
2010-09-17 09:54:47 +00:00
print $inifile "#!/bin/bash \n";
2013-01-15 13:11:41 +00:00
if ($osver_host == 10) {
print $inifile "dhcpcd \${1}\n";
} else { # for sles11 or higher
# -p is used to keep the network connection during the shutdown. Used for nfs-based statelite shutdown
print $inifile "dhcpcd \${1} -p\n";
}
Allows diskless nodes to boot via other interfaces aside of primary boot interface, ie. provides ethernet failover.
1) In initrd, bring up aside from main interface (genimage -i option) also other interfaces (-r option).
2) /etc/resolv.conf creation needed to be rewritten, othewise it gets confused by several dhcpcd records.
3) Fill database with MAC addresses for all interfaces. Since it't not possible to have several stanzas of the same name in dhcpd.conf, we need to define unique "alias" for every interface. For example, for host "host1" we will add '00:1A:64:5D:1B:84!host1e0|00:1A:64:5D:1B:86!host1e1' to macs table. Of course, this aliases have to be defined in DNS, otherwise makedhcp command will not use this aliases:
/etc/hosts:
10.217.249.232 host1 host1e0 host1e1
Since this are aliases (need not be nessesary), both interfaces get the same IP address during initrd, but this doesn't break anything.
a) blades - changed getmacs function to gather all MAC addresses. Which interfaces we are interested in are defined in noderes.installnic or noderes.primarynic as "eth0|eth1".
b) all other - TODO. We have only 8 non-blade nodes, so we fill database manually.
Backwards compatible:
- if there is only one interface in noderes.installnic, getmacs function gathers only this one MAC address
- if we run genimage without -r option, only one interface is brought up
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2124 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
2008-09-10 15:04:32 +00:00
#-- Bring other NICs up in /bin/netstart in initrd for NIC failover
foreach (split /,/,$othernics) {
if (/^$/) { next; }
print $inifile "dhcpcd $_\n";
}
print $inifile <<END;
cat /var/lib/dhcpcd/*info | grep HOSTNAME | uniq | awk -F= '{print \$2}'| sed \"s/'//g\" >> /etc/HOSTNAME
END
2008-05-27 20:20:15 +00:00
2008-05-24 17:29:40 +00:00
close($inifile);
2013-06-17 15:13:41 +00:00
#if "nonodestatus" specified,do not update the nodestatus
system("mkdir -p /tmp/xcatinitrd.$$/tmp/");
open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag");
print $inifile <<EOMS;
#!/usr/bin/awk -f
BEGIN {
xcatdhost = ARGV[1]
xcatiport = ARGV[2]
ns = "/inet/tcp/0/" xcatdhost "/" xcatiport
print "xCAT_xcatd" |& ns
while(1) {
ns |& getline
if(\$0 == "ready")
print ARGV[3] |& ns
if(\$0 == "done")
break
}
close(ns)
exit 0
}
EOMS
2013-06-19 07:32:34 +00:00
close($inifile);
chmod(0755,"/tmp/xcatinitrd.$$/init");
chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart");
chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag");
2013-06-17 15:13:41 +00:00
2008-05-24 17:29:40 +00:00
@filestoadd=();
foreach (@ndrivers) {
2008-09-11 22:03:01 +00:00
if (-f "$customdir/$_") {
2008-05-24 17:29:40 +00:00
push @filestoadd,[$_,"lib/$_"];
2008-09-11 22:03:01 +00:00
} elsif (-f "$pathtofiles/$_") {
push @filestoadd,[$_,"lib/$_"];
}
2008-05-24 17:29:40 +00:00
}
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
2012-11-16 14:02:36 +00:00
foreach ("sbin/ifconfig", "usr/bin/clear","usr/bin/touch","bin/hostname","usr/bin/egrep","bin/ln","bin/ls","usr/bin/dirname","usr/bin/expr","usr/bin/chroot","usr/bin/grep","bin/cpio","bin/sleep","bin/mount","bin/umount","sbin/dhcpcd","bin/bash","sbin/insmod","bin/mkdir","bin/mknod","sbin/ip","bin/cat","usr/bin/awk","usr/bin/wget","bin/cp","usr/bin/cpio","usr/bin/zcat","usr/bin/gzip","lib/mkinitrd/bin/run-init","usr/bin/uniq","usr/bin/sed","usr/bin/wc", "bin/sed","sbin/udevd", "usr/bin/readlink", "usr/sbin/parted", "sbin/mke2fs", "sbin/mkswap", "sbin/swapon", "bin/chmod", "usr/bin/bc") {
2010-01-26 12:10:16 +00:00
getlibs($_);
push @filestoadd,$_;
}
2011-10-18 07:08:12 +00:00
if($osver_host == 11) {
foreach ("sbin/mount.nfs", "sbin/umount.nfs", "sbin/udevadm") {
getlibs($_);
push @filestoadd,$_;
}
}
2010-06-16 00:09:21 +00:00
2010-01-26 12:10:16 +00:00
}else {
2013-05-13 09:22:56 +00:00
foreach ("sbin/ifconfig","usr/bin/clear","usr/bin/touch","usr/bin/grep","usr/bin/egrep","bin/cpio","bin/sleep","bin/mount","sbin/dhcpcd","bin/bash","sbin/insmod","bin/mkdir","bin/mknod","sbin/ip","bin/cat","usr/bin/awk","usr/bin/wget","bin/cp","usr/bin/cpio","usr/bin/zcat","usr/bin/gzip","lib/mkinitrd/bin/run-init","usr/bin/uniq","usr/bin/sed","sbin/udevd", "usr/bin/readlink", "usr/bin/expr", "usr/sbin/parted", "sbin/mke2fs", "sbin/mkswap", "sbin/swapon", "bin/chmod", "usr/bin/bc") {
2010-03-31 09:17:51 +00:00
getlibs($_);
2010-01-26 12:10:16 +00:00
push @filestoadd,$_;
}
2011-10-18 07:08:12 +00:00
if($osver_host == 11) {
getlibs("sbin/udevadm");
push @filestoadd,"sbin/udevadm";
}
2010-01-26 12:10:16 +00:00
}
2011-10-18 07:08:12 +00:00
2013-04-24 07:57:24 +00:00
if ($arch =~ /64/) {
2008-05-24 17:29:40 +00:00
push @filestoadd,"lib64/libnss_dns.so.2";
2013-04-08 08:23:14 +00:00
push @filestoadd,"lib64/libnss_files.so.2";
2008-05-24 17:29:40 +00:00
}
else {
push @filestoadd,"lib/libnss_dns.so.2";
2013-04-08 08:23:14 +00:00
push @filestoadd,"lib/libnss_files.so.2";
2008-05-24 17:29:40 +00:00
}
2010-03-31 09:17:51 +00:00
# cross-platfrom support on power6&7 etc
# ldd can't handle such one scenario: mn is power6, the target platform is power7
if ($arch =~ /ppc64/) {
2010-08-13 09:09:06 +00:00
system("cp -a -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64/");
2010-03-31 09:17:51 +00:00
}
2008-05-24 17:29:40 +00:00
push @filestoadd,keys %libhash;
2011-03-28 07:39:59 +00:00
2009-09-24 18:51:53 +00:00
find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>);
2012-10-15 06:40:00 +00:00
my $pathonrootimage = "$rootimg_dir/tmpfiles";
my $pathinrootimage = "/tmpfiles";
mkpath($pathonrootimage);
2008-05-24 17:29:40 +00:00
foreach (@filestoadd) {
if (ref($_)) {
2008-09-11 22:03:01 +00:00
#print "$_->[0], $_->[1]\n";
2012-10-15 06:40:00 +00:00
my $srcfile = $_->[0];
system("chroot $rootimg_dir cp $srcfile $pathinrootimage");
my $srcpath = "$pathonrootimage/".basename($_->[0]);
2008-09-11 22:03:01 +00:00
if (-f "$customdir/".$_->[0]) {
$srcpath="$customdir/".$_->[0];
} elsif (-f "$pathtofiles/".$_->[0]) {
2008-05-24 17:29:40 +00:00
$srcpath="$pathtofiles/".$_->[0];
}
2012-10-15 06:40:00 +00:00
mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1]));
2008-05-24 17:29:40 +00:00
copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]);
chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1];
} else {
2008-09-11 22:03:01 +00:00
#print "$_\n";
2012-10-15 06:40:00 +00:00
system("chroot $rootimg_dir cp $_ $pathinrootimage");
my $srcpath = "$pathonrootimage/".basename($_);
2008-09-11 22:03:01 +00:00
if (-f "$customdir/$_") {
$srcpath = "$customdir/$_";
} elsif (-f "$pathtofiles/$_") {
2008-09-09 23:52:04 +00:00
$srcpath = "$pathtofiles/$_";
2008-05-24 17:29:40 +00:00
}
2012-10-15 06:40:00 +00:00
mkpath(dirname("/tmp/xcatinitrd.$$/$_"));
2008-05-24 17:29:40 +00:00
copy("$srcpath","/tmp/xcatinitrd.$$/$_");
chmod 0755,"/tmp/xcatinitrd.$$/".$_;
}
}
2012-10-15 06:40:00 +00:00
rmtree($pathonrootimage);
2008-05-24 17:29:40 +00:00
2012-10-15 06:40:00 +00:00
#copy conf files needed by nfs mount in sles11.2
if($osver_host == 11)
{
system("cp -r $rootimg_dir/etc/protocols /tmp/xcatinitrd.$$/etc/");
system("cp -r $rootimg_dir/etc/netconfig /tmp/xcatinitrd.$$/etc/");
}
# Copy udev libraries
system("mkdir -p /tmp/xcatinitrd.$$/etc/udev");
system("mkdir -p /tmp/xcatinitrd.$$/lib/firmware");
system("cp -r $rootimg_dir/etc/udev/* /tmp/xcatinitrd.$$/etc/udev");
system("cp -r $rootimg_dir/bin/uname /tmp/xcatinitrd.$$/bin/");
if ( -d "$rootimg_dir/lib/firmware/" ) {
system("cp -r $rootimg_dir/lib/firmware/* /tmp/xcatinitrd.$$/lib/firmware");
}
system("cp -r $rootimg_dir/usr/bin/killall /tmp/xcatinitrd.$$/usr/bin");
2011-02-17 07:13:23 +00:00
# Copy rules for network adapter
2012-04-23 20:52:58 +00:00
#my $name = `cat /etc/sysconfig/network/ifcfg-$prinic | grep NAME`;
#my $nic = '';
#if ($name =~ m/(\d+\.\d+\.\d+)/g) {
# $nic = $&;
#}
2011-10-18 07:08:12 +00:00
2011-11-21 01:52:33 +00:00
# Somehow checking for *$nic.rules does not work
#if ( -f "/etc/udev/rules.d/*$nic.rules" ) {
2012-04-23 20:52:58 +00:00
# system("cp -r /etc/udev/rules.d/*$nic.rules /tmp/xcatinitrd.$$/etc/udev/rules.d");
2011-11-21 01:52:33 +00:00
#}
#if ( -f "/etc/udev/rules.d/*persistent-net.rules" ) {
2012-04-23 20:52:58 +00:00
# system("cp -r /etc/udev/rules.d/*persistent-net.rules /tmp/xcatinitrd.$$/etc/udev/rules.d");
2011-11-21 01:52:33 +00:00
#}
2011-02-17 07:13:23 +00:00
2012-10-15 06:40:00 +00:00
system("mkdir -p /tmp/xcatinitrd.$$/lib/udev");
system("cp -r $rootimg_dir/lib/udev/* /tmp/xcatinitrd.$$/lib/udev");
2010-06-16 00:09:21 +00:00
2009-09-24 18:51:53 +00:00
#copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_");
2009-02-12 12:04:51 +00:00
system("cd /tmp/xcatinitrd.$$/bin/; ln -sf bash sh"); #neccessary for SLES11
2010-09-17 09:54:47 +00:00
if ($mode eq "statelite") {
system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-statelite.gz");
print "The initial ramdisk for statelite has been generated successfully!\n";
} else {
system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-stateless.gz");
print "The initial ramdisk for statelite has been generated successfully!\n";
}
2008-05-24 17:29:40 +00:00
system("rm -rf /tmp/xcatinitrd.$$");
}
sub isyumdir {
if ($File::Find::name =~ /\/repodata$/) {
my $location = $File::Find::name;
$location =~ s/\/repodata$//;
push @yumdirs,$location;
}
}
sub isnetdriver {
foreach (@ndrivers) {
if ($File::Find::name =~ /\/$_/) {
my $filetoadd = $File::Find::name;
2009-09-24 18:51:53 +00:00
$filetoadd =~ s!$rootimg_dir!!;
2008-05-24 17:29:40 +00:00
push @filestoadd,[$filetoadd,"lib/$_"];
}
}
}
sub postscripts { # TODO: customized postscripts
2010-09-17 09:54:47 +00:00
generic_post();
unless( -d "$rootimg_dir/opt/xcat/") {
mkdir "$rootimg_dir/opt/xcat/";
2010-01-26 12:10:16 +00:00
}
2010-09-17 09:54:47 +00:00
copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/"); #TODO: it is not used in stateless
chmod '0755', "$rootimg_dir/opt/xcat/xcatdsklspost";
2008-05-24 17:29:40 +00:00
}
2010-09-17 09:54:47 +00:00
sub generic_post { # This function is meant to leave the image in a state approximating a normal install
my $cfgfile;
2013-04-24 07:57:24 +00:00
#modify /etc/sysconfig/clock in the image:HWCLOCK="--local", TIMEZONE=site:timezone
if ($timezone) {
system("sed -i '".'s!\(TIMEZONE=\).*!\1'."\"$timezone\"!"."' $rootimg_dir/etc/sysconfig/clock");
system("chroot $rootimg_dir zic -l $timezone");
}
system("sed -i 's!\\(HWCLOCK=\\).*!\\1\"--localtime\"!' $rootimg_dir/etc/sysconfig/clock");
2010-09-17 09:54:47 +00:00
unlink("$rootimg_dir/dev/null");
system("mknod $rootimg_dir/dev/null c 1 3");
open($cfgfile,">","$rootimg_dir/etc/fstab");
print $cfgfile "devpts /dev/pts devpts gid=5,mode=620 0 0\n";
print $cfgfile "tmpfs /dev/shm tmpfs defaults 0 0\n";
print $cfgfile "proc /proc proc defaults 0 0\n";
print $cfgfile "sysfs /sys sysfs defaults 0 0\n";
if ($tmplimit) {
print $cfgfile "tmpfs /tmp tmpfs defaults,size=$tmplimit 0 2\n";
print $cfgfile "tmpfs /var/tmp tmpfs defaults,size=$tmplimit 0 2\n";
} else {
print $cfgfile "tmpfs /tmp tmpfs defaults,size=10m 0 2\n";
print $cfgfile "tmpfs /var/tmp tmpfs defaults,size=10m 0 2\n";
}
my $rootfs_name = $profile."_".$arch;
print $cfgfile "$rootfs_name / tmpfs rw 0 1\n";
close($cfgfile);
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network");
print $cfgfile "NETWORKING=yes\n";
close($cfgfile);
open($cfgfile,">","$rootimg_dir/etc/resolv.conf");
print $cfgfile "#Dummy resolv.conf to make boot cleaner";
close($cfgfile);
2011-07-15 11:14:59 +00:00
# Create the ifcfg-x file for diskless node. But keep the ONBOOT=no
# to skip the break of nfs-based boot
if ($prinic) {
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$prinic");
print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\nSTARTMODE=auto\n";
close($cfgfile);
}
2010-09-17 09:54:47 +00:00
foreach (split /,/,$othernics) {
next if (/^$/);
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$_");
print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\nSTARTMODE=auto\n";
2010-01-26 12:10:16 +00:00
close($cfgfile);
}
2010-06-16 00:09:21 +00:00
2012-10-15 06:40:00 +00:00
# securetty not needed on s390x
if ($arch ne "s390x") {
open( $cfgfile, ">>", "$rootimg_dir/etc/securetty" );
print $cfgfile "ttyS0\n";
print $cfgfile "ttyS1\n";
print $cfgfile "console\n";
close($cfgfile);
}
2010-06-16 00:09:21 +00:00
2010-09-17 09:54:47 +00:00
my @passwd;
open($cfgfile,"<","$rootimg_dir/etc/passwd");
@passwd = <$cfgfile>;
close($cfgfile);
open($cfgfile,">","$rootimg_dir/etc/passwd");
foreach (@passwd) {
if (/^root:/) {
s/^root:\*/root:x/;
}
print $cfgfile $_;
}
close($cfgfile);
foreach (<$rootimg_dir/etc/skel/.*>) {
next if (basename($_) eq '.' or basename($_) eq '..');
copy $_,"$rootimg_dir/root/";
}
2010-06-16 00:09:21 +00:00
# gettyset is not found on s390x
if ($arch ne "s390x") {
open( $cfgfile, ">", "$rootimg_dir/etc/init.d/gettyset" );
print $cfgfile "#!/bin/bash\n";
print $cfgfile "### BEGIN INIT INFO\n";
print $cfgfile "# Provides: gettyset\n";
print $cfgfile "# Required-Start: sshd\n";
print $cfgfile "# Required-Stop:\n";
print $cfgfile "# Default-Start: 3\n";
print $cfgfile "# Default-Stop: 0 1 2 6\n";
print $cfgfile "# Short-Description: gettyset\n";
print $cfgfile "# Description:\n";
print $cfgfile "### END INIT INFO\n";
2013-01-15 13:11:41 +00:00
print $cfgfile "VERS=`grep VERSION /etc/SuSE-release`\n";
print $cfgfile "if [ -n \"\$VERS\" ]; then\n";
print $cfgfile " VERNUM=`echo \$VERS|awk -F= \'{print \$2}\'|sed -e \'s/ //g\'`\n";
print $cfgfile "fi\n";
print $cfgfile "if [ \"\$VERNUM\" -gt 10 ]; then\n";
print $cfgfile " exit\n";
print $cfgfile "fi\n";
print $cfgfile "\n";
2010-06-16 00:09:21 +00:00
print $cfgfile "for i in `cat /proc/cmdline`; do\n";
print $cfgfile ' KEY=`echo $i|cut -d= -f 1`' . "\n";
print $cfgfile " if [ \"\$KEY\" == \"console\" -a \"\$i\" != \"console=tty0\" ]; then\n";
print $cfgfile " VALUE=`echo \$i | cut -d= -f 2`\n";
print $cfgfile " COTTY=`echo \$VALUE|cut -d, -f 1`\n";
print $cfgfile " COSPEED=`echo \$VALUE|cut -d, -f 2|cut -dn -f 1`\n";
print $cfgfile " if echo \$VALUE | grep n8r; then\n";
print $cfgfile " FLOWFLAG=\"-h\"\n";
print $cfgfile " fi\n";
print $cfgfile " echo xco:2345:respawn:/sbin/agetty \$FLOWFLAG \$COTTY \$COSPEED xterm >> /etc/inittab\n";
print $cfgfile " init q\n";
print $cfgfile " fi\n";
print $cfgfile "done\n";
print $cfgfile "/etc/init.d/boot.localnet start\n";
close($cfgfile);
chmod( 0755, "$rootimg_dir/etc/init.d/gettyset" );
}
2010-07-14 09:57:05 +00:00
copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit");
chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit");
2012-11-09 03:45:35 +00:00
#insserv with -f option to ignore the dependency on sles10.4
system("chroot $rootimg_dir insserv -f network sshd gettyset xcatpostinit");
2011-10-18 07:08:12 +00:00
my $rc = system("grep sshd $rootimg_dir/etc/init.d/.depend.start | grep TARGETS");
2010-09-17 09:54:47 +00:00
if ($rc) {
system("sed -i '".'s/^\(TARGETS = .*\)$/\1 sshd/'."' $rootimg_dir/etc/init.d/.depend.start");
system("ln -s ../sshd $rootimg_dir/etc/init.d/rc3.d/S20sshd");
}
2011-10-18 07:08:12 +00:00
my $rc = system("grep gettyset $rootimg_dir/etc/init.d/.depend.start | grep TARGETS");
2010-09-17 09:54:47 +00:00
if ($rc) {
system("sed -i '".'s/^\(TARGETS = .*\)$/\1 gettyset/'."' $rootimg_dir/etc/init.d/.depend.start");
system("ln -s ../gettyset $rootimg_dir/etc/init.d/rc3.d/S60gettyset");
}
2008-05-24 17:29:40 +00:00
}
2008-09-09 23:52:04 +00:00
2009-10-06 20:21:11 +00:00
2010-08-12 09:05:51 +00:00
my $driver_name;
my $real_path;
sub get_path ()
{
if ($File::Find::name =~ /\/$driver_name/) {
$real_path = $File::Find::name;
}
}
2012-07-05 14:59:08 +00:00
my @all_real_path;
sub get_all_path ()
{
if ($File::Find::name =~ /\/$driver_name/) {
push @all_real_path, $File::Find::name;
}
}
# Load driver disk and driver rpm to the initrd
# Get the driver disk or driver rpm from the osimage.driverupdatesrc
# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm'
# the 'rpm' is default.
#
# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk
# from /install/driverdisk/<os>/<arch>
#
# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver
# rpm to the initrd.
#
# Return the driver names by loading order
2010-08-12 09:05:51 +00:00
sub load_dd()
{
2012-07-05 14:59:08 +00:00
my @dd_list;
my @rpm_list;
my @driver_list;
2012-10-16 05:58:29 +00:00
my $Injectalldriver;
2012-07-05 14:59:08 +00:00
my @rpm_drivers;
# Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well
if ($driverupdatesrc) {
my @srcs = split(',', $driverupdatesrc);
foreach my $src (@srcs) {
if ($src =~ /dud:(.*)/i) {
push @dd_list, $1;
} elsif ($src =~ /rpm:(.*)/i) {
push @rpm_list, $1;
} else {
push @rpm_list, $src;
}
}
}
if (! @dd_list) {
# get Driver update disk from the default path if not specified in osimage
# check the Driver Update Disk images, it can be .img or .iso
if (-d "$installroot/driverdisk/$osver/$arch") {
@dd_list = `find $installroot/driverdisk/$osver/$arch -type f`;
}
}
foreach (split /,/,$netdriver) {
2012-10-16 05:58:29 +00:00
if (/^allupdate$/) {
$Injectalldriver = 1;
next;
}
2012-07-05 14:59:08 +00:00
unless (/\.ko$/) {
s/$/.ko/;
}
push @driver_list, $_;
2010-08-12 09:05:51 +00:00
}
chomp(@dd_list);
2012-07-05 14:59:08 +00:00
chomp(@rpm_list);
2010-08-12 09:05:51 +00:00
2012-10-16 05:58:29 +00:00
unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) {
2012-10-15 06:40:00 +00:00
return ();
2010-08-12 09:05:51 +00:00
}
# Create the work space, it should be cleaned at end of genimage
2010-08-23 08:00:51 +00:00
my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX");
2010-08-12 09:05:51 +00:00
mkpath "$dd_dir/mnt";
mkpath "$dd_dir/mods";
2012-07-05 14:59:08 +00:00
my @dd_drivers = (); #driver names
2010-08-12 09:05:51 +00:00
# Load drivers from each Driver Disk
# For multiple dd, if want to make it has order, rename the dd with a number
# ahead of the name like 0_xx, 1_xx
foreach my $dd (sort(@dd_list)) {
my $rc = system ("mount -o loop $dd $dd_dir/mnt");
if ($rc) {
print "mount the Driver Disk $dd failed.\n";
next;
}
mkpath "$dd_dir/full";
# Copy out the drivers
opendir(DIR, "$dd_dir/mnt") || die "Cannot open dir $dd_dir/mnt";
while (my $dir = readdir(DIR)) {
if ($dir =~ /^\./) { next; }
# Every driver update disk can have multiple directories, each directory
# has the directory format like /linux/[distribution]/[architechture]-[version]/
# If the directory name is numeric, then it will be used as order to load the
# the dirviers inside.
# For the directory name which is not numeric, copy them to directory 0. It will be
# loaled first.
if ($dir !~ /^\d*$/) {
mkpath "$dd_dir/full/0";
system ("cp -rf $dd_dir/mnt/$dir $dd_dir/full/0");
} else {
system ("cp -rf $dd_dir/mnt/$dir $dd_dir/full/");
}
}
closedir(DIR);
# Get all the kernel modules base on the order of directory name.
# The structure of dd: <order>/linux/[distribution]/[architechture]-[version]/
# The supported arch: i386, ia64, ppc, ppc64, s390, s390x sparc or x86_64.
my $darch = $arch;
if ($darch =~ /^x86$/) {
$darch = "i386";
}
# If the version is os version. If the os is "sles11.1", the possible os version
# could be "sles11.1", "11.1", "11", "sles11"
my @distro = ($osver);
my $distro1 = $osver;
$distro1 =~ s/[^\d]*//;
push @distro,$distro1;
my $distro2 = $distro1;
$distro2 =~ s/\..*//;
push @distro,$distro2;
my $distro3 = $osver;
$distro3 =~ s/\..*//;
push @distro,$distro3;
opendir (FDIR, "$dd_dir/full") || die "Cannot open dir $dd_dir/full";
my @fulldir = readdir(FDIR);
closedir (FDIR);
# Create the directory for drivers from driver disk
if (! -d "$rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk") {
mkpath "$rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk";
}
# Copy the drivers to the root image and get the driver loading order
foreach my $dir (sort(@fulldir)) {
if ($dir =~ /^\./) { next; }
my $vdir;
foreach (@distro) {
if (-d "$dd_dir/full/$dir/linux/suse/$darch-$_") {
$vdir = "$dd_dir/full/$dir/linux/suse/$darch-$_";
}
}
if (! $vdir) { next; }
# Use the module_order if it has
if (-f "$vdir/modules/module.order") {
open(ORDER, "<", "$vdir/modules/module.order");
while (my $file = <ORDER>) {
chomp ($file);
if (-f "$vdir/modules/$file") {
$driver_name = $file;
$real_path = "";
find(\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>);
if ($real_path eq "") {
system ("cp $vdir/modules/$file $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk");
} else {
system ("cp $vdir/modules/$file $real_path");
}
push @dd_drivers, $file;
}
}
} else {
opendir (MDIR, "$vdir/modules") || die "Cannot open dir $vdir/modules";
while (my $file = readdir(MDIR)) {
if (-f "$vdir/modules/$file" && $file =~ /\.ko/) {
$driver_name = $file;
$real_path = "";
find(\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>);
if ($real_path eq "") {
system ("cp $vdir/modules/$file $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk");
} else {
system ("cp $vdir/modules/$file $real_path");
}
push @dd_drivers, $file;
}
}
}
}
rmtree "$dd_dir/full";
my $rc = system ("umount -f $dd_dir/mnt");
if ($rc) {
print "umount the directory $dd_dir/mnt failed\n";
exit 1;
}
}
2012-07-05 14:59:08 +00:00
# Loading the drivers from rpm packages
2012-10-16 05:58:29 +00:00
if (@rpm_list && ($Injectalldriver || @driver_list)) {
2012-07-05 14:59:08 +00:00
# Extract the files from rpm to the tmp dir
mkpath "$dd_dir/rpm";
foreach my $rpm (@rpm_list) {
if (-r $rpm) {
if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) {
print "Error: Cannot extract the files from the rpm $rpm.\n";
}
} else {
print "Error: Cannot read the rpm $rpm.\n";
}
}
2012-11-28 08:59:49 +00:00
# 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
$driver_name = "\*ko.new";
@all_real_path = ();
find(\&get_all_path, <$dd_dir/rpm/*>);
foreach my $file (@all_real_path) {
my $newname = $file;
$newname =~ s/\.new$//;
if (system ("mv -f $file $newname")) {
print "Error: Could not rename $file\n";
}
}
2012-07-05 14:59:08 +00:00
# Copy the firmware to the rootimage
if (-d "$dd_dir/rpm/lib/firmware") {
system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib");
}
# Copy the drivers to the rootimage
if (-d "$dd_dir/rpm/lib/modules/$kernelver") {
#mkpath "$rootimg_dir/lib/modules/$kernelver/updates/";
if (@driver_list) {
foreach my $driver (@driver_list) {
$driver_name = $driver;
$real_path = "";
find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) {
2012-10-16 05:58:29 +00:00
# remove the old one if existing
@all_real_path = ();
find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>);
foreach (@all_real_path) {
if (-r $_) {
unlink ($_);
}
}
2012-07-05 14:59:08 +00:00
if (! -d "$rootimg_dir$1") {
mkpath "$rootimg_dir$1";
}
system ("cp -rf $real_path $rootimg_dir$1");
push @rpm_drivers, $driver;
} else {
print "Error: cannot find the driver $driver from the driver rpms\n";
}
}
2012-10-16 05:58:29 +00:00
} elsif ($Injectalldriver) {
2012-07-05 14:59:08 +00:00
# copy all the drviers to the rootimage
find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
2012-10-16 05:58:29 +00:00
my @all_drivers = @all_real_path;
foreach my $new_driver (@all_drivers) {
if (basename($new_driver) =~ /\.ko$/) {
# remove the old one if existing
$driver_name = basename($new_driver);
@all_real_path = ();
find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>);
foreach my $old_driver (@all_real_path) {
if (-r $old_driver) {
unlink ($old_driver);
}
}
push @rpm_drivers, basename($new_driver);
2012-07-05 14:59:08 +00:00
}
}
2012-10-16 05:58:29 +00:00
system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/");
2012-07-05 14:59:08 +00:00
}
} else {
print "Warning: cannot find the kernel $kernelver from drvier rpms\n";
}
push @dd_drivers, @rpm_drivers;
}
2010-08-12 09:05:51 +00:00
# Generate the dependency relationship
system ("chroot '$rootimg_dir' depmod $kernelver");
# Clean the env
rmtree "$dd_dir";
return @dd_drivers;
}
2011-06-24 16:22:15 +00:00
sub usage {
2012-04-23 20:52:58 +00:00
print 'Usage: genimage -o <OSVER> [-a <arch>] -p <profile> -i <nodebootif> -n <nodenetdrivers> [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-l rootlimitsize] [--permission <permission>] [--interactive]'."\n";
2011-07-07 16:10:53 +00:00
print " --permission is used for statelite only\n";
print "Examples:\n";
print " genimage -i eth0 -n tg3 -o sles11 -p compute\n";
2012-03-27 20:59:36 +00:00
print " genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o sles11 -p compute --interactive\n";
2011-07-07 16:10:53 +00:00
print " genimage -i eth0 -n tg3,bnx2 -o sles11 -p compute\n";
print " genimage -i eth0 -n tg3,bnx2 -o sles11 -p compute --permission 777\n";
2011-06-24 16:22:15 +00:00
return 0;
}