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";
2010-07-09 06:19:30 +00:00
use lib "../imgutils";
2008-05-24 17:29:40 +00:00
use File::Basename;
use File::Path;
use File::Copy;
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
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;
if ($name =~ /geninitrd/) {
$onlyinitrd=1;
}
my $rootlimit;
my $tmplimit;
my $installroot = "/install";
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
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,
2010-03-05 06:54:52 +00:00
'permission=s' => \$permission
2008-05-24 17:29:40 +00:00
);
2010-03-05 06:54:52 +00:00
2010-09-17 09:54:47 +00:00
# if "Table.pm" can be found here, the attributes in linuximage and osimage will be updated
my $needUpdateTable = 0;
my %keyhash = ();
my $updates_os = (); # the hash for updating osimage table
my $updates = (); # the hash for updating linuximage table
my $osimagetab;
my $linuximagetab;
my $ref_linuximage_tab;
my $ref_osimage_tab;
eval { require ("$::XCATROOT/lib/perl/xCAT/Table.pm") };
unless ($@) {
# Table.pm is there, we can update the xCAT table
$needUpdateTable = 1;
# get the info from the osimage and linuximage table
$osimagetab = xCAT::Table->new('osimage', -create=>1);
unless ($osimagetab) {
print "The osimage table cannot be found.\n";
exit 1;
}
$linuximagetab = xCAT::Table->new('linuximage', -create=>1);
unless($linuximagetab) {
print "The linuximage table cannot be found.\n";
exit 1;
}
}
if (@ARGV > 0 and $needUpdateTable eq 1) {
2009-09-24 18:51:53 +00:00
$imagename=$ARGV[0];
if ($arch or $osver or $profile) {
2010-09-17 09:54:47 +00:00
print "-o, -p and -a options are not allowed when a image name is specified.\n";
2009-09-24 18:51:53 +00:00
exit 1;
}
2010-09-17 09:54:47 +00:00
(my $ref_osimage_tab) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod');
unless ($ref_osimage_tab) {
print "Cannot find image \'$imagename\' from the osimage table.\n";
exit 1;
2009-09-24 18:51:53 +00:00
}
2010-09-17 09:54:47 +00:00
(my $ref_linuximage_tab) = $linuximagetab->getAttribs({imagename => $imagename}, 'pkglist', 'pkgdir', 'otherpkglist', 'otherpkgdir', 'postinstall', 'rootimgdir', 'nodebootif', 'otherifce', 'kernelver', 'netdrivers', 'permission');
unless ($ref_linuximage_tab) {
print "Cannot find $imagename from the linuximage table\n";
exit 1;
2009-09-24 18:51:53 +00:00
}
$osver=$ref->{'osvers'};
$arch=$ref->{'osarch'};
$profile=$ref->{'profile'};
2010-09-17 09:54:47 +00:00
my $provmethod=$ref->{'provmethod'}; # TODO: not necessary, and need to update both statelite and stateless modes
2009-09-24 18:51:53 +00:00
unless ($osver and $arch and $profile and $provmethod) {
2010-09-17 09:54:47 +00:00
print"osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database.\n";
exit 1;
2009-09-24 18:51:53 +00:00
}
2010-09-17 09:54:47 +00:00
unless ($provmethod eq 'netboot' || $provmethod eq 'statelite') {
print "\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'.";
exit 1;
2009-09-24 18:51:53 +00:00
}
2010-09-17 09:54:47 +00:00
unless ( $ref_linuximage_tab->{'pkglist'}) {
print"A .pkglist file must be specified for image \'$imagename\' in the linuximage table.\n";
2009-09-24 18:51:53 +00:00
exit 0;
}
2010-09-17 09:54:47 +00:00
$pkglist = $ref_linuximage_tab->{'pkglist'};
$srcdir = $ref_linuximage_tab->{'pkgdir'};
$srcdir = "$srcdir/1" if ($srcdir);
$srcdir_otherpkgs = $ref_linuximage_tab->{'otherpkgdir'};
$otherpkglist = $ref_linuximage_tab->{'otherpkglist'};
$postinstall_filename = $ref_linuximage_tab->{'postinstall'};
$destdir = $ref_linuximage_tab->{'rootimgdir'};
# TODO: how can we do if the user specifies one wrong value to the following attributes?
# currently, one message is output to indicate the users there will be some updates
if ($prinic) {
if ($prinic ne $ref_linuximage_tab->{'nodebootif'}) {
print "The primary nic is different from the value in linuximage table, will update it\n";
$updates{'nodebootif'} = $prinic;
}
} else {
$prinic = $ref_linuximage_tab->{'nodebootif'};
}
if ($othernics) {
if ($othernics ne $ref_linuximage_tab->{'otherifce'}) {
print "The other ifces are different from the value in linuximage table, will update it\n";
$updates{'otherifce'} = $othernics;
}
} else {
$othernics = $ref_linuximage_tab->{'otherifce'};
}
if ($kernelver) {
if ($kernelver ne $ref_linuximage_tab->{'kernelver'}) {
print "The kernelver is different from the value in linuximage table, will update it\n";
$updates{'kernelver'} = $kernelver;
}
} else {
$kernelver = $ref_linuximage_tab->{'kernelver'};
}
2009-09-24 18:51:53 +00:00
2010-09-17 09:54:47 +00:00
if ($ndrivers) {
if ($ndrivers ne $ref_linuximage_tab->{'netdrivers'}) {
print "The netdrivers are different from the value in linuximage table, will update it\n";
$updates{'netdrivers'} = $ndrivers;
}
} else {
$ndrivers = $ref_linuximage_tab->{'netdrivers'};
}
if ($permission) {
if ($permission ne $ref_linuximage_tab->{'permission'}) {
print "The permission value is different from the value in linuximage table, will update it\n";
$updates{'permission'} = $permission;
}
} else {
$permission = $ref_linuximage_tab->{'permission'};
2010-03-05 06:54:52 +00:00
}
}
2010-09-17 09:54:47 +00:00
$permission = "755" unless ($permission);
$updates{'permission'} = $permission if ($needUpdateTable);
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);
$updates{'pkgdir'} = $srcdir if ($needUpdateTable);
$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);
$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($needUpdateTable);
$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir);
$updates{'rootimgdir'} = $destdir if ($needUpdateTable);
2009-09-24 18:51:53 +00:00
$rootimg_dir="$destdir/rootimg";
2008-05-24 17:29:40 +00:00
unless ($osver and $profile and $netdriver and $prinic) {
2010-09-17 09:54:47 +00:00
print 'Usage: genimage -i <nodebootif> -n <nodenetdrivers> [-r <otherifaces>] -k <KERNELVER> -o <OSVER> -p <PROFILE> [-a <ARCH>] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>]'."\n";
print ' genimage [-i <nodebootif>] [-n <nodenetdrivers>] [-r <otherifaces>] [-k <KERNELVER>] [-o <OSVER>] [-p <PROFILE>] [-a <ARCH>] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] <imagename>'."\n";
print " --permission is used for statelite only\n";
2008-05-24 17:29:40 +00:00
print "Examples:\n";
2010-09-17 09:54:47 +00:00
print " genimage -i eth0 -n tg3 -o sles11 -p compute\n";
print " genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o sles11 -p compute\n";
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";
print " genimage -i eth0 -n tg3 myimagename\n";
2008-05-24 17:29:40 +00:00
exit 1;
}
my @ndrivers;
2010-09-17 09:54:47 +00:00
if ($netdriver) {
if ( ($updates{'netdrivers'} ne $netdriver) and $needUpdateTable ) {
$updates{'netdrivers'} = $netdriver;
}
} else {
if ($arch eq 'x86' or $arch eq 'x86_64') {
@ndrivers = qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en/;
} elsif ($arch eq 'ppc64') {
@ndrivers = qw/e1000 e1000e igb ibmveth ehea/;
} elsif ($arch eq "s390x") {
# TODO: put the default network drviers for s390x here
}
}
2008-05-24 17:29:40 +00:00
foreach (split /,/,$netdriver) {
2010-09-17 09:54:47 +00:00
unless (/\.ko$/) {
s/$/.ko/;
}
next if (/^$/);
2010-08-19 01:29:28 +00:00
# Do not include qeth module here
# This module is included later on
2010-09-17 09:54:47 +00:00
unless ( $_ =~ m/qeth/i ) {
2010-08-19 01:29:28 +00:00
push @ndrivers, $_;
}
2008-05-24 17:29:40 +00:00
}
2010-09-17 09:54:47 +00:00
2008-05-26 16:11:24 +00:00
unless (grep /af_packet/,@ndrivers) {
unshift(@ndrivers,"af_packet.ko");
}
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"); }
$updates{'otherpkglist'} = $otherpkglist if ($needUpdateTable 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
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);
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
2009-02-12 12:04:51 +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 ar file:$srcdir $osver");
}else {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir sa file:$srcdir");
2009-02-12 12:04:51 +00:00
}
2008-09-09 23:52:04 +00:00
2009-07-02 20:24:27 +00:00
#remove the old repository for extra packages
2009-10-06 20:21:11 +00:00
my $result=`zypper -R $rootimg_dir sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`;
2009-07-02 20:24:27 +00:00
if ($result =~ /\S/) {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir sd $result");
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
2009-09-24 18:51:53 +00:00
if(-e "$rootimg_dir/etc/zypp/repos.d/otherpkg.repo") {
2010-09-17 09:54:47 +00:00
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;
2010-03-31 00:51:21 +00:00
foreach $pass (sort (keys(%extra_hash))) {
2010-03-22 16:14:06 +00:00
foreach (keys(%{$extra_hash{$pass}})) {
2009-10-06 20:21:11 +00:00
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { 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) {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir ar file:$srcdir_otherpkgs/$_ otherpkg$index");
2009-07-02 20:24:27 +00:00
}else {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir sa file:$srcdir_otherpkgs/$_");
2009-07-02 20:24:27 +00:00
}
} else {
if($osver_host == 11) {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir ar -t Plaindir file:$srcdir_otherpkgs/$_ otherpkg$index");
2009-07-02 20:24:27 +00:00
}else {
2009-09-24 18:51:53 +00:00
system("zypper -R $rootimg_dir 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/\|/;
system("zypper -R $rootimg_dir ar $repourl $repoalias");
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
system("zypper -R $rootimg_dir refresh");
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) {
2009-09-24 18:51:53 +00:00
$yumcmd = "zypper -R $rootimg_dir install -l "; #add -l for SLES11
2009-02-12 12:04:51 +00:00
}else {
2009-09-24 18:51:53 +00:00
$yumcmd = "zypper -R $rootimg_dir install ";
}
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) {
$updates{'pkglist'} = $pkglist if ($needUpdateTable);
} 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;
2010-03-31 00:51:21 +00:00
foreach $pass (sort (keys(%pkg_hash))) {
2010-03-22 16:14:06 +00:00
$pkgnames = "";
foreach (keys(%{$pkg_hash{$pass}})) {
if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;}
2010-03-24 08:47:35 +00:00
my $pa=$pkg_hash{$pass}{$_};
2010-03-22 16:14:06 +00:00
$pkgnames .= " " . join(' ', @$pa);
}
2010-03-31 00:51:21 +00:00
print "$yumcmd $pkgnames\n";
2010-03-22 16:14:06 +00:00
my $rc = system("$yumcmd $pkgnames");
2010-03-31 00:51:21 +00:00
$rc = $rc >> 8;
if (($rc) && ($rc != '104')) {
print "zypper invocation failed with rc: $rc\n";
2010-03-22 16:14:06 +00:00
exit 1;
}
2008-05-24 17:29:40 +00:00
}
2009-04-23 19:12:33 +00:00
2010-03-31 00:51:21 +00:00
foreach $pass (sort (keys(%extra_hash))) {
2010-03-22 16:14:06 +00:00
#remove the packages that are specified in the otherpkgs.list files with leading '-'
my $yumcmd_remove= "zypper -R $rootimg_dir remove ";
if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) {
my $pa=$extra_hash{$pass}{'PRE_REMOVE'};
my $rm_packges= join(' ', @$pa);
if ($rm_packges) {
2010-09-17 09:54:47 +00:00
$rc = system("$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}) {
2010-03-31 00:51:21 +00:00
print "$yumcmd $extrapkgnames{$pass}\n";
2010-03-22 16:14:06 +00:00
$rc = system("$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) {
2010-09-17 09:54:47 +00:00
$rc = system("$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
my $yumcmd_update = "zypper -R $rootimg_dir update ";
$rc = system("$yumcmd_update");
# ignore any return code
2010-09-17 09:54:47 +00:00
#$kernelver = $basekernelver unless($kernelver);
#$updates{'kernelver'} = $kernelver if ($needUpdateTable);
if ($kernelver) {
# if "-k" is specified, the kernel file should be in the "/boot" directory (not in the rootimg chroot environment)
# the modules should be in /lib/modules/$kernelver
if ( -e "/boot/vmlinux-$kernelver") {
copy("/boot/vmlinux-$kernelver", "$rootimg_dir/boot/");
system("cp -r /lib/modules/$kernelver $rootimg_dir/lib/modules/");
} elsif ( -e "/boot/vmlinuz-$kernelver") {
copy("/boot/vmlinuz-$kernelver", "$rootimg_dir/boot/");
} elsif ( -e "/boot/image-$kernelver") {
copy("/boot/image-$kernelver", "$rootimg_dir/boot/");
} else {
xdie "couldnot find the kernel file matched $kernelver in /boot!";
}
if ( -e "/lib/modules/$kernelver" ) {
system("cp -r /lib/modules/$kernelver $rootimg_dir/lib/modules/");
} else {
xdie "couldnot find /lib/modules/$kernelver!";
}
} else {
# 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 = "";
} else {
$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;
}
}
}
unless($basekernelver) {
xdie "couldnot find the kernel file in root image, please make sure kernel package is in your pkglist!";
}
}
chomp $basekernelver;
$kernelver = $basekernelver;
$updates{kernelver} = $kernelver if ($needUpdateTable);
}
2008-05-24 17:29:40 +00:00
postscripts(); #run 'postscripts'
}
unlink "/tmp/genimage.$$.yum.conf";
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
}
if (($postinstall_filename) && (-x $postinstall_filename)) {
2010-03-19 21:12:56 +00:00
#print "postinstall_filename=$postinstall_filename\n";
2010-09-17 09:54:47 +00:00
$updates{'postinstall'} = $postinstall_filename if ($needUpdateTable);
2009-09-24 18:51:53 +00:00
my $rc = system($postinstall_filename, $rootimg_dir,$osver,$arch,$profile);
2009-02-18 13:43:11 +00:00
if($rc) {
print "postinstall script failed\n";
exit 1;
}
}
2009-04-23 14:13:56 +00:00
2010-01-26 12:10:16 +00:00
2010-09-17 09:54:47 +00:00
# commit the changes to the linuximage/osimage table if necessary
if ($needUpdateTable) {
# 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
if ($imagename) {
$keychain{'imagename'} = $imagename;
$linuximagetab->setAttribs(\%keyhash, \%updates);
$linuximagetab->commit;
} else {
# update the imagename for stateless
$keyhash{'imagename'} = "$osver-$arch-netboot-$profile";
$updates_os{'profile'} = $profile;
$updates_os{'imagetype'} = 'linux';
$updates_os{'provmethod'} = 'netboot';
$updates_os{'osname'} = 'Linux';
$updates_os{'osvers'} = $osver;
$updates_os{'osdistro'} = 'rh'; # not used currently
$updates_os{'osarch'} = $arch;
$osimagetab->setAttribs(\%keyhash, \%updates_os);
$osimagetab->commit;
$linuximagetab->setAttribs(\%keyhash, \%updates);
$linuximagetab->commit;
# update the imagename for statelite
$keyhash{'imagename'} = "$osver-$arch-statelite-$profile";
$updates_os{'provmethod'} = 'statelite';
$osimagetab->setAttribs(\%keyhash, \%updates_os);
$linuximagetab->setAttribs(\%keyhash, \%updates);
$linuximagetab->commit;
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;
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");
# 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;
}
print "Added driver $dd from driver update disk.\n";
}
@ndrivers = (@new_order, @ndrivers);
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
unshift (@checkdeps,$dep); #recursively check dependencies
unshift (@ndrivers,$dep);
print "Added $dep as an autodetected depedency\n";
}
}
}
}
close($moddeps);
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 {
my $file = shift;
2009-09-24 18:51:53 +00:00
my $liblist = `chroot $rootimg_dir ldd $file`;
2008-05-24 17:29:40 +00:00
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;
}
}
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
push @ndrivers, qw{sunrpc.ko lockd.ko nfs_acl.ko fscache.ko auth_rpcgss.ko exportfs.ko nfsd.ko nfs.ko};
}
2010-06-09 07:50:50 +00:00
if(-r "$rootimg_dir/boot/vmlinux-$kernelver") { # SLES use vmlinux-* as its name
2010-04-21 09:36:22 +00:00
copy("$rootimg_dir/boot/vmlinux-$kernelver","$destdir/kernel");
2010-06-09 07:50:50 +00:00
} elsif(-r "$rootimg_dir/boot/vmlinuz-$kernelver") { # OpenSuSE maight use vmlinuz-* as its name
copy("$rootimg_dir/boot/vmlinuz-$kernelver","$destdir/kernel");
} elsif(-r "$rootimg_dir/boot/image-$kernelver") { # SLES on s390x use image-* as its name
copy("$rootimg_dir/boot/image-$kernelver","$destdir/kernel");
2010-04-21 09:36:22 +00:00
} else {
2010-06-16 00:09:21 +00:00
xdie("Cannot find suitable kernel file for $kernelver");
2010-04-02 12:05:33 +00:00
}
2010-06-09 07:50:50 +00:00
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
2008-05-26 16:11:24 +00:00
print $inifile "mount -t proc /proc /proc\n";
2008-05-24 17:29:40 +00:00
print $inifile "mount -t sysfs /sys /sys\n";
2010-03-05 08:00:51 +00:00
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
2008-05-24 17:29:40 +00:00
foreach (@ndrivers) {
print $inifile "insmod /lib/$_\n";
}
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
2010-09-17 09:54:47 +00:00
# Start udev on s390x
if ($arch eq "s390x") {
print $inifile <<EOMS;
2010-06-16 00:09:21 +00:00
# Start udev to find devices attached to node
# This script can be found in /lib/mkinitrd
echo "Creating device nodes with udev"
echo `/sbin/udevd --daemon`
echo `/sbin/udevadm trigger`
echo `/sbin/udevadm settle --timeout=10`
EOMS
2010-09-17 09:54:47 +00:00
}
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
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
VALUE=`echo \$i |awk -F= '{print \$2}'`
BOOTIF=`ifconfig -a|grep -i "hwaddr $VALUE"|awk '{print $1}'`
if [ ! -z "\$XCATSERVER" ]; then
break
fi
elif [ "\$KEY" == 'XCAT' ]; then
VALUE=`echo \$i |awk -F= '{print \$2}'`
# format: XCAT=xcatmaster:xcatdport
XCATSERVER=\$VALUE
if [ ! -z "\$BOOTIF" ]; then
break
fi
fi
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
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
2008-05-26 16:11:24 +00:00
ip addr add dev lo 127.0.0.1/8
ip link set lo up
2008-05-24 17:29:40 +00:00
cd /
2010-09-17 09:54:47 +00:00
2008-05-24 17:29:40 +00:00
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
2010-09-17 09:54:47 +00:00
NFSROOT=1
VALUE=`echo \$i |awk -F= '{print \$2}'`
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
fi
2008-05-24 17:29:40 +00:00
done
2010-01-26 12:10:16 +00:00
# show xCAT logo
fancydisplay
# begin NFSROOT/Statelite code
if [ "\$NFSROOT" = "1" ]; then
echo Setting up Statelite
# for loop back mounting capability!
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`
2010-08-12 03:24:40 +00:00
while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14
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. This initrd wasn't created for statelite node? rerun genimage with the -m statelite flag, then rerun 'nodeset \$ME statelite'
2. Is DNS set up? Maybe that's why I can't mount \${SERVER}.
3. The nfs modules aren't set right in this initfs?"
shell
exit
fi
echo -e "\${RED}Could not mount \$SERVER:\$ROOTDIR on \$NEWROOT \$RESET"
RS=`expr \$RANDOM % 30`
echo -e "Trying again in \$RS seconds"
sleep \$RS
done
# 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
2010-08-12 03:24:40 +00:00
while ! mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT \$NEWROOT/\$RWDIR/persistent -o nolock,tcp
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
echo -e "\${RED}Hmmm... Can't mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT. \${NORMAL}"
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
# do all the mounts:
\$NEWROOT/etc/init.d/statelite
# 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) {
print $inifile " mount -o size=$rootlimit -t tmpfs rootfs /sysroot\n";
} else {
print $inifile " mount -t tmpfs rootfs /sysroot\n";
}
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";
print $inifile "cd /\n";
2009-02-12 12:04:51 +00:00
print $inifile "mkdir /sysroot/var/lib/dhcpcd/\n"; #neccessary for SLES11, not sure for SLES10
2008-05-27 18:21:23 +00:00
print $inifile "cp /var/lib/dhcpcd/* /sysroot/var/lib/dhcpcd/\n";
print $inifile "cp /etc/resolv.conf /sysroot/etc/\n";
2008-05-27 20:20:15 +00:00
print $inifile "cp /etc/HOSTNAME /sysroot/etc/\n";
2008-05-24 17:29:40 +00:00
print $inifile "mknod /sysroot/dev/console c 5 1\n";
2008-05-26 16:11:24 +00:00
print $inifile "exec /lib/mkinitrd/bin/run-init -c /dev/console /sysroot /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";
print $inifile "dhcpcd \${1}\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);
chmod(0755,"/tmp/xcatinitrd.$$/init");
chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart");
@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") {
2010-08-15 16:06:23 +00:00
foreach ("sbin/ifconfig", "usr/bin/clear", "sbin/mount.nfs","sbin/umount.nfs","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") {
2010-01-26 12:10:16 +00:00
getlibs($_);
push @filestoadd,$_;
}
2010-06-16 00:09:21 +00:00
# 'sbin/udevd' and 'sbin/udevadm' needed on s390x
if ($arch eq "s390x") {
2010-08-19 01:29:28 +00:00
foreach ("sbin/udevd", "sbin/udevadm", "usr/bin/readlink") {
2010-06-16 00:09:21 +00:00
getlibs($_);
push @filestoadd,$_;
}
}
2010-01-26 12:10:16 +00:00
}else {
foreach ("sbin/ifconfig","usr/bin/clear", "usr/bin/grep","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") {
2010-03-31 09:17:51 +00:00
getlibs($_);
2010-01-26 12:10:16 +00:00
push @filestoadd,$_;
}
}
2008-05-24 17:29:40 +00:00
if ($arch =~ /x86_64/) {
push @filestoadd,"lib64/libnss_dns.so.2";
}
else {
push @filestoadd,"lib/libnss_dns.so.2";
}
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;
if($basekernelver ne $kernelver) {
2009-09-24 18:51:53 +00:00
system("rm -rf $rootimg_dir/lib/modules/$basekernelver");
unless (-d "$rootimg_dir/lib/modules/$kernelver") {
2008-05-24 17:29:40 +00:00
if(-d "/lib/modules/$kernelver") {
2009-09-24 18:51:53 +00:00
system("cd /lib/modules;cp -r $kernelver $rootimg_dir/lib/modules/");
2008-05-24 17:29:40 +00:00
}
else {
xdie("Cannot read /lib/modules/$kernelver");
}
}
}
2009-09-24 18:51:53 +00:00
find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>);
2008-05-24 17:29:40 +00:00
foreach (@filestoadd) {
if (ref($_)) {
2008-09-11 22:03:01 +00:00
#print "$_->[0], $_->[1]\n";
2009-10-06 20:21:11 +00:00
my $srcpath = "$rootimg_dir/".$_->[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];
}
copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]);
chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1];
} else {
2008-09-11 22:03:01 +00:00
#print "$_\n";
2009-09-24 18:51:53 +00:00
my $srcpath = "$rootimg_dir/$_";
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
}
copy("$srcpath","/tmp/xcatinitrd.$$/$_");
chmod 0755,"/tmp/xcatinitrd.$$/".$_;
}
}
2010-06-16 00:09:21 +00:00
# Copy udev libraries on s390x
if ($arch eq "s390x") {
system("mkdir -p /tmp/xcatinitrd.$$/etc/udev");
system("cp -r $rootimg_dir/etc/udev/* /tmp/xcatinitrd.$$/etc/udev");
2010-08-19 01:29:28 +00:00
# Copy rules for network adapter
my $name = `cat /etc/sysconfig/network/ifcfg-$prinic | grep NAME`;
my $nic = '';
if ($name =~ m/(\d+\.\d+\.\d+)/g) {
$nic = $&;
}
system("cp -r /etc/udev/rules.d/*$nic.rules /tmp/xcatinitrd.$$/etc/udev/rules.d");
system("cp -r /etc/udev/rules.d/*persistent-net.rules /tmp/xcatinitrd.$$/etc/udev/rules.d");
2010-06-16 00:09:21 +00:00
system("mkdir -p /tmp/xcatinitrd.$$/lib/udev");
system("cp -r $rootimg_dir/lib/udev/* /tmp/xcatinitrd.$$/lib/udev");
}
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;
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);
#open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$prinic");
#print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$prinic\nSTARTMODE=auto\n";
#close($cfgfile);
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
# 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-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";
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");
system("chroot $rootimg_dir insserv gettyset xcatpostinit");
2010-06-16 00:09:21 +00:00
2010-09-17 09:54:47 +00:00
my $rc = system("grep sshd $rootimg_dir/etc/init.d/.depend.start");
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");
}
my $rc = system("grep gettyset $rootimg_dir/etc/init.d/.depend.start");
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;
}
}
#load the driver update disk, and return the driver names by loading order
sub load_dd()
{
# check the Driver Update Disk images, it can be .img or .iso
if (! -d "$installroot/driverdisk/$osver/$arch") {
return ();
}
my @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`;
chomp(@dd_list);
if (! @dd_list) {
return ();
}
# 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";
my @dd_drivers = (); #dirver names
# 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;
}
}
# Generate the dependency relationship
system ("chroot '$rootimg_dir' depmod $kernelver");
# Clean the env
rmtree "$dd_dir";
return @dd_drivers;
}