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-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";
my $kernelver = ""; #`uname -r`;
my $basekernelver; # = $kernelver;
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
'm=s' => \$mode, #provide options for the mode of "genimage"
'permission=s' => \$permission
2008-05-24 17:29:40 +00:00
);
2010-03-05 06:54:52 +00:00
2009-09-24 18:51:53 +00:00
if (@ARGV > 0) {
$imagename=$ARGV[0];
if ($arch or $osver or $profile) {
print "-o, -p and -a options are not allowed when a image name is specified.\n";
exit 1;
}
#load the module in memory
eval {require("$::XCATROOT/lib/perl/xCAT/Table.pm")};
if ($@) {
print $@;
exit 1;
}
#get the info from the osimage and linux
my $osimagetab=xCAT::Table->new('osimage', -create=>1);
if (!$osimagetab) {
print "The osimage table cannot be opened.\n";
exit 1;
}
my $linuximagetab=xCAT::Table->new('linuximage', -create=>1);
if (!$linuximagetab) {
print "The linuximage table cannot be opened.\n";
exit 1;
}
(my $ref) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod');
if (!$ref) {
print "Cannot find image \'$imagename\' from the osimage table.\n";
exit 1;
}
(my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'pkglist', 'pkgdir', 'otherpkglist', 'otherpkgdir', 'postinstall', 'rootimgdir');
if (!$ref1) {
print "Cannot find $imagename from the linuximage table\n";
exit 1;
}
$osver=$ref->{'osvers'};
$arch=$ref->{'osarch'};
$profile=$ref->{'profile'};
my $provmethod=$ref->{'provmethod'};
unless ($osver and $arch and $profile and $provmethod) {
print"osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database.\n";
exit 1;
}
if ($provmethod ne 'netboot') {
print "\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'.";
exit 1;
}
if (! $ref1->{'pkglist'}) {
print"A .pkglist file must be specified for image \'$imagename\' in the linuximage table.\n";
exit 0;
}
$pkglist =$ref1->{'pkglist'};
$srcdir=$ref1->{'pkgdir'};
if ($srcdir) { $srcdir="$srcdir/1"; }
$srcdir_otherpkgs=$ref1->{'otherpkgdir'};
$otherpkglist=$ref1->{'otherpkglist'};
$postinstall_filename=$ref1->{'postinstall'};
$destdir=$ref1->{'rootimgdir'};
}
2010-03-05 06:54:52 +00:00
if ($mode eq "statelite") {
if (!$permission) {
$permission = "755";
}
}
2009-09-24 18:51:53 +00:00
if (!$arch) {
2009-10-13 11:39:37 +00:00
$arch = `uname -m`;
2009-09-24 18:51:53 +00:00
chomp($arch);
if ($arch =~ /i.86$/) {
$arch = "x86";
}
}
if (!$srcdir) {
$srcdir="$installroot/$osver/$arch/1";
}
if (!$srcdir_otherpkgs) {
$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch";
}
if (!$destdir)
{
$destdir="$installroot/netboot/$osver/$arch/$profile";
}
$rootimg_dir="$destdir/rootimg";
2008-05-24 17:29:40 +00:00
unless ($osver and $profile and $netdriver and $prinic) {
2010-03-05 10:18:04 +00:00
print 'Usage: genimage -i <nodebootif> -n <nodenetdrivers> [-r <otherifaces>] -k <KERNELVER> -o <OSVER> -p <PROFILE> -a <ARCH> [-m <mode> [--permission <permission>]]'."\n";
2009-09-24 18:51:53 +00:00
print ' genimage -i <nodebootif> -n <nodenetdrivers> [-r <otherifaces>] -k <KERNELVER> <imagename>'."\n";
2010-03-05 10:18:04 +00:00
print ' --permission only works when "-m statelite" is set'."\n";
2008-05-24 17:29:40 +00:00
print "Examples:\n";
print " genimage -i eth0 -n tg3 -o centos5.1 -p compute\n";
print " genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o centos5.1 -p compute\n";
2010-03-24 08:47:35 +00:00
print " genimage -i eth0 -n tg3,bnx2 -o centos5.1 -p compute -m statelite\n";
print " genimage -i eth0 -n tg3,bnx2 -o centos5.1 -p compute -m statelite --permission 777\n";
2009-09-24 18:51:53 +00:00
print " genimage -i eth0 -ntg3 myimagename\n";
2008-05-24 17:29:40 +00:00
exit 1;
}
my @ndrivers;
foreach (split /,/,$netdriver) {
unless (/\.ko$/) {
s/$/.ko/;
}
if (/^$/) {
next;
}
push @ndrivers,$_;
}
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
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
push @ndrivers, "sunrpc.ko";
push @ndrivers, "lockd.ko";
push @ndrivers, "nfs_acl.ko";
2010-02-11 02:24:48 +00:00
push @ndrivers, "fscache.ko";
2010-01-26 12:10:16 +00:00
push @ndrivers, "auth_rpcgss.ko";
push @ndrivers, "exportfs.ko";
push @ndrivers, "nfsd.ko";
push @ndrivers, "nfs.ko";
2010-06-16 00:09:21 +00:00
# Additional modules needed on s390x
if ($arch eq "s390x") {
push @ndrivers, "qdio.ko";
push @ndrivers, "ccwgroup.ko";
push @ndrivers, "af_packet.ko";
push @ndrivers, "qeth.ko";
push @ndrivers, "qeth_l2.ko";
push @ndrivers, "qeth_l3.ko";
}
2010-01-26 12:10:16 +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-03-19 21:12:56 +00:00
if (!$imagename) {
2010-07-09 06:19:30 +00:00
$otherpkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "otherpkgs.pkglist");
if (!$otherpkglist) { $otherpkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "otherpkgs.pkglist"); }
2010-03-19 21:12:56 +00:00
}
my %extra_hash=();
if ($otherpkglist) {
2010-07-09 09:36:36 +00:00
%extra_hash=imgutils::get_package_names($otherpkglist);
2010-03-19 21:12:56 +00:00
}
2008-09-09 23:52:04 +00:00
2009-09-24 18:51:53 +00:00
mkpath "$rootimg_dir/etc";
mkpath "$rootimg_dir/dev";
#system "mount -o bind /dev $rootimg_dir/dev";
2010-01-26 12:10:16 +00:00
if( ! -e "$rootimg_dir/dev/zero") {
system "mknod $rootimg_dir/dev/zero c 1 5";
}
if( ! -e "$rootimg_dir/dev/null") {
system "mknod $rootimg_dir/dev/null c 1 3"; #that's neccessary for SLES11
}
2009-09-24 18:51:53 +00:00
open($fd,">>","$rootimg_dir/etc/fstab");
2008-05-24 17:29:40 +00:00
print $fd "#Dummy fstab for rpm postscripts to see\n";
close($fd);
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") {
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
my $repolist;
2010-07-09 06:19:30 +00:00
$repolist = imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "repolist");
2010-04-09 03:18:56 +00:00
if(!$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;
2009-09-24 18:51:53 +00:00
if (!$imagename) {
2010-07-09 06:19:30 +00:00
$pkglist=imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "pkglist");
if (!$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
if (!$pkglist) {
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) {
$rc = system("$yumcmd_remove $rm_packges");
}
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')) {
print "zypper invocation failed with rc: $rc\n";
2010-03-22 16:14:06 +00:00
exit 1;
}
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) {
$rc = system("$yumcmd_remove $rm_packges");
}
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
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
2009-09-24 18:51:53 +00:00
if (!$imagename) {
2010-07-09 06:19:30 +00:00
$postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall");
2009-09-24 18:51:53 +00:00
if (!$postinstall_filename) {
2010-07-09 06:19:30 +00:00
$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";
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
if($mode eq "statelite") {
mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts;
2010-02-11 02:24:48 +00:00
mkpath "$rootimg_dir/root/.ssh"; # create place for NFS mounts for ssh;
2010-01-26 12:10:16 +00:00
# this script will get the directories;
2010-02-11 02:24:48 +00:00
unless( -r "$pathtofiles/../add-on/statelite/rc.statelite") {
print "Can't find $pathtofiles/../add-on/statelite/rc.statelite!\n";
2010-01-26 12:10:16 +00:00
exit;
}
2010-02-11 02:24:48 +00:00
system("cp $pathtofiles/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite");
2010-01-26 12:10:16 +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
}
2009-04-23 19:12:33 +00:00
#some rpms mounts the imageroot/proc on the /proc, need to release it,
#otherwise got kernal panic when installing
2009-08-13 08:36:38 +00:00
#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-04-02 07:11:44 +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
2010-06-09 07:50:50 +00:00
my @KVERS= <$rootimg_dir/boot/vmlinu[xz]-*>;
2010-06-16 00:09:21 +00:00
# The kernel name is different on s390x, e.g. image-2.6.32.9-0.5-default
if ($arch eq "s390x") {
@KVERS = <$rootimg_dir/boot/image-*>;
}
2010-06-09 07:50:50 +00:00
#as I know, s390x is using image-* as its kernel name
2010-04-02 12:05:33 +00:00
unless (scalar(@KVERS)) {
2010-06-09 07:50:50 +00:00
@KVERS=<$rootimg_dir/boot/image-*>;
2010-04-02 12:05:33 +00:00
}
foreach (@KVERS) {
s/vmlinu.-//;
2010-06-09 07:50:50 +00:00
s/image-//;
2010-04-02 12:05:33 +00:00
}
unless (scalar(@KVERS)) {
@KVERS= <$rootimg_dir/lib/modules/*>;
}
2010-04-02 07:11:44 +00:00
if (scalar(@KVERS)) {
2010-06-09 07:50:50 +00:00
foreach my $kver (@KVERS) {
if ($kver !~ m/.gz$/) {
$basekernelver = basename($kver);
last;
}
}
2010-04-02 07:11:44 +00:00
}
unless ($basekernelver) {
$basekernelver = `uname -r`;
}
2010-06-16 00:09:21 +00:00
# Extract the base kernel
if ($arch eq "s390x") {
$basekernelver =~ s/image-//g;
}
2010-06-09 07:50:50 +00:00
chomp($basekernelver);
if ($kernelver) {
# if the kernelver is specified by "-k",
# the kernel file should be in /boot
# the moudles should be in /lib/modules/$kernelver
if ( -e "/boot/vmlinux-$kernelver") {
copy("/boot/vmlinux-$kernelver", "$rootimg_dir/boot/");
}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("couldn't find the kernel file matched $kernelver in /boot");
}
if ( -e "/lib/modules/$kernelver" ) {
copy("/lib/modules/$kernelver", "$rootimg_dir/lib/modules/");
} else {
xdie("couldn't find /lib/modules/$kernelver");
}
} else {
2010-04-02 07:11:44 +00:00
$kernelver=$basekernelver;
}
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);
2008-05-24 17:29:40 +00:00
mkinitrd();
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-04-02 12:05:33 +00:00
mkpath("/tmp/xcatinitrd.$$/bin");
2010-06-16 00:09:21 +00:00
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-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");
# if($osver =~ /sles/ && $arch eq "ppc64") {#SLES for Power6&7
# mkpath("/tmp/xcatinitrd.$$/lib64/power6");
# mkpath("/tmp/xcatinitrd.$$/lib64/power7");
# }
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-01-26 12:10:16 +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
# Start udev on s390x
if ($arch eq "s390x") {
print $inifile <<EOMS;
# 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
}
2008-05-24 17:29:40 +00:00
print $inifile <<EOMS;
netstart
2010-01-26 12:10:16 +00:00
while ! ifconfig | grep inet; do
echo -e "\${RED}Failed to acquire address, retrying \${RESET}"
sleep 1
netstart
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 /
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
NFS=0
fi
if [ "nfs" == "`echo \$VALUE|awk -F: '{print \$1}'`" ]; then
NFS=1
SERVER=`echo \$VALUE|awk -F/ '{print \$3}'`
ROOTDIR=`echo \$VALUE|awk -F/ '{for(i=4;i<=NF;i++) printf "/%s",\$i}'`
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
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
2008-05-24 17:29:40 +00:00
fi
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-02-11 02:24:48 +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-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
cp -fp /var/lib/dhcpcd/dhcpcd-$prinic.info \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhcpcd/dhcpcd-$prinic.info
[ -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
2008-05-24 17:29:40 +00:00
if [ "\$NFS" = "1" ]; then
echo Setting up nfs with ram overlay.
mknod /dev/loop0 b 7 0
mkdir -p /ro
mkdir -p /rw
#NOTE: should prob have max count
while [ ! -d /ro/bin ]; do
echo mounting \$SERVER:\$ROOTDIR on /ro
2008-05-26 16:11:24 +00:00
mount \$SERVER:\$ROOTDIR /ro -r -n -o nolock,rsize=32768,udp,nfsvers=3,timeo=14
2010-01-26 12:10:16 +00:00
ST=`expr \$RANDOM % 5`
sleep \$ST
2008-05-24 17:29:40 +00:00
done
mount -t tmpfs rw /rw
mkdir -p /rw/etc
2008-05-27 18:21:23 +00:00
mkdir -p /rw/var/lib/dhcpcd
2008-05-24 17:29:40 +00:00
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
elif [ -r /rootimg.sfs ]; then
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";
print $inifile <<EOMS;
echo "You're dead. rpower nodename reset to play again.
* Did you packimage with -m cpio, -m squashfs, or -m nfs?
* If using -m squashfs did you include aufs.ko with geninitrd?
e.g.: -n tg3,squashfs,aufs,loop
* If using -m nfs did you export NFS and sync rootimg? And
did you include the aufs and nfs modules in the proper order:
e.g.: -n tg3,aufs,loop,sunrpc,lockd,nfs_acl,nfs
"
sleep 5
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");
2008-05-26 16:11:24 +00:00
print $inifile "#!/bin/bash\n";
print $inifile "dhcpcd $prinic\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") {
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") {
getlibs($_);
push @filestoadd,$_;
}
2010-06-16 00:09:21 +00:00
# 'sbin/udevd' and 'sbin/udevadm' needed on s390x
if ($arch eq "s390x") {
foreach ("sbin/udevd", "sbin/udevadm") {
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");
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
2009-09-24 18:51:53 +00:00
system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd.gz");
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
generic_post();
2010-01-26 12:10:16 +00:00
if($mode eq "statelite") {
if( ! -d "$rootimg_dir/opt/xcat/") {
mkdir "$rootimg_dir/opt/xcat/";
}
copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/");
chmod '0755', "$rootimg_dir/opt/xcat/xcatdsklspost";
2010-02-11 02:24:48 +00:00
#system("$XCATROOT/share/xcat/netboot/add-on/statelite/add_passwd $rootimg_dir");
#system("$XCATROOT/share/xcat/netboot/add-on/statelite/add_ssh $rootimg_dir");
2010-01-26 12:10:16 +00:00
}
2008-05-24 17:29:40 +00:00
}
sub generic_post { #This function is meant to leave the image in a state approximating a normal install
my $cfgfile;
2010-01-26 12:10:16 +00:00
if($mode ne "statelite") {
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 0 0\n";
print $cfgfile "tmpfs /var/tmp tmpfs defaults 0 0\n";
}
close($cfgfile);
}
2009-09-24 18:51:53 +00:00
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network");
2008-05-24 17:29:40 +00:00
print $cfgfile "NETWORKING=yes\n";
close($cfgfile);
2009-09-24 18:51:53 +00:00
open($cfgfile,">","$rootimg_dir/etc/resolv.conf");
2008-05-24 17:29:40 +00:00
print $cfgfile "#Dummy resolv.conf to make boot cleaner";
close($cfgfile);
2010-04-06 05:54:54 +00:00
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$prinic");
2010-04-06 06:45:36 +00:00
print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$prinic\nSTARTMODE=auto\n";
2008-05-24 17:29:40 +00:00
close($cfgfile);
foreach (split /,/,$othernics) {
if (/^$/) { next; }
2010-04-06 05:54:54 +00:00
open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$_");
2010-04-06 06:45:36 +00:00
print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\nSTARTMODE=auto\n";
2008-05-24 17:29:40 +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);
}
2008-05-24 17:29:40 +00:00
my @passwd;
2009-09-24 18:51:53 +00:00
open($cfgfile,"<","$rootimg_dir/etc/passwd");
2008-05-24 17:29:40 +00:00
@passwd = <$cfgfile>;
close($cfgfile);
2009-09-24 18:51:53 +00:00
open($cfgfile,">","$rootimg_dir/etc/passwd");
2008-05-24 17:29:40 +00:00
foreach (@passwd) {
if (/^root:/) {
s/^root:\*/root:x/
}
print $cfgfile $_;
}
close($cfgfile);
2009-09-24 18:51:53 +00:00
foreach (<$rootimg_dir/etc/skel/.*>) {
2008-05-24 17:29:40 +00:00
if (basename($_) eq '.' or basename($_) eq '..') {
next;
}
2009-09-24 18:51:53 +00:00
copy $_,"$rootimg_dir/root/";
2008-05-24 17:29:40 +00:00
}
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
2009-09-24 18:51:53 +00:00
my $rc = system("grep sshd $rootimg_dir/etc/init.d/.depend.start");
2008-05-26 16:11:24 +00:00
if ($rc) {
2009-09-24 18:51:53 +00:00
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");
2008-05-26 16:11:24 +00:00
}
2009-09-24 18:51:53 +00:00
my $rc = system("grep gettyset $rootimg_dir/etc/init.d/.depend.start");
2008-05-26 16:11:24 +00:00
if ($rc) {
2009-09-24 18:51:53 +00:00
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-26 16:11:24 +00:00
}
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
my $dd_dir = "/tmp/dd_tmp";
# If $dd_dir was not cleaned, try to unmount mnt first
if (-d "$dd_dir/mnt") {
system ("umount $dd_dir/mnt >/dev/null 2>&1");
}
if( -d "$dd_dir") {
rmtree "$dd_dir";
}
mkpath "$dd_dir";
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;
}