From 64a2057a9492a0dcefee75fa301bbd671196928f Mon Sep 17 00:00:00 2001 From: ligc Date: Wed, 31 Jul 2013 15:13:40 +0800 Subject: [PATCH] Revert "Revert "fix for bug 4239: do not use ip command on AIX"" This reverts commit 5b348a322028e3a245c23595f6f7eaeaac2319f5. --- perl-xCAT/xCAT/InstUtils.pm | 12 +- xCAT-client/bin/chhypervisor | 103 +- xCAT-client/bin/clonevm | 103 +- xCAT-client/bin/rmigrate | 103 +- xCAT-client/bin/rshutdown | 103 +- xCAT-client/bin/rspconfig | 103 +- xCAT-client/bin/switchblade | 103 +- xCAT-client/bin/winstall | 88 +- .../share/xcat/install/SL/compute.SL6.pkglist | 9 +- .../share/xcat/install/SL/compute.SL6.tmpl | 150 +- .../share/xcat/install/esxi/base.esxi4.1.tmpl | 37 +- .../xcat/install/fedora/compute.fedora12.tmpl | 150 +- .../install/fedora/compute.fedora15.pkglist | 9 +- .../xcat/install/fedora/compute.fedora15.tmpl | 152 +- .../share/xcat/install/ol/compute.ol6.pkglist | 9 +- .../share/xcat/install/ol/compute.ol6.tmpl | 150 +- .../share/xcat/netboot/SL/compute.SL6.pkglist | 16 +- .../share/xcat/netboot/SL/dracut/check | 4 +- .../xcat/netboot/SL/dracut/install.netboot | 11 +- .../xcat/netboot/SL/dracut/install.statelite | 10 +- .../xcat/netboot/SL/dracut/installkernel | 3 +- .../xcat/netboot/SL/dracut/xcat-cmdline.sh | 5 +- .../xcat/netboot/SL/dracut/xcat-prepivot.sh | 127 +- .../share/xcat/netboot/SL/dracut/xcatroot | 264 +- xCAT-server/share/xcat/netboot/SL/genimage | 2082 +++++++++++++++- xCAT-server/share/xcat/netboot/centos/dracut | 1 - .../share/xcat/netboot/centos/genimage | 2082 +++++++++++++++- .../share/xcat/netboot/centos/geninitrd | 2082 +++++++++++++++- .../share/xcat/netboot/centos/kvm.exlist | 25 +- .../share/xcat/netboot/centos/kvm.pkglist | 26 +- .../share/xcat/netboot/centos/xen.exlist | 14 +- .../share/xcat/netboot/centos/xen.pkglist | 21 +- .../netboot/fedora/compute.fedora12.pkglist | 15 +- .../netboot/fedora/compute.fedora15.pkglist | 15 +- .../share/xcat/netboot/fedora/dracut/check | 4 +- .../netboot/fedora/dracut/install.netboot | 11 +- .../netboot/fedora/dracut/install.statelite | 10 +- .../xcat/netboot/fedora/dracut/installkernel | 3 +- .../netboot/fedora/dracut/xcat-cmdline.sh | 5 +- .../netboot/fedora/dracut/xcat-premount.sh | 19 +- .../netboot/fedora/dracut/xcat-prepivot.sh | 127 +- .../netboot/fedora/dracut/xcat-updateflag | 25 +- .../share/xcat/netboot/fedora/dracut/xcatroot | 264 +- .../xcat/netboot/fedora/dracut_009/check | 4 +- .../netboot/fedora/dracut_009/install.netboot | 11 +- .../fedora/dracut_009/install.statelite | 10 +- .../netboot/fedora/dracut_009/installkernel | 3 +- .../fedora/dracut_009/xcat-premount.sh | 19 +- .../netboot/fedora/dracut_009/xcat-updateflag | 25 +- .../share/xcat/netboot/fedora/genimage | 2082 +++++++++++++++- .../share/xcat/netboot/fedora/geninitrd | 2082 +++++++++++++++- .../share/xcat/netboot/ol/compute.exlist | 15 +- .../share/xcat/netboot/ol/compute.ol6.pkglist | 16 +- .../share/xcat/netboot/ol/compute.pkglist | 15 +- xCAT-server/share/xcat/netboot/ol/dracut | 1 - xCAT-server/share/xcat/netboot/ol/genimage | 2082 +++++++++++++++- xCAT-server/share/xcat/netboot/rh/geninitrd | 2082 +++++++++++++++- xCAT-server/share/xcat/netboot/sles/geninitrd | 2137 ++++++++++++++++- xCAT-server/share/xcat/netboot/suse/geninitrd | 893 ++++++- .../share/xcat/netboot/ubuntu/geninitrd | 1774 +++++++++++++- .../cmos_settings/nosol/default/6391 | 10 +- .../cmos_settings/nosol/default/7321 | 10 +- .../cmos_settings/nosol/default/7323 | 10 +- .../cmos_settings/nosol/default/7870 | 9 +- .../cmos_settings/nosol/default/7871 | 9 +- .../cmos_settings/nosol/default/7901 | 17 +- .../cmos_settings/nosol/default/7902 | 17 +- .../cmos_settings/nosol/default/7944 | 10 +- .../cmos_settings/nosol/default/7945 | 10 +- .../cmos_settings/nosol/default/7946 | 10 +- .../cmos_settings/nosol/default/7947 | 10 +- xCAT/templates/cmos_settings/nosol/hpc/7321 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7323 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7391 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7870 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7871 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7901 | 18 +- xCAT/templates/cmos_settings/nosol/hpc/7902 | 18 +- xCAT/templates/cmos_settings/nosol/hpc/7944 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7945 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7946 | 17 +- xCAT/templates/cmos_settings/nosol/hpc/7947 | 17 +- xCAT/templates/cmos_settings/sol/default/6391 | 10 +- xCAT/templates/cmos_settings/sol/default/7321 | 10 +- xCAT/templates/cmos_settings/sol/default/7323 | 10 +- xCAT/templates/cmos_settings/sol/default/7870 | 8 +- xCAT/templates/cmos_settings/sol/default/7871 | 8 +- xCAT/templates/cmos_settings/sol/default/7901 | 17 +- xCAT/templates/cmos_settings/sol/default/7902 | 17 +- xCAT/templates/cmos_settings/sol/default/7944 | 10 +- xCAT/templates/cmos_settings/sol/default/7945 | 10 +- xCAT/templates/cmos_settings/sol/default/7946 | 10 +- xCAT/templates/cmos_settings/sol/default/7947 | 10 +- xCAT/templates/cmos_settings/sol/hpc/7321 | 17 +- xCAT/templates/cmos_settings/sol/hpc/7323 | 17 +- xCAT/templates/cmos_settings/sol/hpc/7391 | 17 +- xCAT/templates/cmos_settings/sol/hpc/7870 | 16 +- xCAT/templates/cmos_settings/sol/hpc/7871 | 16 +- xCAT/templates/cmos_settings/sol/hpc/7901 | 18 +- xCAT/templates/cmos_settings/sol/hpc/7902 | 18 +- xCAT/templates/cmos_settings/sol/hpc/7912 | 15 +- xCAT/templates/cmos_settings/sol/hpc/7944 | 17 +- xCAT/templates/cmos_settings/sol/hpc/7945 | 17 +- xCAT/templates/cmos_settings/sol/hpc/7946 | 17 +- xCAT/templates/cmos_settings/sol/hpc/7947 | 17 +- 105 files changed, 22434 insertions(+), 105 deletions(-) mode change 100644 => 100755 perl-xCAT/xCAT/InstUtils.pm mode change 120000 => 100755 xCAT-client/bin/chhypervisor mode change 120000 => 100755 xCAT-client/bin/clonevm mode change 120000 => 100755 xCAT-client/bin/rmigrate mode change 120000 => 100755 xCAT-client/bin/rshutdown mode change 120000 => 100755 xCAT-client/bin/rspconfig mode change 120000 => 100755 xCAT-client/bin/switchblade mode change 120000 => 100755 xCAT-client/bin/winstall mode change 120000 => 100644 xCAT-server/share/xcat/install/SL/compute.SL6.pkglist mode change 120000 => 100644 xCAT-server/share/xcat/install/SL/compute.SL6.tmpl mode change 120000 => 100644 xCAT-server/share/xcat/install/esxi/base.esxi4.1.tmpl mode change 120000 => 100644 xCAT-server/share/xcat/install/fedora/compute.fedora12.tmpl mode change 120000 => 100644 xCAT-server/share/xcat/install/fedora/compute.fedora15.pkglist mode change 120000 => 100644 xCAT-server/share/xcat/install/fedora/compute.fedora15.tmpl mode change 120000 => 100644 xCAT-server/share/xcat/install/ol/compute.ol6.pkglist mode change 120000 => 100644 xCAT-server/share/xcat/install/ol/compute.ol6.tmpl mode change 120000 => 100644 xCAT-server/share/xcat/netboot/SL/compute.SL6.pkglist mode change 120000 => 100755 xCAT-server/share/xcat/netboot/SL/dracut/check mode change 120000 => 100755 xCAT-server/share/xcat/netboot/SL/dracut/install.netboot mode change 120000 => 100755 xCAT-server/share/xcat/netboot/SL/dracut/install.statelite mode change 120000 => 100755 xCAT-server/share/xcat/netboot/SL/dracut/installkernel mode change 120000 => 100644 xCAT-server/share/xcat/netboot/SL/dracut/xcat-cmdline.sh mode change 120000 => 100755 xCAT-server/share/xcat/netboot/SL/dracut/xcat-prepivot.sh mode change 120000 => 100755 xCAT-server/share/xcat/netboot/SL/dracut/xcatroot mode change 120000 => 100755 xCAT-server/share/xcat/netboot/SL/genimage delete mode 120000 xCAT-server/share/xcat/netboot/centos/dracut mode change 120000 => 100755 xCAT-server/share/xcat/netboot/centos/genimage mode change 120000 => 100755 xCAT-server/share/xcat/netboot/centos/geninitrd mode change 120000 => 100644 xCAT-server/share/xcat/netboot/centos/kvm.exlist mode change 120000 => 100644 xCAT-server/share/xcat/netboot/centos/kvm.pkglist mode change 120000 => 100644 xCAT-server/share/xcat/netboot/centos/xen.exlist mode change 120000 => 100644 xCAT-server/share/xcat/netboot/centos/xen.pkglist mode change 120000 => 100644 xCAT-server/share/xcat/netboot/fedora/compute.fedora12.pkglist mode change 120000 => 100644 xCAT-server/share/xcat/netboot/fedora/compute.fedora15.pkglist mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut/check mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut/install.netboot mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut/install.statelite mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut/installkernel mode change 120000 => 100644 xCAT-server/share/xcat/netboot/fedora/dracut/xcat-cmdline.sh mode change 120000 => 100644 xCAT-server/share/xcat/netboot/fedora/dracut/xcat-premount.sh mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut/xcat-prepivot.sh mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut/xcat-updateflag mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut/xcatroot mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut_009/check mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut_009/install.netboot mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut_009/install.statelite mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut_009/installkernel mode change 120000 => 100644 xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-premount.sh mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-updateflag mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/genimage mode change 120000 => 100755 xCAT-server/share/xcat/netboot/fedora/geninitrd mode change 120000 => 100644 xCAT-server/share/xcat/netboot/ol/compute.exlist mode change 120000 => 100644 xCAT-server/share/xcat/netboot/ol/compute.ol6.pkglist mode change 120000 => 100644 xCAT-server/share/xcat/netboot/ol/compute.pkglist delete mode 120000 xCAT-server/share/xcat/netboot/ol/dracut mode change 120000 => 100755 xCAT-server/share/xcat/netboot/ol/genimage mode change 120000 => 100755 xCAT-server/share/xcat/netboot/rh/geninitrd mode change 120000 => 100755 xCAT-server/share/xcat/netboot/sles/geninitrd mode change 120000 => 100755 xCAT-server/share/xcat/netboot/suse/geninitrd mode change 120000 => 100755 xCAT-server/share/xcat/netboot/ubuntu/geninitrd mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/6391 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7321 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7323 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7870 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7871 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7901 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7902 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7944 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7945 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7946 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/default/7947 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7321 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7323 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7391 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7870 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7871 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7901 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7902 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7944 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7945 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7946 mode change 120000 => 100644 xCAT/templates/cmos_settings/nosol/hpc/7947 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/6391 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7321 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7323 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7870 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7871 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7901 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7902 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7944 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7945 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7946 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/default/7947 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7321 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7323 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7391 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7870 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7871 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7901 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7902 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7912 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7944 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7945 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7946 mode change 120000 => 100644 xCAT/templates/cmos_settings/sol/hpc/7947 diff --git a/perl-xCAT/xCAT/InstUtils.pm b/perl-xCAT/xCAT/InstUtils.pm old mode 100644 new mode 100755 index e227950db..c43caa420 --- a/perl-xCAT/xCAT/InstUtils.pm +++ b/perl-xCAT/xCAT/InstUtils.pm @@ -217,7 +217,17 @@ sub is_me #my ($b1, $b2, $b3, $b4) = split /\./, $nameIP; # get all the possible IPs for the node I'm running on - my $ipcmd = "ip addr | grep 'inet'"; + # this is a common subroutine for both AIX and Linux, + # AIX does not have ip command + my $ipcmd; + if ( -f "/sbin/ip" ) + { + $ipcmd = "ip addr | grep 'inet'"; + } + else + { + $ipcmd = "ifconfig -a | grep 'inet'"; + } my $result = xCAT::Utils->runcmd($ipcmd, -1, 1); if ($::RUNCMD_RC != 0) { diff --git a/xCAT-client/bin/chhypervisor b/xCAT-client/bin/chhypervisor deleted file mode 120000 index b1c9eea11..000000000 --- a/xCAT-client/bin/chhypervisor +++ /dev/null @@ -1 +0,0 @@ -xcatclient \ No newline at end of file diff --git a/xCAT-client/bin/chhypervisor b/xCAT-client/bin/chhypervisor new file mode 100755 index 000000000..d721a8cb1 --- /dev/null +++ b/xCAT-client/bin/chhypervisor @@ -0,0 +1,102 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# Used as a standard client cmd that can be used for many of the xcat cmds. +# It grabs the arguments, noderange, and stdin and then submits the request to +# xcatd and waits for responses. Most of the client/server communication is +# contained in Client.pm. + +# To use this, sym link your cmd name to this script. + +BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } +use lib "$::XCATROOT/lib/perl"; +use Cwd; +#use IO::Socket::SSL; +#use IO::Socket::INET; +use File::Basename; +#use Data::Dumper; +use xCAT::Client; +use strict; +my $bname = basename($0); +my $cmdref; +if ($bname =~ /xcatclient/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin +else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient +$cmdref->{cwd}->[0] = cwd(); + +my $data; +# allows our plugins to get the stdin of the cmd that invoked the plugin +if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) ) +{ + my $rin=""; + my $rout; + vec($rin,fileno(STDIN),1)=1; + my $nfound=select($rout=$rin,"","",1); + if ($nfound) + { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +else +{ + if (-p STDIN) { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} + + +my $arg; +my @tmpargv = @ARGV; + +# lslite needs to handle imagename besides noderange +# so do not fill {noderange} if imagename given +my $str = join(',', @tmpargv); +if (($bname =~ /lslite/) && $str =~ /-i/) +{ + $arg = "NO_NODE_RANGE"; +} +else +{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list. + $arg=shift(@ARGV); + while ($arg =~ /^-/) { + push (@{$cmdref->{arg}}, $arg); + $arg=shift(@ARGV); + } +} + +if ($arg ne "NO_NODE_RANGE") { + # The noderange can be specified through a noderange file, + # the noderange file can be a relative path, + # convert the relative path to a full path. + # an ideal way is converting the relative path in xCAT::Noderange::noderange, + # but the existing xCAT::Noderange::noderange can not get the cwd(), + # needs to change all the callers to pass the cwd(), + # there are more than 100 callers. + my @tempnr = (); + foreach my $nr (split(/,/, $arg)) { + if ($nr =~ /^\^(.*)$/) { + my $nrf = $1; + if ($nrf !~ /^\//) { #relative path + $nrf = Cwd::abs_path($nrf); + } + $nrf = "\^" . $nrf; + push @tempnr, $nrf; + } else { + push @tempnr, $nr; + } + } + $arg = join(',',@tempnr); + $cmdref->{noderange}->[0]=$arg; +} +if (@ARGV) { + push (@{$cmdref->{arg}}, @ARGV); +} +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} + +xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); +exit $xCAT::Client::EXITCODE; diff --git a/xCAT-client/bin/clonevm b/xCAT-client/bin/clonevm deleted file mode 120000 index b1c9eea11..000000000 --- a/xCAT-client/bin/clonevm +++ /dev/null @@ -1 +0,0 @@ -xcatclient \ No newline at end of file diff --git a/xCAT-client/bin/clonevm b/xCAT-client/bin/clonevm new file mode 100755 index 000000000..d721a8cb1 --- /dev/null +++ b/xCAT-client/bin/clonevm @@ -0,0 +1,102 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# Used as a standard client cmd that can be used for many of the xcat cmds. +# It grabs the arguments, noderange, and stdin and then submits the request to +# xcatd and waits for responses. Most of the client/server communication is +# contained in Client.pm. + +# To use this, sym link your cmd name to this script. + +BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } +use lib "$::XCATROOT/lib/perl"; +use Cwd; +#use IO::Socket::SSL; +#use IO::Socket::INET; +use File::Basename; +#use Data::Dumper; +use xCAT::Client; +use strict; +my $bname = basename($0); +my $cmdref; +if ($bname =~ /xcatclient/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin +else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient +$cmdref->{cwd}->[0] = cwd(); + +my $data; +# allows our plugins to get the stdin of the cmd that invoked the plugin +if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) ) +{ + my $rin=""; + my $rout; + vec($rin,fileno(STDIN),1)=1; + my $nfound=select($rout=$rin,"","",1); + if ($nfound) + { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +else +{ + if (-p STDIN) { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} + + +my $arg; +my @tmpargv = @ARGV; + +# lslite needs to handle imagename besides noderange +# so do not fill {noderange} if imagename given +my $str = join(',', @tmpargv); +if (($bname =~ /lslite/) && $str =~ /-i/) +{ + $arg = "NO_NODE_RANGE"; +} +else +{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list. + $arg=shift(@ARGV); + while ($arg =~ /^-/) { + push (@{$cmdref->{arg}}, $arg); + $arg=shift(@ARGV); + } +} + +if ($arg ne "NO_NODE_RANGE") { + # The noderange can be specified through a noderange file, + # the noderange file can be a relative path, + # convert the relative path to a full path. + # an ideal way is converting the relative path in xCAT::Noderange::noderange, + # but the existing xCAT::Noderange::noderange can not get the cwd(), + # needs to change all the callers to pass the cwd(), + # there are more than 100 callers. + my @tempnr = (); + foreach my $nr (split(/,/, $arg)) { + if ($nr =~ /^\^(.*)$/) { + my $nrf = $1; + if ($nrf !~ /^\//) { #relative path + $nrf = Cwd::abs_path($nrf); + } + $nrf = "\^" . $nrf; + push @tempnr, $nrf; + } else { + push @tempnr, $nr; + } + } + $arg = join(',',@tempnr); + $cmdref->{noderange}->[0]=$arg; +} +if (@ARGV) { + push (@{$cmdref->{arg}}, @ARGV); +} +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} + +xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); +exit $xCAT::Client::EXITCODE; diff --git a/xCAT-client/bin/rmigrate b/xCAT-client/bin/rmigrate deleted file mode 120000 index b1c9eea11..000000000 --- a/xCAT-client/bin/rmigrate +++ /dev/null @@ -1 +0,0 @@ -xcatclient \ No newline at end of file diff --git a/xCAT-client/bin/rmigrate b/xCAT-client/bin/rmigrate new file mode 100755 index 000000000..d721a8cb1 --- /dev/null +++ b/xCAT-client/bin/rmigrate @@ -0,0 +1,102 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# Used as a standard client cmd that can be used for many of the xcat cmds. +# It grabs the arguments, noderange, and stdin and then submits the request to +# xcatd and waits for responses. Most of the client/server communication is +# contained in Client.pm. + +# To use this, sym link your cmd name to this script. + +BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } +use lib "$::XCATROOT/lib/perl"; +use Cwd; +#use IO::Socket::SSL; +#use IO::Socket::INET; +use File::Basename; +#use Data::Dumper; +use xCAT::Client; +use strict; +my $bname = basename($0); +my $cmdref; +if ($bname =~ /xcatclient/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin +else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient +$cmdref->{cwd}->[0] = cwd(); + +my $data; +# allows our plugins to get the stdin of the cmd that invoked the plugin +if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) ) +{ + my $rin=""; + my $rout; + vec($rin,fileno(STDIN),1)=1; + my $nfound=select($rout=$rin,"","",1); + if ($nfound) + { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +else +{ + if (-p STDIN) { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} + + +my $arg; +my @tmpargv = @ARGV; + +# lslite needs to handle imagename besides noderange +# so do not fill {noderange} if imagename given +my $str = join(',', @tmpargv); +if (($bname =~ /lslite/) && $str =~ /-i/) +{ + $arg = "NO_NODE_RANGE"; +} +else +{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list. + $arg=shift(@ARGV); + while ($arg =~ /^-/) { + push (@{$cmdref->{arg}}, $arg); + $arg=shift(@ARGV); + } +} + +if ($arg ne "NO_NODE_RANGE") { + # The noderange can be specified through a noderange file, + # the noderange file can be a relative path, + # convert the relative path to a full path. + # an ideal way is converting the relative path in xCAT::Noderange::noderange, + # but the existing xCAT::Noderange::noderange can not get the cwd(), + # needs to change all the callers to pass the cwd(), + # there are more than 100 callers. + my @tempnr = (); + foreach my $nr (split(/,/, $arg)) { + if ($nr =~ /^\^(.*)$/) { + my $nrf = $1; + if ($nrf !~ /^\//) { #relative path + $nrf = Cwd::abs_path($nrf); + } + $nrf = "\^" . $nrf; + push @tempnr, $nrf; + } else { + push @tempnr, $nr; + } + } + $arg = join(',',@tempnr); + $cmdref->{noderange}->[0]=$arg; +} +if (@ARGV) { + push (@{$cmdref->{arg}}, @ARGV); +} +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} + +xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); +exit $xCAT::Client::EXITCODE; diff --git a/xCAT-client/bin/rshutdown b/xCAT-client/bin/rshutdown deleted file mode 120000 index b1c9eea11..000000000 --- a/xCAT-client/bin/rshutdown +++ /dev/null @@ -1 +0,0 @@ -xcatclient \ No newline at end of file diff --git a/xCAT-client/bin/rshutdown b/xCAT-client/bin/rshutdown new file mode 100755 index 000000000..d721a8cb1 --- /dev/null +++ b/xCAT-client/bin/rshutdown @@ -0,0 +1,102 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# Used as a standard client cmd that can be used for many of the xcat cmds. +# It grabs the arguments, noderange, and stdin and then submits the request to +# xcatd and waits for responses. Most of the client/server communication is +# contained in Client.pm. + +# To use this, sym link your cmd name to this script. + +BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } +use lib "$::XCATROOT/lib/perl"; +use Cwd; +#use IO::Socket::SSL; +#use IO::Socket::INET; +use File::Basename; +#use Data::Dumper; +use xCAT::Client; +use strict; +my $bname = basename($0); +my $cmdref; +if ($bname =~ /xcatclient/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin +else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient +$cmdref->{cwd}->[0] = cwd(); + +my $data; +# allows our plugins to get the stdin of the cmd that invoked the plugin +if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) ) +{ + my $rin=""; + my $rout; + vec($rin,fileno(STDIN),1)=1; + my $nfound=select($rout=$rin,"","",1); + if ($nfound) + { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +else +{ + if (-p STDIN) { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} + + +my $arg; +my @tmpargv = @ARGV; + +# lslite needs to handle imagename besides noderange +# so do not fill {noderange} if imagename given +my $str = join(',', @tmpargv); +if (($bname =~ /lslite/) && $str =~ /-i/) +{ + $arg = "NO_NODE_RANGE"; +} +else +{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list. + $arg=shift(@ARGV); + while ($arg =~ /^-/) { + push (@{$cmdref->{arg}}, $arg); + $arg=shift(@ARGV); + } +} + +if ($arg ne "NO_NODE_RANGE") { + # The noderange can be specified through a noderange file, + # the noderange file can be a relative path, + # convert the relative path to a full path. + # an ideal way is converting the relative path in xCAT::Noderange::noderange, + # but the existing xCAT::Noderange::noderange can not get the cwd(), + # needs to change all the callers to pass the cwd(), + # there are more than 100 callers. + my @tempnr = (); + foreach my $nr (split(/,/, $arg)) { + if ($nr =~ /^\^(.*)$/) { + my $nrf = $1; + if ($nrf !~ /^\//) { #relative path + $nrf = Cwd::abs_path($nrf); + } + $nrf = "\^" . $nrf; + push @tempnr, $nrf; + } else { + push @tempnr, $nr; + } + } + $arg = join(',',@tempnr); + $cmdref->{noderange}->[0]=$arg; +} +if (@ARGV) { + push (@{$cmdref->{arg}}, @ARGV); +} +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} + +xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); +exit $xCAT::Client::EXITCODE; diff --git a/xCAT-client/bin/rspconfig b/xCAT-client/bin/rspconfig deleted file mode 120000 index b1c9eea11..000000000 --- a/xCAT-client/bin/rspconfig +++ /dev/null @@ -1 +0,0 @@ -xcatclient \ No newline at end of file diff --git a/xCAT-client/bin/rspconfig b/xCAT-client/bin/rspconfig new file mode 100755 index 000000000..d721a8cb1 --- /dev/null +++ b/xCAT-client/bin/rspconfig @@ -0,0 +1,102 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# Used as a standard client cmd that can be used for many of the xcat cmds. +# It grabs the arguments, noderange, and stdin and then submits the request to +# xcatd and waits for responses. Most of the client/server communication is +# contained in Client.pm. + +# To use this, sym link your cmd name to this script. + +BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } +use lib "$::XCATROOT/lib/perl"; +use Cwd; +#use IO::Socket::SSL; +#use IO::Socket::INET; +use File::Basename; +#use Data::Dumper; +use xCAT::Client; +use strict; +my $bname = basename($0); +my $cmdref; +if ($bname =~ /xcatclient/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin +else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient +$cmdref->{cwd}->[0] = cwd(); + +my $data; +# allows our plugins to get the stdin of the cmd that invoked the plugin +if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) ) +{ + my $rin=""; + my $rout; + vec($rin,fileno(STDIN),1)=1; + my $nfound=select($rout=$rin,"","",1); + if ($nfound) + { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +else +{ + if (-p STDIN) { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} + + +my $arg; +my @tmpargv = @ARGV; + +# lslite needs to handle imagename besides noderange +# so do not fill {noderange} if imagename given +my $str = join(',', @tmpargv); +if (($bname =~ /lslite/) && $str =~ /-i/) +{ + $arg = "NO_NODE_RANGE"; +} +else +{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list. + $arg=shift(@ARGV); + while ($arg =~ /^-/) { + push (@{$cmdref->{arg}}, $arg); + $arg=shift(@ARGV); + } +} + +if ($arg ne "NO_NODE_RANGE") { + # The noderange can be specified through a noderange file, + # the noderange file can be a relative path, + # convert the relative path to a full path. + # an ideal way is converting the relative path in xCAT::Noderange::noderange, + # but the existing xCAT::Noderange::noderange can not get the cwd(), + # needs to change all the callers to pass the cwd(), + # there are more than 100 callers. + my @tempnr = (); + foreach my $nr (split(/,/, $arg)) { + if ($nr =~ /^\^(.*)$/) { + my $nrf = $1; + if ($nrf !~ /^\//) { #relative path + $nrf = Cwd::abs_path($nrf); + } + $nrf = "\^" . $nrf; + push @tempnr, $nrf; + } else { + push @tempnr, $nr; + } + } + $arg = join(',',@tempnr); + $cmdref->{noderange}->[0]=$arg; +} +if (@ARGV) { + push (@{$cmdref->{arg}}, @ARGV); +} +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} + +xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); +exit $xCAT::Client::EXITCODE; diff --git a/xCAT-client/bin/switchblade b/xCAT-client/bin/switchblade deleted file mode 120000 index b1c9eea11..000000000 --- a/xCAT-client/bin/switchblade +++ /dev/null @@ -1 +0,0 @@ -xcatclient \ No newline at end of file diff --git a/xCAT-client/bin/switchblade b/xCAT-client/bin/switchblade new file mode 100755 index 000000000..d721a8cb1 --- /dev/null +++ b/xCAT-client/bin/switchblade @@ -0,0 +1,102 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# Used as a standard client cmd that can be used for many of the xcat cmds. +# It grabs the arguments, noderange, and stdin and then submits the request to +# xcatd and waits for responses. Most of the client/server communication is +# contained in Client.pm. + +# To use this, sym link your cmd name to this script. + +BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } +use lib "$::XCATROOT/lib/perl"; +use Cwd; +#use IO::Socket::SSL; +#use IO::Socket::INET; +use File::Basename; +#use Data::Dumper; +use xCAT::Client; +use strict; +my $bname = basename($0); +my $cmdref; +if ($bname =~ /xcatclient/) { $cmdref->{command}->[0]=shift @ARGV; } # xcatclient was invoked directly and the 1st arg is cmd name that is used to locate the plugin +else { $cmdref->{command}->[0] = $bname; } # the cmd was sym linked to xcatclient +$cmdref->{cwd}->[0] = cwd(); + +my $data; +# allows our plugins to get the stdin of the cmd that invoked the plugin +if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) ) +{ + my $rin=""; + my $rout; + vec($rin,fileno(STDIN),1)=1; + my $nfound=select($rout=$rin,"","",1); + if ($nfound) + { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +else +{ + if (-p STDIN) { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} + + +my $arg; +my @tmpargv = @ARGV; + +# lslite needs to handle imagename besides noderange +# so do not fill {noderange} if imagename given +my $str = join(',', @tmpargv); +if (($bname =~ /lslite/) && $str =~ /-i/) +{ + $arg = "NO_NODE_RANGE"; +} +else +{ # Consider the 1st non-hyphen arg to be the noderange. All others (before and after) go on the arg list. + $arg=shift(@ARGV); + while ($arg =~ /^-/) { + push (@{$cmdref->{arg}}, $arg); + $arg=shift(@ARGV); + } +} + +if ($arg ne "NO_NODE_RANGE") { + # The noderange can be specified through a noderange file, + # the noderange file can be a relative path, + # convert the relative path to a full path. + # an ideal way is converting the relative path in xCAT::Noderange::noderange, + # but the existing xCAT::Noderange::noderange can not get the cwd(), + # needs to change all the callers to pass the cwd(), + # there are more than 100 callers. + my @tempnr = (); + foreach my $nr (split(/,/, $arg)) { + if ($nr =~ /^\^(.*)$/) { + my $nrf = $1; + if ($nrf !~ /^\//) { #relative path + $nrf = Cwd::abs_path($nrf); + } + $nrf = "\^" . $nrf; + push @tempnr, $nrf; + } else { + push @tempnr, $nr; + } + } + $arg = join(',',@tempnr); + $cmdref->{noderange}->[0]=$arg; +} +if (@ARGV) { + push (@{$cmdref->{arg}}, @ARGV); +} +foreach (keys %ENV) { + if (/^XCAT_/) { + $cmdref->{environment}->{$_} = $ENV{$_}; + } +} + +xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); +exit $xCAT::Client::EXITCODE; diff --git a/xCAT-client/bin/winstall b/xCAT-client/bin/winstall deleted file mode 120000 index 0bae78d7c..000000000 --- a/xCAT-client/bin/winstall +++ /dev/null @@ -1 +0,0 @@ -rinstall \ No newline at end of file diff --git a/xCAT-client/bin/winstall b/xCAT-client/bin/winstall new file mode 100755 index 000000000..48ce9b1a1 --- /dev/null +++ b/xCAT-client/bin/winstall @@ -0,0 +1,87 @@ +#!/usr/bin/env perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +# Used as a convience command combined of [nodech]-nodeset-rsetboot-rpower-[rcons/wcons] +# to make ease of node OS provision + +# This is the client front-end to rinstall/winstall commands + + +BEGIN +{ + $::XCATROOT = + $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} + : -d '/opt/xcat' ? '/opt/xcat' + : '/usr'; +} + +use lib "$::XCATROOT/lib/perl"; +use File::Basename; +use Getopt::Long; +use xCAT::MsgUtils; +use xCAT::Utils; +use xCAT::Client; +use Cwd; +use strict; + +# build a request to go the rinstall plugin +my $bname = basename($0); +my $cmdref; +$cmdref->{command}->[0] = $bname; +$cmdref->{cwd}->[0] = cwd(); +# allows our plugins to get the stdin of the cmd that invoked the plugin +my $data; +if ( (($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'}) ) +{ + my $rin=""; + my $rout; + vec($rin,fileno(STDIN),1)=1; + my $nfound=select($rout=$rin,"","",1); + if ($nfound) + { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +else +{ + if (-p STDIN) { + while ( ) { $data.=$_; } + $cmdref->{stdin}->[0]=$data; + } +} +my $arg; +my @tmpargv = @ARGV; +# first +$arg=shift(@ARGV); +# first 1st non-hyphen arg is the noderange +while ($arg =~ /^-/) { + push (@{$cmdref->{arg}}, $arg); + $arg=shift(@ARGV); +} +$cmdref->{noderange}->[0]=$arg; +push (@{$cmdref->{arg}}, @ARGV); + +my $noderange=$cmdref->{noderange}->[0]; # save the noderange + +# ok call Client to run the plugin rinstall.pm +xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response); + +if ($xCAT::Client::EXITCODE == 0) # no errors +{ + my $startconsole=$cmdref->{startconsole}->[0]; + # if startconsole requested ( -c flag) for rinstall always for winstall + # This is set in the rinstall plugin + if ($startconsole == 1) { + if (basename($0) =~ /rinstall/) { + + exec("rcons $noderange"); + } + elsif (basename($0) =~ /winstall/) { + # winstall can commence a wcons command to the noderange for monitoring the provision cycle + + exec("wcons $noderange"); + } + } +} +exit $xCAT::Client::EXITCODE; diff --git a/xCAT-server/share/xcat/install/SL/compute.SL6.pkglist b/xCAT-server/share/xcat/install/SL/compute.SL6.pkglist deleted file mode 120000 index a2ac48243..000000000 --- a/xCAT-server/share/xcat/install/SL/compute.SL6.pkglist +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.rhels6.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/SL/compute.SL6.pkglist b/xCAT-server/share/xcat/install/SL/compute.SL6.pkglist new file mode 100644 index 000000000..675b27249 --- /dev/null +++ b/xCAT-server/share/xcat/install/SL/compute.SL6.pkglist @@ -0,0 +1,8 @@ +#Please make sure there is a space between @ and group name +ntp +nfs-utils +net-snmp +rsync +yp-tools +openssh-server +util-linux-ng diff --git a/xCAT-server/share/xcat/install/SL/compute.SL6.tmpl b/xCAT-server/share/xcat/install/SL/compute.SL6.tmpl deleted file mode 120000 index c5c95df5a..000000000 --- a/xCAT-server/share/xcat/install/SL/compute.SL6.tmpl +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.rhels6.tmpl \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/SL/compute.SL6.tmpl b/xCAT-server/share/xcat/install/SL/compute.SL6.tmpl new file mode 100644 index 000000000..5adfce92d --- /dev/null +++ b/xCAT-server/share/xcat/install/SL/compute.SL6.tmpl @@ -0,0 +1,149 @@ +# +#cmdline + +lang en_US + +# +# Where's the source? +# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image +# +#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR# + +%include /tmp/repos + +#device ethernet e100 +keyboard "us" + +# +# Clear the MBR +# +zerombr + +# +# Wipe out the disk +# +clearpart --all --initlabel +#clearpart --linux +key --skip + +# +# Customize to fit your needs +# + +#XCAT_PARTITION_START# +#No RAID +#/boot really significant for this sort of setup nowadays? +#part /boot --size 50 --fstype ext3 +%include /tmp/partitioning +#part swap --size 1024 +#part / --size 1 --grow --fstype ext4 +#XCAT_PARTITION_END# + +#RAID 0 /scr for performance +#part / --size 1024 --ondisk sda +#part swap --size 512 --ondisk sda +#part /var --size 1024 --ondisk sdb +#part swap --size 512 --ondisk sdb +#part raid.01 --size 1 --grow --ondisk sda +#part raid.02 --size 1 --grow --ondisk sdb +#raid /scr --level 0 --device md0 raid.01 raid.02 + +#Full RAID 1 Sample +#part raid.01 --size 50 --ondisk sda +#part raid.02 --size 50 --ondisk sdb +#raid /boot --level 1 --device md0 raid.01 raid.02 +# +#part raid.11 --size 1024 --ondisk sda +#part raid.12 --size 1024 --ondisk sdb +#raid / --level 1 --device md1 raid.11 raid.12 +# +#part raid.21 --size 1024 --ondisk sda +#part raid.22 --size 1024 --ondisk sdb +#raid /var --level 1 --device md2 raid.21 raid.22 +# +#part raid.31 --size 1024 --ondisk sda +#part raid.32 --size 1024 --ondisk sdb +#raid swap --level 1 --device md3 raid.31 raid.32 +# +#part raid.41 --size 1 --grow --ondisk sda +#part raid.42 --size 1 --grow --ondisk sdb +#raid /scr --level 1 --device md4 raid.41 raid.42 + +# +# bootloader config +# --append +# --useLilo +# --md5pass +# +bootloader + +# +# install or upgrade +# +install + +# +# text mode install (default is graphical) +# +#text + +# +# firewall +# +firewall --disabled + +# +# Select a zone +# Add the --utc switch if your hardware clock is set to GMT +# +#timezone US/Hawaii +#timezone US/Pacific +#timezone US/Mountain +#timezone US/Central +#timezone US/Eastern +timezone --utc "#TABLE:site:key=timezone:value#" + +# +# Don't do X +# +skipx + + +# +# To generate an encrypted root password use: +# +# perl -e 'print crypt("blah","Xa") . "\n";'p +# openssl passwd -apr1 -salt xxxxxxxx password +# +# where "blah" is your root password. +# +#rootpw --iscrypted XaLGAVe1C41x2 +#rootpw XaLGAVe1C41x2 --iscrypted +rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password# + +# +# NIS setup: auth --enablenis --nisdomain sensenet +# --nisserver neptune --useshadow --enablemd5 +# +# OR +auth --useshadow --enablemd5 + +# +# SE Linux +# +selinux --disabled + +# +# Reboot after installation +# +reboot + +# +#end of section +# +%packages +#INCLUDE_DEFAULT_PKGLIST# +%pre +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh# +%post +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.rh# diff --git a/xCAT-server/share/xcat/install/esxi/base.esxi4.1.tmpl b/xCAT-server/share/xcat/install/esxi/base.esxi4.1.tmpl deleted file mode 120000 index 0af27f47f..000000000 --- a/xCAT-server/share/xcat/install/esxi/base.esxi4.1.tmpl +++ /dev/null @@ -1 +0,0 @@ -../esx/base.esxi4.1.tmpl \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/esxi/base.esxi4.1.tmpl b/xCAT-server/share/xcat/install/esxi/base.esxi4.1.tmpl new file mode 100644 index 000000000..ee2bb0cd1 --- /dev/null +++ b/xCAT-server/share/xcat/install/esxi/base.esxi4.1.tmpl @@ -0,0 +1,36 @@ +# Sample scripted installation file +# edited and updated by vallard@sumavi.com + +# Accept the VMware End User License Agreement +vmaccepteula + +# Set the root password for the DCUI and Tech Support Mode +rootpw --iscrypted #CRYPT:passwd:key=vmware,username=root:password# + +# clear all partitions. +clearpart --alldrives --overwritevmfs +# Choose the first disk (in channel/target/lun order) to install onto +autopart --firstdisk --overwritevmfs + +# The install media is on the network. +install url http://#TABLE:noderes:$NODE:nfsserver#/install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch# + + +# Set the network to DHCP on the first network adapter +#network --bootproto=dhcp --device=vmnic0 +network --bootproto=dhcp + +# reboot automatically when we're done. +reboot + +# A sample post-install script +%post --interpreter=busybox --unsupported --ignorefailure=true + +# tell xCAT management server we are done installing +# have to put in the IP address instead of the hostname because VMware +# ESXi 4.1 can not resolve IP addresses... +echo "\nnextdestiny\n" | /bin/openssl s_client -quiet -connect #COMMAND: host #TABLE:noderes:$NODE:xcatmaster# | head -1 | sed 's/.*address//g' #:3001 2>&1 | tee /tmp/foo.log + +# enable SSH on next boot: +%firstboot --interpreter=busybox --unsupported --level=47 +sed -ie 's/#ssh/ssh/' /etc/inetd.conf #ssh is too nice not to have diff --git a/xCAT-server/share/xcat/install/fedora/compute.fedora12.tmpl b/xCAT-server/share/xcat/install/fedora/compute.fedora12.tmpl deleted file mode 120000 index 20d269a83..000000000 --- a/xCAT-server/share/xcat/install/fedora/compute.fedora12.tmpl +++ /dev/null @@ -1 +0,0 @@ -compute.fedora13.tmpl \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/fedora/compute.fedora12.tmpl b/xCAT-server/share/xcat/install/fedora/compute.fedora12.tmpl new file mode 100644 index 000000000..79eedbac9 --- /dev/null +++ b/xCAT-server/share/xcat/install/fedora/compute.fedora12.tmpl @@ -0,0 +1,149 @@ +#egan@us.ibm.com +# +cmdline + +lang en_US +network --bootproto dhcp --hostname=#HOSTNAME# + +# +# Where's the source? +# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image +# +#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR# +url --url http://#TABLE:noderes:$NODE:nfsserver#/install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch# + +#device ethernet e100 +keyboard "us" + +# +# Clear the MBR +# +zerombr yes + +# +# Wipe out the disk +# +clearpart --all --initlabel +#clearpart --linux +key --skip + +# +# Customize to fit your needs +# + +#XCAT_PARTITION_START# +#No RAID +#/boot really significant for this sort of setup nowadays? +#part /boot --size 50 --fstype ext3 +part swap --size 1024 +part / --size 1 --grow --fstype ext4 +#XCAT_PARTITION_END# + +#RAID 0 /scr for performance +#part / --size 1024 --ondisk sda +#part swap --size 512 --ondisk sda +#part /var --size 1024 --ondisk sdb +#part swap --size 512 --ondisk sdb +#part raid.01 --size 1 --grow --ondisk sda +#part raid.02 --size 1 --grow --ondisk sdb +#raid /scr --level 0 --device md0 raid.01 raid.02 + +#Full RAID 1 Sample +#part raid.01 --size 50 --ondisk sda +#part raid.02 --size 50 --ondisk sdb +#raid /boot --level 1 --device md0 raid.01 raid.02 +# +#part raid.11 --size 1024 --ondisk sda +#part raid.12 --size 1024 --ondisk sdb +#raid / --level 1 --device md1 raid.11 raid.12 +# +#part raid.21 --size 1024 --ondisk sda +#part raid.22 --size 1024 --ondisk sdb +#raid /var --level 1 --device md2 raid.21 raid.22 +# +#part raid.31 --size 1024 --ondisk sda +#part raid.32 --size 1024 --ondisk sdb +#raid swap --level 1 --device md3 raid.31 raid.32 +# +#part raid.41 --size 1 --grow --ondisk sda +#part raid.42 --size 1 --grow --ondisk sdb +#raid /scr --level 1 --device md4 raid.41 raid.42 + +# +# bootloader config +# --append +# --useLilo +# --md5pass +# +bootloader + +# +# install or upgrade +# +install + +# +# text mode install (default is graphical) +# +text + +# +# firewall +# +firewall --disabled + +# +# Select a zone +# Add the --utc switch if your hardware clock is set to GMT +# +#timezone US/Hawaii +#timezone US/Pacific +#timezone US/Mountain +#timezone US/Central +#timezone US/Eastern +timezone --utc "#TABLE:site:key=timezone:value#" + +# +# Don't do X +# +skipx + + +# +# To generate an encrypted root password use: +# +# perl -e 'print crypt("blah","Xa") . "\n";'p +# openssl passwd -apr1 -salt xxxxxxxx password +# +# where "blah" is your root password. +# +#rootpw --iscrypted XaLGAVe1C41x2 +#rootpw XaLGAVe1C41x2 --iscrypted +rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password# + +# +# NIS setup: auth --enablenis --nisdomain sensenet +# --nisserver neptune --useshadow --enablemd5 +# +# OR +auth --useshadow --enablemd5 + +# +# SE Linux +# +selinux --disabled + +# +# Reboot after installation +# +reboot + +# +#end of section +# +%packages +#INCLUDE_DEFAULT_PKGLIST# +%pre +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh# +%post +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.rh# diff --git a/xCAT-server/share/xcat/install/fedora/compute.fedora15.pkglist b/xCAT-server/share/xcat/install/fedora/compute.fedora15.pkglist deleted file mode 120000 index 7101667e8..000000000 --- a/xCAT-server/share/xcat/install/fedora/compute.fedora15.pkglist +++ /dev/null @@ -1 +0,0 @@ -compute.fedora14.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/fedora/compute.fedora15.pkglist b/xCAT-server/share/xcat/install/fedora/compute.fedora15.pkglist new file mode 100644 index 000000000..675b27249 --- /dev/null +++ b/xCAT-server/share/xcat/install/fedora/compute.fedora15.pkglist @@ -0,0 +1,8 @@ +#Please make sure there is a space between @ and group name +ntp +nfs-utils +net-snmp +rsync +yp-tools +openssh-server +util-linux-ng diff --git a/xCAT-server/share/xcat/install/fedora/compute.fedora15.tmpl b/xCAT-server/share/xcat/install/fedora/compute.fedora15.tmpl deleted file mode 120000 index 334df473d..000000000 --- a/xCAT-server/share/xcat/install/fedora/compute.fedora15.tmpl +++ /dev/null @@ -1 +0,0 @@ -compute.fedora14.tmpl \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/fedora/compute.fedora15.tmpl b/xCAT-server/share/xcat/install/fedora/compute.fedora15.tmpl new file mode 100644 index 000000000..932dd932f --- /dev/null +++ b/xCAT-server/share/xcat/install/fedora/compute.fedora15.tmpl @@ -0,0 +1,151 @@ +#egan@us.ibm.com +# +cmdline + +lang en_US +network --bootproto dhcp --hostname=#HOSTNAME# + +# +# Where's the source? +# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image +# +#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR# +url --url http://#TABLE:noderes:$NODE:nfsserver#/install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch# + +#device ethernet e100 +keyboard "us" + +# +# Clear the MBR +# +zerombr + +# +# Wipe out the disk +# +clearpart --all --initlabel +#clearpart --linux + +# +# Customize to fit your needs +# + +#XCAT_PARTITION_START# +#No RAID +#/boot really significant for this sort of setup nowadays? +#part /boot --size 50 --fstype ext3 +part swap --size 1024 +part / --size 1 --grow --fstype ext4 +#XCAT_PARTITION_END# + +#RAID 0 /scr for performance +#part / --size 1024 --ondisk sda +#part swap --size 512 --ondisk sda +#part /var --size 1024 --ondisk sdb +#part swap --size 512 --ondisk sdb +#part raid.01 --size 1 --grow --ondisk sda +#part raid.02 --size 1 --grow --ondisk sdb +#raid /scr --level 0 --device md0 raid.01 raid.02 + +#Full RAID 1 Sample +#part raid.01 --size 50 --ondisk sda +#part raid.02 --size 50 --ondisk sdb +#raid /boot --level 1 --device md0 raid.01 raid.02 +# +#part raid.11 --size 1024 --ondisk sda +#part raid.12 --size 1024 --ondisk sdb +#raid / --level 1 --device md1 raid.11 raid.12 +# +#part raid.21 --size 1024 --ondisk sda +#part raid.22 --size 1024 --ondisk sdb +#raid /var --level 1 --device md2 raid.21 raid.22 +# +#part raid.31 --size 1024 --ondisk sda +#part raid.32 --size 1024 --ondisk sdb +#raid swap --level 1 --device md3 raid.31 raid.32 +# +#part raid.41 --size 1 --grow --ondisk sda +#part raid.42 --size 1 --grow --ondisk sdb +#raid /scr --level 1 --device md4 raid.41 raid.42 + +# +# bootloader config +# --append +# --useLilo +# --md5pass +# +bootloader + +# +# install or upgrade +# +install + +# +# text mode install (default is graphical) +# +text + +# +# firewall +# +firewall --disabled + +# +# Select a zone +# Add the --utc switch if your hardware clock is set to GMT +# +#timezone US/Hawaii +#timezone US/Pacific +#timezone US/Mountain +#timezone US/Central +#timezone US/Eastern +timezone --utc "#TABLE:site:key=timezone:value#" + +# +# Don't do X +# +skipx + + +# +# To generate an encrypted root password use: +# +# perl -e 'print crypt("blah","Xa") . "\n";'p +# openssl passwd -apr1 -salt xxxxxxxx password +# +# where "blah" is your root password. +# +#rootpw --iscrypted XaLGAVe1C41x2 +#rootpw XaLGAVe1C41x2 --iscrypted +rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password# + +# +# NIS setup: auth --enablenis --nisdomain sensenet +# --nisserver neptune --useshadow --enablemd5 +# +# OR +auth --useshadow --enablemd5 + +# +# SE Linux +# +selinux --disabled + +# +# Reboot after installation +# +reboot + +# +#end of section +# +%packages +#INCLUDE_DEFAULT_PKGLIST# +%end +%pre +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh# +%end +%post +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.rh# +%end diff --git a/xCAT-server/share/xcat/install/ol/compute.ol6.pkglist b/xCAT-server/share/xcat/install/ol/compute.ol6.pkglist deleted file mode 120000 index a2ac48243..000000000 --- a/xCAT-server/share/xcat/install/ol/compute.ol6.pkglist +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.rhels6.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/ol/compute.ol6.pkglist b/xCAT-server/share/xcat/install/ol/compute.ol6.pkglist new file mode 100644 index 000000000..675b27249 --- /dev/null +++ b/xCAT-server/share/xcat/install/ol/compute.ol6.pkglist @@ -0,0 +1,8 @@ +#Please make sure there is a space between @ and group name +ntp +nfs-utils +net-snmp +rsync +yp-tools +openssh-server +util-linux-ng diff --git a/xCAT-server/share/xcat/install/ol/compute.ol6.tmpl b/xCAT-server/share/xcat/install/ol/compute.ol6.tmpl deleted file mode 120000 index c5c95df5a..000000000 --- a/xCAT-server/share/xcat/install/ol/compute.ol6.tmpl +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.rhels6.tmpl \ No newline at end of file diff --git a/xCAT-server/share/xcat/install/ol/compute.ol6.tmpl b/xCAT-server/share/xcat/install/ol/compute.ol6.tmpl new file mode 100644 index 000000000..5adfce92d --- /dev/null +++ b/xCAT-server/share/xcat/install/ol/compute.ol6.tmpl @@ -0,0 +1,149 @@ +# +#cmdline + +lang en_US + +# +# Where's the source? +# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image +# +#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR# + +%include /tmp/repos + +#device ethernet e100 +keyboard "us" + +# +# Clear the MBR +# +zerombr + +# +# Wipe out the disk +# +clearpart --all --initlabel +#clearpart --linux +key --skip + +# +# Customize to fit your needs +# + +#XCAT_PARTITION_START# +#No RAID +#/boot really significant for this sort of setup nowadays? +#part /boot --size 50 --fstype ext3 +%include /tmp/partitioning +#part swap --size 1024 +#part / --size 1 --grow --fstype ext4 +#XCAT_PARTITION_END# + +#RAID 0 /scr for performance +#part / --size 1024 --ondisk sda +#part swap --size 512 --ondisk sda +#part /var --size 1024 --ondisk sdb +#part swap --size 512 --ondisk sdb +#part raid.01 --size 1 --grow --ondisk sda +#part raid.02 --size 1 --grow --ondisk sdb +#raid /scr --level 0 --device md0 raid.01 raid.02 + +#Full RAID 1 Sample +#part raid.01 --size 50 --ondisk sda +#part raid.02 --size 50 --ondisk sdb +#raid /boot --level 1 --device md0 raid.01 raid.02 +# +#part raid.11 --size 1024 --ondisk sda +#part raid.12 --size 1024 --ondisk sdb +#raid / --level 1 --device md1 raid.11 raid.12 +# +#part raid.21 --size 1024 --ondisk sda +#part raid.22 --size 1024 --ondisk sdb +#raid /var --level 1 --device md2 raid.21 raid.22 +# +#part raid.31 --size 1024 --ondisk sda +#part raid.32 --size 1024 --ondisk sdb +#raid swap --level 1 --device md3 raid.31 raid.32 +# +#part raid.41 --size 1 --grow --ondisk sda +#part raid.42 --size 1 --grow --ondisk sdb +#raid /scr --level 1 --device md4 raid.41 raid.42 + +# +# bootloader config +# --append +# --useLilo +# --md5pass +# +bootloader + +# +# install or upgrade +# +install + +# +# text mode install (default is graphical) +# +#text + +# +# firewall +# +firewall --disabled + +# +# Select a zone +# Add the --utc switch if your hardware clock is set to GMT +# +#timezone US/Hawaii +#timezone US/Pacific +#timezone US/Mountain +#timezone US/Central +#timezone US/Eastern +timezone --utc "#TABLE:site:key=timezone:value#" + +# +# Don't do X +# +skipx + + +# +# To generate an encrypted root password use: +# +# perl -e 'print crypt("blah","Xa") . "\n";'p +# openssl passwd -apr1 -salt xxxxxxxx password +# +# where "blah" is your root password. +# +#rootpw --iscrypted XaLGAVe1C41x2 +#rootpw XaLGAVe1C41x2 --iscrypted +rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password# + +# +# NIS setup: auth --enablenis --nisdomain sensenet +# --nisserver neptune --useshadow --enablemd5 +# +# OR +auth --useshadow --enablemd5 + +# +# SE Linux +# +selinux --disabled + +# +# Reboot after installation +# +reboot + +# +#end of section +# +%packages +#INCLUDE_DEFAULT_PKGLIST# +%pre +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh# +%post +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.rh# diff --git a/xCAT-server/share/xcat/netboot/SL/compute.SL6.pkglist b/xCAT-server/share/xcat/netboot/SL/compute.SL6.pkglist deleted file mode 120000 index a2ac48243..000000000 --- a/xCAT-server/share/xcat/netboot/SL/compute.SL6.pkglist +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.rhels6.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/compute.SL6.pkglist b/xCAT-server/share/xcat/netboot/SL/compute.SL6.pkglist new file mode 100644 index 000000000..555ec63cc --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/compute.SL6.pkglist @@ -0,0 +1,15 @@ +bash +dracut-network +nfs-utils +openssl +dhclient +kernel +openssh-server +openssh-clients +wget +vim-minimal +ntp +rpm +rsync +rsyslog +e2fsprogs diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/check b/xCAT-server/share/xcat/netboot/SL/dracut/check deleted file mode 120000 index 87ffb9d77..000000000 --- a/xCAT-server/share/xcat/netboot/SL/dracut/check +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/check \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/check b/xCAT-server/share/xcat/netboot/SL/dracut/check new file mode 100755 index 000000000..d7cc89ce0 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/dracut/check @@ -0,0 +1,3 @@ +#!/bin/sh +[ "$1" = "-d" ] && echo network +exit 0 diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/install.netboot b/xCAT-server/share/xcat/netboot/SL/dracut/install.netboot deleted file mode 120000 index 642f46713..000000000 --- a/xCAT-server/share/xcat/netboot/SL/dracut/install.netboot +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/install.netboot \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/install.netboot b/xCAT-server/share/xcat/netboot/SL/dracut/install.netboot new file mode 100755 index 000000000..d9fe9c714 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/dracut/install.netboot @@ -0,0 +1,10 @@ +#!/bin/sh +echo $drivers +dracut_install wget cpio gzip dash modprobe touch echo cut wc +dracut_install -o ctorrent +dracut_install grep ifconfig hostname awk egrep grep dirname expr +dracut_install mount.nfs +dracut_install parted mke2fs bc mkswap swapon chmod +inst "$moddir/xcat-updateflag" "/tmp/updateflag" +inst "$moddir/xcatroot" "/sbin/xcatroot" +inst_hook cmdline 10 "$moddir/xcat-cmdline.sh" diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/install.statelite b/xCAT-server/share/xcat/netboot/SL/dracut/install.statelite deleted file mode 120000 index a29fbcca1..000000000 --- a/xCAT-server/share/xcat/netboot/SL/dracut/install.statelite +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/install.statelite \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/install.statelite b/xCAT-server/share/xcat/netboot/SL/dracut/install.statelite new file mode 100755 index 000000000..7c494d84c --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/dracut/install.statelite @@ -0,0 +1,9 @@ +#!/bin/sh +echo $drivers +dracut_install wget cpio gzip dash modprobe wc touch echo cut +dracut_install -o ctorrent +dracut_install grep ifconfig hostname awk egrep grep dirname expr +dracut_install parted mke2fs bc mkswap swapon chmod +inst "$moddir/xcat-updateflag" "/tmp/updateflag" +inst_hook pre-mount 5 "$moddir/xcat-premount.sh" +inst_hook pre-pivot 5 "$moddir/xcat-prepivot.sh" diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/installkernel b/xCAT-server/share/xcat/netboot/SL/dracut/installkernel deleted file mode 120000 index 65990228e..000000000 --- a/xCAT-server/share/xcat/netboot/SL/dracut/installkernel +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/installkernel \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/installkernel b/xCAT-server/share/xcat/netboot/SL/dracut/installkernel new file mode 100755 index 000000000..7902ce5f7 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/dracut/installkernel @@ -0,0 +1,2 @@ +#!/bin/bash +instmods nfs sunrpc diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/xcat-cmdline.sh b/xCAT-server/share/xcat/netboot/SL/dracut/xcat-cmdline.sh deleted file mode 120000 index 76c6651f6..000000000 --- a/xCAT-server/share/xcat/netboot/SL/dracut/xcat-cmdline.sh +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-cmdline.sh \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/xcat-cmdline.sh b/xCAT-server/share/xcat/netboot/SL/dracut/xcat-cmdline.sh new file mode 100644 index 000000000..d445cf585 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/dracut/xcat-cmdline.sh @@ -0,0 +1,4 @@ +root=1 +rootok=1 +netroot=xcat +echo '[ -e $NEWROOT/proc ]' > /initqueue-finished/xcatroot.sh diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/xcat-prepivot.sh b/xCAT-server/share/xcat/netboot/SL/dracut/xcat-prepivot.sh deleted file mode 120000 index d2b623c6c..000000000 --- a/xCAT-server/share/xcat/netboot/SL/dracut/xcat-prepivot.sh +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-prepivot.sh \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/xcat-prepivot.sh b/xCAT-server/share/xcat/netboot/SL/dracut/xcat-prepivot.sh new file mode 100755 index 000000000..73498a91e --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/dracut/xcat-prepivot.sh @@ -0,0 +1,126 @@ +#!/bin/sh +NEWROOT=/sysroot +SERVER=${SERVER%%/*} +SERVER=${SERVER%:} +RWDIR=.statelite +if [ ! -z $STATEMNT ]; then #btw, uri style might have left future options other than nfs open, will u se // to detect uri in the future I guess + SNAPSHOTSERVER=${STATEMNT%:*} + SNAPSHOTROOT=${STATEMNT#*/} + #echo $SNAPSHOTROOT + #echo $SNAPSHOTSERVER + # may be that there is not server and just a directory. + if [ -z $SNAPSHOTROOT ]; then + SNAPSHOTROOT=$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi +fi + +echo Setting up Statelite +mkdir -p $NEWROOT + +# now we need to mount the rest of the system. This is the read/write portions +# echo Mounting snapshot directories + +MAXTRIES=7 +ITER=0 +if [ ! -e "$NEWROOT/$RWDIR" ]; then + echo "" + echo "This NFS root directory doesn't have a /$RWDIR directory for me to mount a rw filesystem. You'd better create it... " + echo "" + /bin/sh +fi + +if [ ! -e "$NEWROOT/etc/init.d/statelite" ]; then + echo "" + echo "$NEWROOT/etc/init.d/statelite doesn't exist. Perhaps you didn't create this image with th e -m statelite mode" + echo "" + /bin/sh +fi + +mount -t tmpfs rw $NEWROOT/$RWDIR +mkdir -p $NEWROOT/$RWDIR/tmpfs +ME=`hostname` +if [ ! -z $NODE ]; then + ME=$NODE +fi + +# mount the SNAPSHOT directory here for persistent use. +if [ ! -z $SNAPSHOTSERVER ]; then + mkdir -p $NEWROOT/$RWDIR/persistent + MAXTRIES=5 + ITER=0 + if [ -z $MNTOPTS ]; then + MNT_OPTIONS="nolock,rsize=32768,tcp,nfsvers=3,timeo=14" + else + MNT_OPTIONS=$MNTOPTS + fi + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are 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." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + + # create directory which is named after my node name + mkdir -p $NEWROOT/$RWDIR/persistent/$ME + ITER=0 + # umount current persistent mount + while ! umount -l $NEWROOT/$RWDIR/persistent; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Cannot umount $NEWROOT/$RWDIR/persistent." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + + # mount persistent to server:/rootpath/nodename + ITER=0 + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Possible problems: cannot mount to $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done +fi + +# TODO: handle the dhclient/resolv.conf/ntp, etc +echo "Get to enable localdisk" +$NEWROOT/etc/init.d/localdisk +$NEWROOT/etc/init.d/statelite +READONLY=yes +export READONLY +fastboot=yes +export fastboot +keep_old_ip=yes +export keep_old_ip +mount -n --bind /dev $NEWROOT/dev +mount -n --bind /proc $NEWROOT/proc +mount -n --bind /sys $NEWROOT/sys + +if [ -d "$NEWROOT/etc/sysconfig" -a ! -e "$NEWROOT/etc/sysconfig/selinux" ]; then + echo "SELINUX=disabled" >> "$NEWROOT/etc/sysconfig/selinux" +fi + +# inject new exit_if_exists +echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$job"' > /initqueue/xcat.sh +# force udevsettle to break +> /initqueue/work diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/xcatroot b/xCAT-server/share/xcat/netboot/SL/dracut/xcatroot deleted file mode 120000 index babd2fb9d..000000000 --- a/xCAT-server/share/xcat/netboot/SL/dracut/xcatroot +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcatroot \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/dracut/xcatroot b/xCAT-server/share/xcat/netboot/SL/dracut/xcatroot new file mode 100755 index 000000000..e18f532a5 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/dracut/xcatroot @@ -0,0 +1,263 @@ +#!/bin/sh +NEWROOT=$3 +RWDIR=.statelite +XCATMASTER=$XCAT + +. /lib/dracut-lib.sh +rootlimit="$(getarg rootlimit=)" + + +getarg nonodestatus +NODESTATUS=$? + +MASTER=`echo $XCATMASTER |awk -F: '{print $1}'` +XCATIPORT="$(getarg XCATIPORT=)" +if [ $? -ne 0 ]; then +XCATIPORT="3002" +fi + + +if [ $NODESTATUS -ne 0 ];then +/tmp/updateflag $MASTER $XCATIPORT "installstatus netbooting" +fi + +if [ ! -z "$imgurl" ]; then + if [ xhttp = x${imgurl%%:*} ]; then + NFS=0 + FILENAME=${imgurl##*/} + while [ ! -r "$FILENAME" ]; do + echo Getting $imgurl... + if ! wget $imgurl; then + rm -f $FILENAME + sleep 27 + fi + done + elif [ xnfs = x${imgurl%%:*} ]; then + NFS=1 + SERVER=${imgurl#nfs:} + SERVER=${SERVER#/} + SERVER=${SERVER#/} + ROOTDIR=$SERVER + SERVER=${SERVER%%/*} + SERVER=${SERVER%:} + ROOTDIR=/${ROOTDIR#*/} + fi +fi +#echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +if [ -r /*.metainfo ]; then + ctorrent /*.metainfo -e 0 +fi +if [ -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 $NEWROOT + mkdir -p $NEWROOT/ro + mkdir -p $NEWROOT/rw + mount --move /ro $NEWROOT/ro + mount --move /rw $NEWROOT/rw +elif [ -r /rootimg.gz ]; then + echo Setting up RAM-root tmpfs. + if [ -z $rootlimit ];then + mount -t tmpfs -o mode=755 rootfs $NEWROOT + else + mount -t tmpfs -o mode=755,size=$rootlimit rootfs $NEWROOT + fi + + cd $NEWROOT + echo -n "Extracting root filesystem:" + if [ -x /bin/cpio ]; then + gzip -cd /rootimg.gz |/bin/cpio -idum + else + gzip -cd /rootimg.gz |cpio -idum + fi + $NEWROOT/etc/init.d/localdisk + echo Done +elif [ -r /rootimg-statelite.gz ]; then + echo Setting up RAM-root tmpfs for statelite mode. + + if [ -z $rootlimit];then + mount -t tmpfs -o mode=755 rootfs $NEWROOT + else + mount -t tmpfs -o mode=755,size=$rootlimit rootfs $NEWROOT + fi + + cd $NEWROOT + echo -n "Extracting root filesystem:" + if [ -x /bin/cpio ]; then + gzip -cd /rootimg-statelite.gz |/bin/cpio -idum + else + gzip -cd /rootimg-statelite.gz |cpio -idum + fi + echo Done + # then, the statelite staffs will be processed + echo Setting up Statelite + modprobe nfs + MAXTRIES=7 + ITER=0 + if [ ! -e "$NEWROOT/$RWDIR" ]; then + echo "" + echo "The /$RWDIR directory doesn't exist in the rootimg... " + echo "" + /bin/sh + fi + + if [ ! -e "$NEWROOT/etc/init.d/statelite" ]; then + echo "" + echo "$NEWROOT/etc/init.d/statelite doesn't exist... " + echo "" + /bin/sh + fi + + mount -t tmpfs rw $NEWROOT/$RWDIR + mkdir -p $NEWROOT/$RWDIR/tmpfs + ME=`hostname` + if [ ! -z $NODE ]; then + ME=$NODE + fi + + + # mount the SNAPSHOT directory here for persistent use. + if [ ! -z $STATEMNT ]; then + SNAPSHOTSERVER=${STATEMNT%:*} + SNAPSHOTROOT=${STATEMNT#*/} + if [ -z $SNAPSHOTROOT ]; then + SNAPSHOTROOT=$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + + if [ ! -z $SNAPSHOTSERVER ]; then + mkdir -p $NEWROOT/$RWDIR/persistent + MAXTRIES=5 + ITER=0 + if [ -z $MNTOPTS ]; then + MNT_OPTIONS="nolock,rsize=32768,tcp,nfsvers=3,timeo=14" + else + MNT_OPTIONS=$MNTOPTS + fi + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "You are 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." + /bin/sh + exit + fi + RS=$(( $RANDOM % 20 )) + echo "Trying again in $RS seconds ..." + sleep $RS + done + + # create directory which is named after my node name + mkdir -p $NEWROOT/$RWDIR/persistent/$ME + ITER=0 + # umount current persistent mount + while ! umount -l $NEWROOT/$RWDIR/persistent; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Cannot umount $NEWROOT/$RWDIR/persistent." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + + # mount persistent to server:/rootpath/nodename + ITER=0 + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Possible problems: cannot mount to $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + fi + + $NEWROOT/etc/init.d/localdisk + $NEWROOT/etc/init.d/statelite + fastboot=yes + export fastboot + keep_old_ip=yes + export keep_old_ip + + mount -n --bind /dev $NEWROOT/dev + mount -n --bind /proc $NEWROOT/proc + mount -n --bind /sys $NEWROOT/sys + +else + echo -n Failed to download image, panicing in 5... + for i in 4 3 2 1 0; do + /bin/sleep 1 + echo -n $i... + done + echo + 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 + +" + /bin/dash + exit +fi +cd / + +if [ -z $STATEMNT ]; then + for lf in /tmp/dhclient.*.lease; do + netif=${lf#*.} + netif=${netif%.*} + cp $lf "$NEWROOT/var/lib/dhclient/dhclient-$netif.leases" + done + + if [ ! -z "$ifname" ]; then + MACX=${ifname#*:} + ETHX=${ifname%:$MACX*} + elif [ ! -z "$netdev" ]; then + ETHX=$netdev + MACX=`ip link show $netdev | grep ether | awk '{print $2}'` + elif [ ! -z "$BOOTIF" ]; then + MACX=$BOOTIF + #ETHX=`ifconfig |grep -i $BOOTIF | awk '{print $1}'` + ETHX=` ip -oneline link show |grep -i $BOOTIF|awk -F ':' '{print $2}'|grep -o "[^ ]\+\( \+[^ ]\+\)*"` + fi + + if [ ! -z "$MACX" ] && [ ! -z "$ETHX" ]; then + if [ ! -e $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX ]; then + touch $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + fi + echo "DEVICE=$ETHX" > $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + echo "BOOTPROTO=dhcp" >> $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + echo "HWADDR=$MACX" >> $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + echo "ONBOOT=yes" >> $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + fi +fi + +cp /etc/resolv.conf "$NEWROOT/etc/" + +if [ -d "$NEWROOT/etc/sysconfig" -a ! -e "$NEWROOT/etc/sysconfig/selinux" ]; then + echo "SELINUX=disabled" >> "$NEWROOT/etc/sysconfig/selinux" +fi + +# inject new exit_if_exists +echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$job"' > /initqueue/xcat.sh +# force udevsettle to break +> /initqueue/work diff --git a/xCAT-server/share/xcat/netboot/SL/genimage b/xCAT-server/share/xcat/netboot/SL/genimage deleted file mode 120000 index 1c50b1848..000000000 --- a/xCAT-server/share/xcat/netboot/SL/genimage +++ /dev/null @@ -1 +0,0 @@ -../rh/genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/SL/genimage b/xCAT-server/share/xcat/netboot/SL/genimage new file mode 100755 index 000000000..8c4ced961 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/SL/genimage @@ -0,0 +1,2081 @@ +#!/usr/bin/env perl + +# The possible files which getting from local OS that may affect he genimage cross distor level +# /proc/self/oom_adj + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $krpmver; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; +my $ignorekernelchk; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#check whether a dir is NFS mounted +sub isNFSdir{ + my $dir=shift; + my $out=qx(df -T -P $dir|tail -n 1|awk '{print \$2}'); + + if($out =~ /nfs/i) + { + return 1; + } + + return 0; +} + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; + } + + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; +} elsif ($arch eq 's390x') { + push @ndrivers, qw/qdio ccwgroup/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless ($onlyinitrd) { + @yumdirs=(); + + my @pkgdirs = split(",", $srcdir); + my $dir; + foreach $dir (@pkgdirs) { + find(\&isyumdir, <$dir/>); + if (!grep /$dir/, @yumdirs) { + print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n"; + } + } + + # Add the dir for kernel rpm to be installed + if ($kernelver) { + find(\&isyumdir, <$kerneldir/>); + if (!grep /$kerneldir/, @yumdirs) { + print "The repository for $kerneldir should be created before running the genimge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@yumdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + + mkpath "$rootimg_dir"; + my $yumconfig; + open($yumconfig,">","/tmp/genimage.$$.yum.conf"); + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + print $yumconfig "[main]\ndiskspacecheck=0\n\n"; + } + + my $repnum=0; + foreach $srcdir (@yumdirs) { + print $yumconfig "[$osver-$arch-$repnum]\nname=$osver-$arch-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n"; + $repnum += 1; + } + $repnum-=1; + close($yumconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my $yumcmd = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + + mkpath("$rootimg_dir/var/lib/yum"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + if ($p =~ /^kernel$/ && $kernelver) { + my $kernelname; + if ($krpmver) { + $kernelname = "kernel-".$krpmver; + } else { + $kernelname = "kernel-".$kernelver; + } + my $searchkern = $yumcmd . " list $kernelname -q"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*kernel[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + if ($kernelver =~ /$version/) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= " " . join(' ', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $yumcmd install $pkgnames\n"; + my $rc = system("$envlist $yumcmd install $pkgnames"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + my %repohash; + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $repohash{$pass}{$index} = 1; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + my $yumcmd_base = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + $yumcmd_base .= "--setopt=diskspacecheck=0 "; + } + + foreach (0..$repnum) { + $yumcmd_base .= "--enablerepo=$osver-$arch-$_ "; + } +# for (1..$index) { +# $yumcmd .= "--enablerepo=otherpkgs$_ "; +# } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + $yumcmd = $yumcmd_base; + foreach my $repo_index ( keys %{$repohash{$pass}} ) { + $yumcmd .= "--enablerepo=otherpkgs$repo_index "; + } + + system("$yumcmd clean all"); + + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + +# # mount /proc file system since several packages need it. +# print "mount /proc file system\nchroot $rootimg_dir /bin/mount -t proc proc /proc\n"; +# system("chroot $rootimg_dir /bin/mount -t proc proc /proc"); + + # install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + $yumcmd =~ s/ $/\n/; + + # debug + #print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $yumcmd\n"; + my $rc = system("$envlist $yumcmd"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + +# # umount /proc file system that just mounted +# print "umount /proc file system\nchroot $rootimg_dir /bin/umount /proc\n"; +# system("chroot $rootimg_dir /bin/umount /proc"); + + # 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) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} + +#get the rpm version, if the rpm version is different then the db verison may change. +my $mnrpmver = `rpm --version | awk '{print \$3}'`; +my $cnrpmver = `chroot $rootimg_dir rpm --version | awk '{print \$3}'`; +if ( $mnrpmver ne $cnrpmver ){ + #fine all db file witch should be rebuided + my $filelist = `file $rootimg_dir/var/lib/rpm/* | grep 'Berkeley DB' | awk -F : '{print \$1}'`; + + my @files = split '\n', $filelist; + + system("rm -rf $rootimg_dir/var/lib/rpm/__db*"); + foreach my $file ( @files ){ + my $filename = basename($file); + #dump the db file to a normal test file with the db_dump on the mn + system("db_dump $file > $rootimg_dir/tmp/$filename.dbtmp9"); + unlink("$rootimg_dir/var/lib/rpm/$filename"); + #chroot to the rootimage and run db_load + system(" chroot $rootimg_dir db_load -f /tmp/$filename.dbtmp9 /var/lib/rpm/$filename"); + } + system("rm -rf $rootimg_dir/tmp/*.dbtmp9"); + #rebuild rpm db file in rootimage for cn + system(" chroot $rootimg_dir rpm --rebuilddb"); +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +unlink "/tmp/genimage.$$.yum.conf"; +if ( (-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut") ) { + $dracutmode = 1; + # get dracut version + my $dracutver = `rpm --root $rootimg_dir -qi dracut | grep Version | awk -F' ' '{print \$3}'`; + chomp($dracutver); + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "033") { + $dracutdir = "dracut_033"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + + +#-- for centos, disable the internet repository +if( -e "$rootimg_dir/etc/yum.repos.d/CentOS-Base.repo" ) { + my $repo_content=`sed -e '/enabled/d' $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo | sed -e '/^gpgkey/i enabled=0'`; + system("echo '$repo_content' > $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo"); +} +# + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +#if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + if (-f "$rootimg_dir/etc/rc.sysinit") { + my $SYSINITFILE; + my $TMPSYSINITFILE; + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +#} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("stateless"); + mkinitrd_dracut("statelite"); +} else { + mkinitrd("statelite"); + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + + my $dracutmoduledir="$rootimg_dir/usr/share/dracut/modules.d/"; + if ( (! -d $dracutmoduledir) and (-d "$rootimg_dir/usr/lib/dracut/modules.d/")) + { + $dracutmoduledir="$rootimg_dir/usr/lib/dracut/modules.d/"; + } + + my $dracutmpath = $dracutmoduledir."97xcat/"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + # Add drivers to support local disk + push @ndrivers, "ext3"; + push @ndrivers, "ext4"; + #remove the duplicated drivers + my @fulldrivers; + foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } + } + @ndrivers = @fulldrivers; + + my $add_drivers = join(' ', @ndrivers); + print "Try to load drivers: $add_drivers to initrd.\n"; + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + cp("$fullpath/$dracutdir/xcat-premount.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-premount.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-premount.sh"); + + #update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + my $additional_options=undef; + if($rootlimit) + { + open(my $ETC_CMDLINE,">","$rootimg_dir/tmp/cmdline"); + print $ETC_CMDLINE qq{rootlimit=$rootlimit\n}; + close $ETC_CMDLINE; + $additional_options= qq{--include /tmp/cmdline /etc/cmdline}; + } + + # force the dracut run in non-hostonly mode for dracut higher than version 033 + if ($dracutver > "033") { + $additional_options .= " -N"; + } + system("chroot $rootimg_dir dracut $additional_options -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + + if($mode eq "statelite") { + push @ndrivers, "nfs.ko"; + + open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); + my @moddeps = <$moddeps>; + my @checkdeps = ("nfs.ko"); + 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"; + } + } + } + } + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox.anaconda mount -t proc /proc /proc\n"; + print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev on s390x +if ($arch eq "s390x") { + print $inifile < /etc/sysconfig/network + +echo "ONBOOT=yes" > /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "BOOTPROTO=dhcp" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "DEVICE=$prinic" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo 'OPTIONS="layer2=1"' >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "SUBCHANNELS=$subchn" >> /etc/sysconfig/network-scripts/ifcfg-$prinic + +# Turn on network devices +echo $subchn > /sys/bus/ccwgroup/drivers/qeth/group +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/layer2 +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/online +echo "alias $prinic qeth" >> /etc/modprobe.conf +echo `ifup $prinic` +sleep 4 +EOMS +} + + print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' + +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}'|sed -e s/^01-// -e s/-/:/g` + #BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + BOOTIF=\`ip -oneline link show |grep -i \$VALUE|awk -F ':' '{print \$2}'|grep -o \"[^ ]\+\( \+[^ ]\+\)*\"\` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 +echo network --device \$IFACE --bootproto dhcp >> /bin/netstart + +netstart \$IFACE +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + + + + + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ ! -z "\$NODENAME" ]; then + ME=\$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + close($inifile); + + #/tmp/updateflag: a script to feedback node provision status to xcatd + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod", "bin/bash", "usr/sbin/chroot", "sbin/mount.nfs", "usr/bin/rsync", "usr/bin/wc") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + push @filestoadd,"lib/libresolv.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + system("mkdir -p /tmp/xcatinitrd.$$/etc/sysconfig"); + system("cp -r $rootimg_dir/etc/sysconfig/* /tmp/xcatinitrd.$$/etc/sysconfig"); + system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + 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; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +sub using_systemd { + my $os = shift; + if ($os =~ /fedora(\d+)/) { + if ($1 >= 15) { + return 1; + } + }elsif ($os =~ /rhels(\d+)/) { + if ($1 >= 7) { + return 1; + } + } + + return 0; +} + + +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 (!&using_systemd($osver)) { + 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); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + + # gettyset is not found on s390x + if ($arch ne "s390x") { + if (!&using_systemd($osver)) { + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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 " if [ -x /sbin/initctl ]; then\n"; # Upstart style + # The syntax of next line is not correct, that means it does NOthing. (rh6 and higher) + # And it should NOT work for rh6 and higher, otherwise it will cauase multiple agetty for ttySx + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\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 " fi\n"; + print $cfgfile "done\n"; + + close($cfgfile); + + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/gettyset S60gettyset"); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd () +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + my $rc = system ("umount -f $dd_dir/mnt"); + if ($rc) { + print "umount the directory $dd_dir/mnt failed\n"; + exit 1; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT-server/share/xcat/netboot/centos/dracut b/xCAT-server/share/xcat/netboot/centos/dracut deleted file mode 120000 index 11bde8445..000000000 --- a/xCAT-server/share/xcat/netboot/centos/dracut +++ /dev/null @@ -1 +0,0 @@ -../rh/dracut \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/centos/genimage b/xCAT-server/share/xcat/netboot/centos/genimage deleted file mode 120000 index 1c50b1848..000000000 --- a/xCAT-server/share/xcat/netboot/centos/genimage +++ /dev/null @@ -1 +0,0 @@ -../rh/genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/centos/genimage b/xCAT-server/share/xcat/netboot/centos/genimage new file mode 100755 index 000000000..8c4ced961 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/centos/genimage @@ -0,0 +1,2081 @@ +#!/usr/bin/env perl + +# The possible files which getting from local OS that may affect he genimage cross distor level +# /proc/self/oom_adj + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $krpmver; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; +my $ignorekernelchk; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#check whether a dir is NFS mounted +sub isNFSdir{ + my $dir=shift; + my $out=qx(df -T -P $dir|tail -n 1|awk '{print \$2}'); + + if($out =~ /nfs/i) + { + return 1; + } + + return 0; +} + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; + } + + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; +} elsif ($arch eq 's390x') { + push @ndrivers, qw/qdio ccwgroup/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless ($onlyinitrd) { + @yumdirs=(); + + my @pkgdirs = split(",", $srcdir); + my $dir; + foreach $dir (@pkgdirs) { + find(\&isyumdir, <$dir/>); + if (!grep /$dir/, @yumdirs) { + print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n"; + } + } + + # Add the dir for kernel rpm to be installed + if ($kernelver) { + find(\&isyumdir, <$kerneldir/>); + if (!grep /$kerneldir/, @yumdirs) { + print "The repository for $kerneldir should be created before running the genimge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@yumdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + + mkpath "$rootimg_dir"; + my $yumconfig; + open($yumconfig,">","/tmp/genimage.$$.yum.conf"); + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + print $yumconfig "[main]\ndiskspacecheck=0\n\n"; + } + + my $repnum=0; + foreach $srcdir (@yumdirs) { + print $yumconfig "[$osver-$arch-$repnum]\nname=$osver-$arch-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n"; + $repnum += 1; + } + $repnum-=1; + close($yumconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my $yumcmd = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + + mkpath("$rootimg_dir/var/lib/yum"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + if ($p =~ /^kernel$/ && $kernelver) { + my $kernelname; + if ($krpmver) { + $kernelname = "kernel-".$krpmver; + } else { + $kernelname = "kernel-".$kernelver; + } + my $searchkern = $yumcmd . " list $kernelname -q"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*kernel[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + if ($kernelver =~ /$version/) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= " " . join(' ', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $yumcmd install $pkgnames\n"; + my $rc = system("$envlist $yumcmd install $pkgnames"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + my %repohash; + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $repohash{$pass}{$index} = 1; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + my $yumcmd_base = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + $yumcmd_base .= "--setopt=diskspacecheck=0 "; + } + + foreach (0..$repnum) { + $yumcmd_base .= "--enablerepo=$osver-$arch-$_ "; + } +# for (1..$index) { +# $yumcmd .= "--enablerepo=otherpkgs$_ "; +# } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + $yumcmd = $yumcmd_base; + foreach my $repo_index ( keys %{$repohash{$pass}} ) { + $yumcmd .= "--enablerepo=otherpkgs$repo_index "; + } + + system("$yumcmd clean all"); + + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + +# # mount /proc file system since several packages need it. +# print "mount /proc file system\nchroot $rootimg_dir /bin/mount -t proc proc /proc\n"; +# system("chroot $rootimg_dir /bin/mount -t proc proc /proc"); + + # install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + $yumcmd =~ s/ $/\n/; + + # debug + #print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $yumcmd\n"; + my $rc = system("$envlist $yumcmd"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + +# # umount /proc file system that just mounted +# print "umount /proc file system\nchroot $rootimg_dir /bin/umount /proc\n"; +# system("chroot $rootimg_dir /bin/umount /proc"); + + # 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) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} + +#get the rpm version, if the rpm version is different then the db verison may change. +my $mnrpmver = `rpm --version | awk '{print \$3}'`; +my $cnrpmver = `chroot $rootimg_dir rpm --version | awk '{print \$3}'`; +if ( $mnrpmver ne $cnrpmver ){ + #fine all db file witch should be rebuided + my $filelist = `file $rootimg_dir/var/lib/rpm/* | grep 'Berkeley DB' | awk -F : '{print \$1}'`; + + my @files = split '\n', $filelist; + + system("rm -rf $rootimg_dir/var/lib/rpm/__db*"); + foreach my $file ( @files ){ + my $filename = basename($file); + #dump the db file to a normal test file with the db_dump on the mn + system("db_dump $file > $rootimg_dir/tmp/$filename.dbtmp9"); + unlink("$rootimg_dir/var/lib/rpm/$filename"); + #chroot to the rootimage and run db_load + system(" chroot $rootimg_dir db_load -f /tmp/$filename.dbtmp9 /var/lib/rpm/$filename"); + } + system("rm -rf $rootimg_dir/tmp/*.dbtmp9"); + #rebuild rpm db file in rootimage for cn + system(" chroot $rootimg_dir rpm --rebuilddb"); +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +unlink "/tmp/genimage.$$.yum.conf"; +if ( (-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut") ) { + $dracutmode = 1; + # get dracut version + my $dracutver = `rpm --root $rootimg_dir -qi dracut | grep Version | awk -F' ' '{print \$3}'`; + chomp($dracutver); + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "033") { + $dracutdir = "dracut_033"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + + +#-- for centos, disable the internet repository +if( -e "$rootimg_dir/etc/yum.repos.d/CentOS-Base.repo" ) { + my $repo_content=`sed -e '/enabled/d' $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo | sed -e '/^gpgkey/i enabled=0'`; + system("echo '$repo_content' > $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo"); +} +# + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +#if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + if (-f "$rootimg_dir/etc/rc.sysinit") { + my $SYSINITFILE; + my $TMPSYSINITFILE; + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +#} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("stateless"); + mkinitrd_dracut("statelite"); +} else { + mkinitrd("statelite"); + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + + my $dracutmoduledir="$rootimg_dir/usr/share/dracut/modules.d/"; + if ( (! -d $dracutmoduledir) and (-d "$rootimg_dir/usr/lib/dracut/modules.d/")) + { + $dracutmoduledir="$rootimg_dir/usr/lib/dracut/modules.d/"; + } + + my $dracutmpath = $dracutmoduledir."97xcat/"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + # Add drivers to support local disk + push @ndrivers, "ext3"; + push @ndrivers, "ext4"; + #remove the duplicated drivers + my @fulldrivers; + foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } + } + @ndrivers = @fulldrivers; + + my $add_drivers = join(' ', @ndrivers); + print "Try to load drivers: $add_drivers to initrd.\n"; + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + cp("$fullpath/$dracutdir/xcat-premount.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-premount.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-premount.sh"); + + #update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + my $additional_options=undef; + if($rootlimit) + { + open(my $ETC_CMDLINE,">","$rootimg_dir/tmp/cmdline"); + print $ETC_CMDLINE qq{rootlimit=$rootlimit\n}; + close $ETC_CMDLINE; + $additional_options= qq{--include /tmp/cmdline /etc/cmdline}; + } + + # force the dracut run in non-hostonly mode for dracut higher than version 033 + if ($dracutver > "033") { + $additional_options .= " -N"; + } + system("chroot $rootimg_dir dracut $additional_options -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + + if($mode eq "statelite") { + push @ndrivers, "nfs.ko"; + + open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); + my @moddeps = <$moddeps>; + my @checkdeps = ("nfs.ko"); + 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"; + } + } + } + } + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox.anaconda mount -t proc /proc /proc\n"; + print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev on s390x +if ($arch eq "s390x") { + print $inifile < /etc/sysconfig/network + +echo "ONBOOT=yes" > /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "BOOTPROTO=dhcp" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "DEVICE=$prinic" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo 'OPTIONS="layer2=1"' >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "SUBCHANNELS=$subchn" >> /etc/sysconfig/network-scripts/ifcfg-$prinic + +# Turn on network devices +echo $subchn > /sys/bus/ccwgroup/drivers/qeth/group +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/layer2 +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/online +echo "alias $prinic qeth" >> /etc/modprobe.conf +echo `ifup $prinic` +sleep 4 +EOMS +} + + print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' + +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}'|sed -e s/^01-// -e s/-/:/g` + #BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + BOOTIF=\`ip -oneline link show |grep -i \$VALUE|awk -F ':' '{print \$2}'|grep -o \"[^ ]\+\( \+[^ ]\+\)*\"\` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 +echo network --device \$IFACE --bootproto dhcp >> /bin/netstart + +netstart \$IFACE +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + + + + + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ ! -z "\$NODENAME" ]; then + ME=\$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + close($inifile); + + #/tmp/updateflag: a script to feedback node provision status to xcatd + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod", "bin/bash", "usr/sbin/chroot", "sbin/mount.nfs", "usr/bin/rsync", "usr/bin/wc") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + push @filestoadd,"lib/libresolv.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + system("mkdir -p /tmp/xcatinitrd.$$/etc/sysconfig"); + system("cp -r $rootimg_dir/etc/sysconfig/* /tmp/xcatinitrd.$$/etc/sysconfig"); + system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + 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; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +sub using_systemd { + my $os = shift; + if ($os =~ /fedora(\d+)/) { + if ($1 >= 15) { + return 1; + } + }elsif ($os =~ /rhels(\d+)/) { + if ($1 >= 7) { + return 1; + } + } + + return 0; +} + + +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 (!&using_systemd($osver)) { + 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); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + + # gettyset is not found on s390x + if ($arch ne "s390x") { + if (!&using_systemd($osver)) { + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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 " if [ -x /sbin/initctl ]; then\n"; # Upstart style + # The syntax of next line is not correct, that means it does NOthing. (rh6 and higher) + # And it should NOT work for rh6 and higher, otherwise it will cauase multiple agetty for ttySx + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\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 " fi\n"; + print $cfgfile "done\n"; + + close($cfgfile); + + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/gettyset S60gettyset"); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd () +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + my $rc = system ("umount -f $dd_dir/mnt"); + if ($rc) { + print "umount the directory $dd_dir/mnt failed\n"; + exit 1; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT-server/share/xcat/netboot/centos/geninitrd b/xCAT-server/share/xcat/netboot/centos/geninitrd deleted file mode 120000 index 2271c3f0f..000000000 --- a/xCAT-server/share/xcat/netboot/centos/geninitrd +++ /dev/null @@ -1 +0,0 @@ -genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/centos/geninitrd b/xCAT-server/share/xcat/netboot/centos/geninitrd new file mode 100755 index 000000000..8c4ced961 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/centos/geninitrd @@ -0,0 +1,2081 @@ +#!/usr/bin/env perl + +# The possible files which getting from local OS that may affect he genimage cross distor level +# /proc/self/oom_adj + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $krpmver; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; +my $ignorekernelchk; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#check whether a dir is NFS mounted +sub isNFSdir{ + my $dir=shift; + my $out=qx(df -T -P $dir|tail -n 1|awk '{print \$2}'); + + if($out =~ /nfs/i) + { + return 1; + } + + return 0; +} + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; + } + + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; +} elsif ($arch eq 's390x') { + push @ndrivers, qw/qdio ccwgroup/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless ($onlyinitrd) { + @yumdirs=(); + + my @pkgdirs = split(",", $srcdir); + my $dir; + foreach $dir (@pkgdirs) { + find(\&isyumdir, <$dir/>); + if (!grep /$dir/, @yumdirs) { + print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n"; + } + } + + # Add the dir for kernel rpm to be installed + if ($kernelver) { + find(\&isyumdir, <$kerneldir/>); + if (!grep /$kerneldir/, @yumdirs) { + print "The repository for $kerneldir should be created before running the genimge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@yumdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + + mkpath "$rootimg_dir"; + my $yumconfig; + open($yumconfig,">","/tmp/genimage.$$.yum.conf"); + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + print $yumconfig "[main]\ndiskspacecheck=0\n\n"; + } + + my $repnum=0; + foreach $srcdir (@yumdirs) { + print $yumconfig "[$osver-$arch-$repnum]\nname=$osver-$arch-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n"; + $repnum += 1; + } + $repnum-=1; + close($yumconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my $yumcmd = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + + mkpath("$rootimg_dir/var/lib/yum"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + if ($p =~ /^kernel$/ && $kernelver) { + my $kernelname; + if ($krpmver) { + $kernelname = "kernel-".$krpmver; + } else { + $kernelname = "kernel-".$kernelver; + } + my $searchkern = $yumcmd . " list $kernelname -q"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*kernel[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + if ($kernelver =~ /$version/) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= " " . join(' ', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $yumcmd install $pkgnames\n"; + my $rc = system("$envlist $yumcmd install $pkgnames"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + my %repohash; + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $repohash{$pass}{$index} = 1; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + my $yumcmd_base = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + $yumcmd_base .= "--setopt=diskspacecheck=0 "; + } + + foreach (0..$repnum) { + $yumcmd_base .= "--enablerepo=$osver-$arch-$_ "; + } +# for (1..$index) { +# $yumcmd .= "--enablerepo=otherpkgs$_ "; +# } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + $yumcmd = $yumcmd_base; + foreach my $repo_index ( keys %{$repohash{$pass}} ) { + $yumcmd .= "--enablerepo=otherpkgs$repo_index "; + } + + system("$yumcmd clean all"); + + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + +# # mount /proc file system since several packages need it. +# print "mount /proc file system\nchroot $rootimg_dir /bin/mount -t proc proc /proc\n"; +# system("chroot $rootimg_dir /bin/mount -t proc proc /proc"); + + # install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + $yumcmd =~ s/ $/\n/; + + # debug + #print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $yumcmd\n"; + my $rc = system("$envlist $yumcmd"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + +# # umount /proc file system that just mounted +# print "umount /proc file system\nchroot $rootimg_dir /bin/umount /proc\n"; +# system("chroot $rootimg_dir /bin/umount /proc"); + + # 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) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} + +#get the rpm version, if the rpm version is different then the db verison may change. +my $mnrpmver = `rpm --version | awk '{print \$3}'`; +my $cnrpmver = `chroot $rootimg_dir rpm --version | awk '{print \$3}'`; +if ( $mnrpmver ne $cnrpmver ){ + #fine all db file witch should be rebuided + my $filelist = `file $rootimg_dir/var/lib/rpm/* | grep 'Berkeley DB' | awk -F : '{print \$1}'`; + + my @files = split '\n', $filelist; + + system("rm -rf $rootimg_dir/var/lib/rpm/__db*"); + foreach my $file ( @files ){ + my $filename = basename($file); + #dump the db file to a normal test file with the db_dump on the mn + system("db_dump $file > $rootimg_dir/tmp/$filename.dbtmp9"); + unlink("$rootimg_dir/var/lib/rpm/$filename"); + #chroot to the rootimage and run db_load + system(" chroot $rootimg_dir db_load -f /tmp/$filename.dbtmp9 /var/lib/rpm/$filename"); + } + system("rm -rf $rootimg_dir/tmp/*.dbtmp9"); + #rebuild rpm db file in rootimage for cn + system(" chroot $rootimg_dir rpm --rebuilddb"); +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +unlink "/tmp/genimage.$$.yum.conf"; +if ( (-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut") ) { + $dracutmode = 1; + # get dracut version + my $dracutver = `rpm --root $rootimg_dir -qi dracut | grep Version | awk -F' ' '{print \$3}'`; + chomp($dracutver); + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "033") { + $dracutdir = "dracut_033"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + + +#-- for centos, disable the internet repository +if( -e "$rootimg_dir/etc/yum.repos.d/CentOS-Base.repo" ) { + my $repo_content=`sed -e '/enabled/d' $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo | sed -e '/^gpgkey/i enabled=0'`; + system("echo '$repo_content' > $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo"); +} +# + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +#if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + if (-f "$rootimg_dir/etc/rc.sysinit") { + my $SYSINITFILE; + my $TMPSYSINITFILE; + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +#} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("stateless"); + mkinitrd_dracut("statelite"); +} else { + mkinitrd("statelite"); + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + + my $dracutmoduledir="$rootimg_dir/usr/share/dracut/modules.d/"; + if ( (! -d $dracutmoduledir) and (-d "$rootimg_dir/usr/lib/dracut/modules.d/")) + { + $dracutmoduledir="$rootimg_dir/usr/lib/dracut/modules.d/"; + } + + my $dracutmpath = $dracutmoduledir."97xcat/"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + # Add drivers to support local disk + push @ndrivers, "ext3"; + push @ndrivers, "ext4"; + #remove the duplicated drivers + my @fulldrivers; + foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } + } + @ndrivers = @fulldrivers; + + my $add_drivers = join(' ', @ndrivers); + print "Try to load drivers: $add_drivers to initrd.\n"; + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + cp("$fullpath/$dracutdir/xcat-premount.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-premount.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-premount.sh"); + + #update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + my $additional_options=undef; + if($rootlimit) + { + open(my $ETC_CMDLINE,">","$rootimg_dir/tmp/cmdline"); + print $ETC_CMDLINE qq{rootlimit=$rootlimit\n}; + close $ETC_CMDLINE; + $additional_options= qq{--include /tmp/cmdline /etc/cmdline}; + } + + # force the dracut run in non-hostonly mode for dracut higher than version 033 + if ($dracutver > "033") { + $additional_options .= " -N"; + } + system("chroot $rootimg_dir dracut $additional_options -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + + if($mode eq "statelite") { + push @ndrivers, "nfs.ko"; + + open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); + my @moddeps = <$moddeps>; + my @checkdeps = ("nfs.ko"); + 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"; + } + } + } + } + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox.anaconda mount -t proc /proc /proc\n"; + print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev on s390x +if ($arch eq "s390x") { + print $inifile < /etc/sysconfig/network + +echo "ONBOOT=yes" > /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "BOOTPROTO=dhcp" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "DEVICE=$prinic" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo 'OPTIONS="layer2=1"' >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "SUBCHANNELS=$subchn" >> /etc/sysconfig/network-scripts/ifcfg-$prinic + +# Turn on network devices +echo $subchn > /sys/bus/ccwgroup/drivers/qeth/group +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/layer2 +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/online +echo "alias $prinic qeth" >> /etc/modprobe.conf +echo `ifup $prinic` +sleep 4 +EOMS +} + + print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' + +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}'|sed -e s/^01-// -e s/-/:/g` + #BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + BOOTIF=\`ip -oneline link show |grep -i \$VALUE|awk -F ':' '{print \$2}'|grep -o \"[^ ]\+\( \+[^ ]\+\)*\"\` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 +echo network --device \$IFACE --bootproto dhcp >> /bin/netstart + +netstart \$IFACE +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + + + + + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ ! -z "\$NODENAME" ]; then + ME=\$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + close($inifile); + + #/tmp/updateflag: a script to feedback node provision status to xcatd + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod", "bin/bash", "usr/sbin/chroot", "sbin/mount.nfs", "usr/bin/rsync", "usr/bin/wc") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + push @filestoadd,"lib/libresolv.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + system("mkdir -p /tmp/xcatinitrd.$$/etc/sysconfig"); + system("cp -r $rootimg_dir/etc/sysconfig/* /tmp/xcatinitrd.$$/etc/sysconfig"); + system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + 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; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +sub using_systemd { + my $os = shift; + if ($os =~ /fedora(\d+)/) { + if ($1 >= 15) { + return 1; + } + }elsif ($os =~ /rhels(\d+)/) { + if ($1 >= 7) { + return 1; + } + } + + return 0; +} + + +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 (!&using_systemd($osver)) { + 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); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + + # gettyset is not found on s390x + if ($arch ne "s390x") { + if (!&using_systemd($osver)) { + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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 " if [ -x /sbin/initctl ]; then\n"; # Upstart style + # The syntax of next line is not correct, that means it does NOthing. (rh6 and higher) + # And it should NOT work for rh6 and higher, otherwise it will cauase multiple agetty for ttySx + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\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 " fi\n"; + print $cfgfile "done\n"; + + close($cfgfile); + + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/gettyset S60gettyset"); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd () +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + my $rc = system ("umount -f $dd_dir/mnt"); + if ($rc) { + print "umount the directory $dd_dir/mnt failed\n"; + exit 1; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT-server/share/xcat/netboot/centos/kvm.exlist b/xCAT-server/share/xcat/netboot/centos/kvm.exlist deleted file mode 120000 index c86878d02..000000000 --- a/xCAT-server/share/xcat/netboot/centos/kvm.exlist +++ /dev/null @@ -1 +0,0 @@ -../rh/kvm.exlist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/centos/kvm.exlist b/xCAT-server/share/xcat/netboot/centos/kvm.exlist new file mode 100644 index 000000000..3c2a4d9cf --- /dev/null +++ b/xCAT-server/share/xcat/netboot/centos/kvm.exlist @@ -0,0 +1,24 @@ +./usr/share/man/* +./usr/share/locale/* +./usr/share/i18n* +./var/cache/yum* +./usr/share/doc* +./usr/share/gnome* +./usr/share/zoneinfo* +./usr/share/cracklib* +./usr/share/info* +./usr/share/omf* +./usr/lib/locale* +./usr/lib64/dri* +./usr/share/backgrounds* +./lib/modules/*/kernel/drivers/net/pcmcia* +./lib/modules/*/kernel/drivers/net/tokenring* +./lib/modules/*/kernel/drivers/net/wireless* +./lib/modules/*/kernel/drivers/net/media* +./lib/modules/*/kernel/drivers/media* +./lib/modules/*/kernel/drivers/video* +./lib/modules/*/kernel/drivers/gpu* +./lib/modules/*/kernel/drivers/isdn* +./lib/modules/*/kernel/drivers/hwmon* +./lib/modules/*/kernel/sound* +./boot* diff --git a/xCAT-server/share/xcat/netboot/centos/kvm.pkglist b/xCAT-server/share/xcat/netboot/centos/kvm.pkglist deleted file mode 120000 index 010315c63..000000000 --- a/xCAT-server/share/xcat/netboot/centos/kvm.pkglist +++ /dev/null @@ -1 +0,0 @@ -../rh/kvm.rhels5.4.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/centos/kvm.pkglist b/xCAT-server/share/xcat/netboot/centos/kvm.pkglist new file mode 100644 index 000000000..3de9dd585 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/centos/kvm.pkglist @@ -0,0 +1,25 @@ +bash +postfix +nfs-utils +openssl +dhclient +kernel +openssh-server +openssh-clients +busybox-anaconda +wget +vim-minimal +ntp +sysklogd +rpm +rsync +bridge-utils +dnsmasq +iscsi-initiator-utils +kvm +libvirt.x86_64 +perl-Sys-Virt +python-urlgrabber.noarch +python-virtinst +screen +xnba-kvm diff --git a/xCAT-server/share/xcat/netboot/centos/xen.exlist b/xCAT-server/share/xcat/netboot/centos/xen.exlist deleted file mode 120000 index f968576ce..000000000 --- a/xCAT-server/share/xcat/netboot/centos/xen.exlist +++ /dev/null @@ -1 +0,0 @@ -../rh/xen.exlist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/centos/xen.exlist b/xCAT-server/share/xcat/netboot/centos/xen.exlist new file mode 100644 index 000000000..7241cb38b --- /dev/null +++ b/xCAT-server/share/xcat/netboot/centos/xen.exlist @@ -0,0 +1,13 @@ +./usr/share/man/* +./usr/share/locale/* +./usr/share/i18n* +./var/cache/yum* +./usr/share/doc* +./usr/share/gnome* +./usr/share/zoneinfo* +./usr/share/cracklib* +./usr/share/info* +./usr/share/omf* +./usr/lib/locale* +./usr/lib/perl5* +./boot* diff --git a/xCAT-server/share/xcat/netboot/centos/xen.pkglist b/xCAT-server/share/xcat/netboot/centos/xen.pkglist deleted file mode 120000 index b8f195934..000000000 --- a/xCAT-server/share/xcat/netboot/centos/xen.pkglist +++ /dev/null @@ -1 +0,0 @@ -../rh/xen.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/centos/xen.pkglist b/xCAT-server/share/xcat/netboot/centos/xen.pkglist new file mode 100644 index 000000000..e39f5b37e --- /dev/null +++ b/xCAT-server/share/xcat/netboot/centos/xen.pkglist @@ -0,0 +1,20 @@ +bash +postfix +nfs-utils +openssl +dhclient +kernel-xen +openssh-server +openssh-clients +busybox-anaconda +wget +vim-minimal +ntp +sysklogd +rpm +rsync +bridge-utils +iscsi-initiator-utils +xen +libvirt.x86_64 +screen diff --git a/xCAT-server/share/xcat/netboot/fedora/compute.fedora12.pkglist b/xCAT-server/share/xcat/netboot/fedora/compute.fedora12.pkglist deleted file mode 120000 index 96fcc8214..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/compute.fedora12.pkglist +++ /dev/null @@ -1 +0,0 @@ -compute.fedora13.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/compute.fedora12.pkglist b/xCAT-server/share/xcat/netboot/fedora/compute.fedora12.pkglist new file mode 100644 index 000000000..927dd6e36 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/compute.fedora12.pkglist @@ -0,0 +1,14 @@ +bash +dracut-network +nfs-utils +openssl +dhclient +kernel +openssh-server +openssh-clients +wget +vim-minimal +ntp +rpm +rsync +rsyslog diff --git a/xCAT-server/share/xcat/netboot/fedora/compute.fedora15.pkglist b/xCAT-server/share/xcat/netboot/fedora/compute.fedora15.pkglist deleted file mode 120000 index 7101667e8..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/compute.fedora15.pkglist +++ /dev/null @@ -1 +0,0 @@ -compute.fedora14.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/compute.fedora15.pkglist b/xCAT-server/share/xcat/netboot/fedora/compute.fedora15.pkglist new file mode 100644 index 000000000..927dd6e36 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/compute.fedora15.pkglist @@ -0,0 +1,14 @@ +bash +dracut-network +nfs-utils +openssl +dhclient +kernel +openssh-server +openssh-clients +wget +vim-minimal +ntp +rpm +rsync +rsyslog diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/check b/xCAT-server/share/xcat/netboot/fedora/dracut/check deleted file mode 120000 index 87ffb9d77..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/check +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/check \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/check b/xCAT-server/share/xcat/netboot/fedora/dracut/check new file mode 100755 index 000000000..d7cc89ce0 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/check @@ -0,0 +1,3 @@ +#!/bin/sh +[ "$1" = "-d" ] && echo network +exit 0 diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/install.netboot b/xCAT-server/share/xcat/netboot/fedora/dracut/install.netboot deleted file mode 120000 index 642f46713..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/install.netboot +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/install.netboot \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/install.netboot b/xCAT-server/share/xcat/netboot/fedora/dracut/install.netboot new file mode 100755 index 000000000..d9fe9c714 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/install.netboot @@ -0,0 +1,10 @@ +#!/bin/sh +echo $drivers +dracut_install wget cpio gzip dash modprobe touch echo cut wc +dracut_install -o ctorrent +dracut_install grep ifconfig hostname awk egrep grep dirname expr +dracut_install mount.nfs +dracut_install parted mke2fs bc mkswap swapon chmod +inst "$moddir/xcat-updateflag" "/tmp/updateflag" +inst "$moddir/xcatroot" "/sbin/xcatroot" +inst_hook cmdline 10 "$moddir/xcat-cmdline.sh" diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/install.statelite b/xCAT-server/share/xcat/netboot/fedora/dracut/install.statelite deleted file mode 120000 index a29fbcca1..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/install.statelite +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/install.statelite \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/install.statelite b/xCAT-server/share/xcat/netboot/fedora/dracut/install.statelite new file mode 100755 index 000000000..7c494d84c --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/install.statelite @@ -0,0 +1,9 @@ +#!/bin/sh +echo $drivers +dracut_install wget cpio gzip dash modprobe wc touch echo cut +dracut_install -o ctorrent +dracut_install grep ifconfig hostname awk egrep grep dirname expr +dracut_install parted mke2fs bc mkswap swapon chmod +inst "$moddir/xcat-updateflag" "/tmp/updateflag" +inst_hook pre-mount 5 "$moddir/xcat-premount.sh" +inst_hook pre-pivot 5 "$moddir/xcat-prepivot.sh" diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/installkernel b/xCAT-server/share/xcat/netboot/fedora/dracut/installkernel deleted file mode 120000 index 65990228e..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/installkernel +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/installkernel \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/installkernel b/xCAT-server/share/xcat/netboot/fedora/dracut/installkernel new file mode 100755 index 000000000..7902ce5f7 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/installkernel @@ -0,0 +1,2 @@ +#!/bin/bash +instmods nfs sunrpc diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-cmdline.sh b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-cmdline.sh deleted file mode 120000 index 76c6651f6..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-cmdline.sh +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-cmdline.sh \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-cmdline.sh b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-cmdline.sh new file mode 100644 index 000000000..d445cf585 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-cmdline.sh @@ -0,0 +1,4 @@ +root=1 +rootok=1 +netroot=xcat +echo '[ -e $NEWROOT/proc ]' > /initqueue-finished/xcatroot.sh diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-premount.sh b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-premount.sh deleted file mode 120000 index 862e21b2e..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-premount.sh +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-premount.sh \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-premount.sh b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-premount.sh new file mode 100644 index 000000000..40c1dbbe5 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-premount.sh @@ -0,0 +1,18 @@ +#!/bin/sh +#script to update nodelist.nodestatus during provision + +MASTER=`echo $XCAT |awk -F: '{print $1}'` + +getarg nonodestatus +NODESTATUS=$? + +XCATIPORT="$(getarg XCATIPORT=)" +if [ $? -ne 0 ]; then +XCATIPORT="3002" +fi + + + +if [ $NODESTATUS -ne 0 ];then +/tmp/updateflag $MASTER $XCATIPORT "installstatus netbooting" +fi diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-prepivot.sh b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-prepivot.sh deleted file mode 120000 index d2b623c6c..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-prepivot.sh +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-prepivot.sh \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-prepivot.sh b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-prepivot.sh new file mode 100755 index 000000000..73498a91e --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-prepivot.sh @@ -0,0 +1,126 @@ +#!/bin/sh +NEWROOT=/sysroot +SERVER=${SERVER%%/*} +SERVER=${SERVER%:} +RWDIR=.statelite +if [ ! -z $STATEMNT ]; then #btw, uri style might have left future options other than nfs open, will u se // to detect uri in the future I guess + SNAPSHOTSERVER=${STATEMNT%:*} + SNAPSHOTROOT=${STATEMNT#*/} + #echo $SNAPSHOTROOT + #echo $SNAPSHOTSERVER + # may be that there is not server and just a directory. + if [ -z $SNAPSHOTROOT ]; then + SNAPSHOTROOT=$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi +fi + +echo Setting up Statelite +mkdir -p $NEWROOT + +# now we need to mount the rest of the system. This is the read/write portions +# echo Mounting snapshot directories + +MAXTRIES=7 +ITER=0 +if [ ! -e "$NEWROOT/$RWDIR" ]; then + echo "" + echo "This NFS root directory doesn't have a /$RWDIR directory for me to mount a rw filesystem. You'd better create it... " + echo "" + /bin/sh +fi + +if [ ! -e "$NEWROOT/etc/init.d/statelite" ]; then + echo "" + echo "$NEWROOT/etc/init.d/statelite doesn't exist. Perhaps you didn't create this image with th e -m statelite mode" + echo "" + /bin/sh +fi + +mount -t tmpfs rw $NEWROOT/$RWDIR +mkdir -p $NEWROOT/$RWDIR/tmpfs +ME=`hostname` +if [ ! -z $NODE ]; then + ME=$NODE +fi + +# mount the SNAPSHOT directory here for persistent use. +if [ ! -z $SNAPSHOTSERVER ]; then + mkdir -p $NEWROOT/$RWDIR/persistent + MAXTRIES=5 + ITER=0 + if [ -z $MNTOPTS ]; then + MNT_OPTIONS="nolock,rsize=32768,tcp,nfsvers=3,timeo=14" + else + MNT_OPTIONS=$MNTOPTS + fi + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are 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." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + + # create directory which is named after my node name + mkdir -p $NEWROOT/$RWDIR/persistent/$ME + ITER=0 + # umount current persistent mount + while ! umount -l $NEWROOT/$RWDIR/persistent; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Cannot umount $NEWROOT/$RWDIR/persistent." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + + # mount persistent to server:/rootpath/nodename + ITER=0 + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Possible problems: cannot mount to $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done +fi + +# TODO: handle the dhclient/resolv.conf/ntp, etc +echo "Get to enable localdisk" +$NEWROOT/etc/init.d/localdisk +$NEWROOT/etc/init.d/statelite +READONLY=yes +export READONLY +fastboot=yes +export fastboot +keep_old_ip=yes +export keep_old_ip +mount -n --bind /dev $NEWROOT/dev +mount -n --bind /proc $NEWROOT/proc +mount -n --bind /sys $NEWROOT/sys + +if [ -d "$NEWROOT/etc/sysconfig" -a ! -e "$NEWROOT/etc/sysconfig/selinux" ]; then + echo "SELINUX=disabled" >> "$NEWROOT/etc/sysconfig/selinux" +fi + +# inject new exit_if_exists +echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$job"' > /initqueue/xcat.sh +# force udevsettle to break +> /initqueue/work diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-updateflag b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-updateflag deleted file mode 120000 index ba998cfb2..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-updateflag +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-updateflag \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-updateflag b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-updateflag new file mode 100755 index 000000000..2f9ac3165 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/xcat-updateflag @@ -0,0 +1,24 @@ +#!/bin/awk -f +#script to feedback the node provision status to xcatd +BEGIN { + + xcatdhost = ARGV[1] + xcatiport = ARGV[2] + + + ns = "/inet/tcp/0/" xcatdhost "/" xcatiport + print "xCAT_xcatd" |& ns + + while(1) { + ns |& getline + + if($0 == "ready") + print ARGV[3] |& ns + if($0 == "done") + break + } + + close(ns) + + exit 0 +} diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcatroot b/xCAT-server/share/xcat/netboot/fedora/dracut/xcatroot deleted file mode 120000 index babd2fb9d..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut/xcatroot +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcatroot \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut/xcatroot b/xCAT-server/share/xcat/netboot/fedora/dracut/xcatroot new file mode 100755 index 000000000..e18f532a5 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut/xcatroot @@ -0,0 +1,263 @@ +#!/bin/sh +NEWROOT=$3 +RWDIR=.statelite +XCATMASTER=$XCAT + +. /lib/dracut-lib.sh +rootlimit="$(getarg rootlimit=)" + + +getarg nonodestatus +NODESTATUS=$? + +MASTER=`echo $XCATMASTER |awk -F: '{print $1}'` +XCATIPORT="$(getarg XCATIPORT=)" +if [ $? -ne 0 ]; then +XCATIPORT="3002" +fi + + +if [ $NODESTATUS -ne 0 ];then +/tmp/updateflag $MASTER $XCATIPORT "installstatus netbooting" +fi + +if [ ! -z "$imgurl" ]; then + if [ xhttp = x${imgurl%%:*} ]; then + NFS=0 + FILENAME=${imgurl##*/} + while [ ! -r "$FILENAME" ]; do + echo Getting $imgurl... + if ! wget $imgurl; then + rm -f $FILENAME + sleep 27 + fi + done + elif [ xnfs = x${imgurl%%:*} ]; then + NFS=1 + SERVER=${imgurl#nfs:} + SERVER=${SERVER#/} + SERVER=${SERVER#/} + ROOTDIR=$SERVER + SERVER=${SERVER%%/*} + SERVER=${SERVER%:} + ROOTDIR=/${ROOTDIR#*/} + fi +fi +#echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +if [ -r /*.metainfo ]; then + ctorrent /*.metainfo -e 0 +fi +if [ -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 $NEWROOT + mkdir -p $NEWROOT/ro + mkdir -p $NEWROOT/rw + mount --move /ro $NEWROOT/ro + mount --move /rw $NEWROOT/rw +elif [ -r /rootimg.gz ]; then + echo Setting up RAM-root tmpfs. + if [ -z $rootlimit ];then + mount -t tmpfs -o mode=755 rootfs $NEWROOT + else + mount -t tmpfs -o mode=755,size=$rootlimit rootfs $NEWROOT + fi + + cd $NEWROOT + echo -n "Extracting root filesystem:" + if [ -x /bin/cpio ]; then + gzip -cd /rootimg.gz |/bin/cpio -idum + else + gzip -cd /rootimg.gz |cpio -idum + fi + $NEWROOT/etc/init.d/localdisk + echo Done +elif [ -r /rootimg-statelite.gz ]; then + echo Setting up RAM-root tmpfs for statelite mode. + + if [ -z $rootlimit];then + mount -t tmpfs -o mode=755 rootfs $NEWROOT + else + mount -t tmpfs -o mode=755,size=$rootlimit rootfs $NEWROOT + fi + + cd $NEWROOT + echo -n "Extracting root filesystem:" + if [ -x /bin/cpio ]; then + gzip -cd /rootimg-statelite.gz |/bin/cpio -idum + else + gzip -cd /rootimg-statelite.gz |cpio -idum + fi + echo Done + # then, the statelite staffs will be processed + echo Setting up Statelite + modprobe nfs + MAXTRIES=7 + ITER=0 + if [ ! -e "$NEWROOT/$RWDIR" ]; then + echo "" + echo "The /$RWDIR directory doesn't exist in the rootimg... " + echo "" + /bin/sh + fi + + if [ ! -e "$NEWROOT/etc/init.d/statelite" ]; then + echo "" + echo "$NEWROOT/etc/init.d/statelite doesn't exist... " + echo "" + /bin/sh + fi + + mount -t tmpfs rw $NEWROOT/$RWDIR + mkdir -p $NEWROOT/$RWDIR/tmpfs + ME=`hostname` + if [ ! -z $NODE ]; then + ME=$NODE + fi + + + # mount the SNAPSHOT directory here for persistent use. + if [ ! -z $STATEMNT ]; then + SNAPSHOTSERVER=${STATEMNT%:*} + SNAPSHOTROOT=${STATEMNT#*/} + if [ -z $SNAPSHOTROOT ]; then + SNAPSHOTROOT=$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + + if [ ! -z $SNAPSHOTSERVER ]; then + mkdir -p $NEWROOT/$RWDIR/persistent + MAXTRIES=5 + ITER=0 + if [ -z $MNTOPTS ]; then + MNT_OPTIONS="nolock,rsize=32768,tcp,nfsvers=3,timeo=14" + else + MNT_OPTIONS=$MNTOPTS + fi + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "You are 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." + /bin/sh + exit + fi + RS=$(( $RANDOM % 20 )) + echo "Trying again in $RS seconds ..." + sleep $RS + done + + # create directory which is named after my node name + mkdir -p $NEWROOT/$RWDIR/persistent/$ME + ITER=0 + # umount current persistent mount + while ! umount -l $NEWROOT/$RWDIR/persistent; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Cannot umount $NEWROOT/$RWDIR/persistent." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + + # mount persistent to server:/rootpath/nodename + ITER=0 + while ! mount $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME $NEWROOT/$RWDIR/persistent -o $MNT_OPTIONS; do + ITER=$(( ITER + 1 )) + if [ "$ITER" == "$MAXTRIES" ]; then + echo "Your are dead, rpower $ME boot to play again." + echo "Possible problems: cannot mount to $SNAPSHOTSERVER:/$SNAPSHOTROOT/$ME." + /bin/sh + exit + fi + RS= $(( $RANDOM % 20 )) + echo "Trying again in $RS seconds..." + sleep $RS + done + fi + + $NEWROOT/etc/init.d/localdisk + $NEWROOT/etc/init.d/statelite + fastboot=yes + export fastboot + keep_old_ip=yes + export keep_old_ip + + mount -n --bind /dev $NEWROOT/dev + mount -n --bind /proc $NEWROOT/proc + mount -n --bind /sys $NEWROOT/sys + +else + echo -n Failed to download image, panicing in 5... + for i in 4 3 2 1 0; do + /bin/sleep 1 + echo -n $i... + done + echo + 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 + +" + /bin/dash + exit +fi +cd / + +if [ -z $STATEMNT ]; then + for lf in /tmp/dhclient.*.lease; do + netif=${lf#*.} + netif=${netif%.*} + cp $lf "$NEWROOT/var/lib/dhclient/dhclient-$netif.leases" + done + + if [ ! -z "$ifname" ]; then + MACX=${ifname#*:} + ETHX=${ifname%:$MACX*} + elif [ ! -z "$netdev" ]; then + ETHX=$netdev + MACX=`ip link show $netdev | grep ether | awk '{print $2}'` + elif [ ! -z "$BOOTIF" ]; then + MACX=$BOOTIF + #ETHX=`ifconfig |grep -i $BOOTIF | awk '{print $1}'` + ETHX=` ip -oneline link show |grep -i $BOOTIF|awk -F ':' '{print $2}'|grep -o "[^ ]\+\( \+[^ ]\+\)*"` + fi + + if [ ! -z "$MACX" ] && [ ! -z "$ETHX" ]; then + if [ ! -e $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX ]; then + touch $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + fi + echo "DEVICE=$ETHX" > $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + echo "BOOTPROTO=dhcp" >> $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + echo "HWADDR=$MACX" >> $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + echo "ONBOOT=yes" >> $NEWROOT/etc/sysconfig/network-scripts/ifcfg-$ETHX + fi +fi + +cp /etc/resolv.conf "$NEWROOT/etc/" + +if [ -d "$NEWROOT/etc/sysconfig" -a ! -e "$NEWROOT/etc/sysconfig/selinux" ]; then + echo "SELINUX=disabled" >> "$NEWROOT/etc/sysconfig/selinux" +fi + +# inject new exit_if_exists +echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm "$job"' > /initqueue/xcat.sh +# force udevsettle to break +> /initqueue/work diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/check b/xCAT-server/share/xcat/netboot/fedora/dracut_009/check deleted file mode 120000 index 87ffb9d77..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut_009/check +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/check \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/check b/xCAT-server/share/xcat/netboot/fedora/dracut_009/check new file mode 100755 index 000000000..d7cc89ce0 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut_009/check @@ -0,0 +1,3 @@ +#!/bin/sh +[ "$1" = "-d" ] && echo network +exit 0 diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.netboot b/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.netboot deleted file mode 120000 index 642f46713..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.netboot +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/install.netboot \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.netboot b/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.netboot new file mode 100755 index 000000000..d9fe9c714 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.netboot @@ -0,0 +1,10 @@ +#!/bin/sh +echo $drivers +dracut_install wget cpio gzip dash modprobe touch echo cut wc +dracut_install -o ctorrent +dracut_install grep ifconfig hostname awk egrep grep dirname expr +dracut_install mount.nfs +dracut_install parted mke2fs bc mkswap swapon chmod +inst "$moddir/xcat-updateflag" "/tmp/updateflag" +inst "$moddir/xcatroot" "/sbin/xcatroot" +inst_hook cmdline 10 "$moddir/xcat-cmdline.sh" diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.statelite b/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.statelite deleted file mode 120000 index a29fbcca1..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.statelite +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/install.statelite \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.statelite b/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.statelite new file mode 100755 index 000000000..7c494d84c --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut_009/install.statelite @@ -0,0 +1,9 @@ +#!/bin/sh +echo $drivers +dracut_install wget cpio gzip dash modprobe wc touch echo cut +dracut_install -o ctorrent +dracut_install grep ifconfig hostname awk egrep grep dirname expr +dracut_install parted mke2fs bc mkswap swapon chmod +inst "$moddir/xcat-updateflag" "/tmp/updateflag" +inst_hook pre-mount 5 "$moddir/xcat-premount.sh" +inst_hook pre-pivot 5 "$moddir/xcat-prepivot.sh" diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/installkernel b/xCAT-server/share/xcat/netboot/fedora/dracut_009/installkernel deleted file mode 120000 index 65990228e..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut_009/installkernel +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/installkernel \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/installkernel b/xCAT-server/share/xcat/netboot/fedora/dracut_009/installkernel new file mode 100755 index 000000000..7902ce5f7 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut_009/installkernel @@ -0,0 +1,2 @@ +#!/bin/bash +instmods nfs sunrpc diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-premount.sh b/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-premount.sh deleted file mode 120000 index 862e21b2e..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-premount.sh +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-premount.sh \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-premount.sh b/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-premount.sh new file mode 100644 index 000000000..40c1dbbe5 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-premount.sh @@ -0,0 +1,18 @@ +#!/bin/sh +#script to update nodelist.nodestatus during provision + +MASTER=`echo $XCAT |awk -F: '{print $1}'` + +getarg nonodestatus +NODESTATUS=$? + +XCATIPORT="$(getarg XCATIPORT=)" +if [ $? -ne 0 ]; then +XCATIPORT="3002" +fi + + + +if [ $NODESTATUS -ne 0 ];then +/tmp/updateflag $MASTER $XCATIPORT "installstatus netbooting" +fi diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-updateflag b/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-updateflag deleted file mode 120000 index ba998cfb2..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-updateflag +++ /dev/null @@ -1 +0,0 @@ -../../rh/dracut/xcat-updateflag \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-updateflag b/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-updateflag new file mode 100755 index 000000000..2f9ac3165 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/dracut_009/xcat-updateflag @@ -0,0 +1,24 @@ +#!/bin/awk -f +#script to feedback the node provision status to xcatd +BEGIN { + + xcatdhost = ARGV[1] + xcatiport = ARGV[2] + + + ns = "/inet/tcp/0/" xcatdhost "/" xcatiport + print "xCAT_xcatd" |& ns + + while(1) { + ns |& getline + + if($0 == "ready") + print ARGV[3] |& ns + if($0 == "done") + break + } + + close(ns) + + exit 0 +} diff --git a/xCAT-server/share/xcat/netboot/fedora/genimage b/xCAT-server/share/xcat/netboot/fedora/genimage deleted file mode 120000 index 1c50b1848..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/genimage +++ /dev/null @@ -1 +0,0 @@ -../rh/genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/genimage b/xCAT-server/share/xcat/netboot/fedora/genimage new file mode 100755 index 000000000..8c4ced961 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/genimage @@ -0,0 +1,2081 @@ +#!/usr/bin/env perl + +# The possible files which getting from local OS that may affect he genimage cross distor level +# /proc/self/oom_adj + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $krpmver; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; +my $ignorekernelchk; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#check whether a dir is NFS mounted +sub isNFSdir{ + my $dir=shift; + my $out=qx(df -T -P $dir|tail -n 1|awk '{print \$2}'); + + if($out =~ /nfs/i) + { + return 1; + } + + return 0; +} + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; + } + + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; +} elsif ($arch eq 's390x') { + push @ndrivers, qw/qdio ccwgroup/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless ($onlyinitrd) { + @yumdirs=(); + + my @pkgdirs = split(",", $srcdir); + my $dir; + foreach $dir (@pkgdirs) { + find(\&isyumdir, <$dir/>); + if (!grep /$dir/, @yumdirs) { + print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n"; + } + } + + # Add the dir for kernel rpm to be installed + if ($kernelver) { + find(\&isyumdir, <$kerneldir/>); + if (!grep /$kerneldir/, @yumdirs) { + print "The repository for $kerneldir should be created before running the genimge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@yumdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + + mkpath "$rootimg_dir"; + my $yumconfig; + open($yumconfig,">","/tmp/genimage.$$.yum.conf"); + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + print $yumconfig "[main]\ndiskspacecheck=0\n\n"; + } + + my $repnum=0; + foreach $srcdir (@yumdirs) { + print $yumconfig "[$osver-$arch-$repnum]\nname=$osver-$arch-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n"; + $repnum += 1; + } + $repnum-=1; + close($yumconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my $yumcmd = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + + mkpath("$rootimg_dir/var/lib/yum"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + if ($p =~ /^kernel$/ && $kernelver) { + my $kernelname; + if ($krpmver) { + $kernelname = "kernel-".$krpmver; + } else { + $kernelname = "kernel-".$kernelver; + } + my $searchkern = $yumcmd . " list $kernelname -q"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*kernel[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + if ($kernelver =~ /$version/) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= " " . join(' ', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $yumcmd install $pkgnames\n"; + my $rc = system("$envlist $yumcmd install $pkgnames"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + my %repohash; + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $repohash{$pass}{$index} = 1; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + my $yumcmd_base = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + $yumcmd_base .= "--setopt=diskspacecheck=0 "; + } + + foreach (0..$repnum) { + $yumcmd_base .= "--enablerepo=$osver-$arch-$_ "; + } +# for (1..$index) { +# $yumcmd .= "--enablerepo=otherpkgs$_ "; +# } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + $yumcmd = $yumcmd_base; + foreach my $repo_index ( keys %{$repohash{$pass}} ) { + $yumcmd .= "--enablerepo=otherpkgs$repo_index "; + } + + system("$yumcmd clean all"); + + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + +# # mount /proc file system since several packages need it. +# print "mount /proc file system\nchroot $rootimg_dir /bin/mount -t proc proc /proc\n"; +# system("chroot $rootimg_dir /bin/mount -t proc proc /proc"); + + # install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + $yumcmd =~ s/ $/\n/; + + # debug + #print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $yumcmd\n"; + my $rc = system("$envlist $yumcmd"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + +# # umount /proc file system that just mounted +# print "umount /proc file system\nchroot $rootimg_dir /bin/umount /proc\n"; +# system("chroot $rootimg_dir /bin/umount /proc"); + + # 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) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} + +#get the rpm version, if the rpm version is different then the db verison may change. +my $mnrpmver = `rpm --version | awk '{print \$3}'`; +my $cnrpmver = `chroot $rootimg_dir rpm --version | awk '{print \$3}'`; +if ( $mnrpmver ne $cnrpmver ){ + #fine all db file witch should be rebuided + my $filelist = `file $rootimg_dir/var/lib/rpm/* | grep 'Berkeley DB' | awk -F : '{print \$1}'`; + + my @files = split '\n', $filelist; + + system("rm -rf $rootimg_dir/var/lib/rpm/__db*"); + foreach my $file ( @files ){ + my $filename = basename($file); + #dump the db file to a normal test file with the db_dump on the mn + system("db_dump $file > $rootimg_dir/tmp/$filename.dbtmp9"); + unlink("$rootimg_dir/var/lib/rpm/$filename"); + #chroot to the rootimage and run db_load + system(" chroot $rootimg_dir db_load -f /tmp/$filename.dbtmp9 /var/lib/rpm/$filename"); + } + system("rm -rf $rootimg_dir/tmp/*.dbtmp9"); + #rebuild rpm db file in rootimage for cn + system(" chroot $rootimg_dir rpm --rebuilddb"); +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +unlink "/tmp/genimage.$$.yum.conf"; +if ( (-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut") ) { + $dracutmode = 1; + # get dracut version + my $dracutver = `rpm --root $rootimg_dir -qi dracut | grep Version | awk -F' ' '{print \$3}'`; + chomp($dracutver); + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "033") { + $dracutdir = "dracut_033"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + + +#-- for centos, disable the internet repository +if( -e "$rootimg_dir/etc/yum.repos.d/CentOS-Base.repo" ) { + my $repo_content=`sed -e '/enabled/d' $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo | sed -e '/^gpgkey/i enabled=0'`; + system("echo '$repo_content' > $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo"); +} +# + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +#if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + if (-f "$rootimg_dir/etc/rc.sysinit") { + my $SYSINITFILE; + my $TMPSYSINITFILE; + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +#} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("stateless"); + mkinitrd_dracut("statelite"); +} else { + mkinitrd("statelite"); + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + + my $dracutmoduledir="$rootimg_dir/usr/share/dracut/modules.d/"; + if ( (! -d $dracutmoduledir) and (-d "$rootimg_dir/usr/lib/dracut/modules.d/")) + { + $dracutmoduledir="$rootimg_dir/usr/lib/dracut/modules.d/"; + } + + my $dracutmpath = $dracutmoduledir."97xcat/"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + # Add drivers to support local disk + push @ndrivers, "ext3"; + push @ndrivers, "ext4"; + #remove the duplicated drivers + my @fulldrivers; + foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } + } + @ndrivers = @fulldrivers; + + my $add_drivers = join(' ', @ndrivers); + print "Try to load drivers: $add_drivers to initrd.\n"; + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + cp("$fullpath/$dracutdir/xcat-premount.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-premount.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-premount.sh"); + + #update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + my $additional_options=undef; + if($rootlimit) + { + open(my $ETC_CMDLINE,">","$rootimg_dir/tmp/cmdline"); + print $ETC_CMDLINE qq{rootlimit=$rootlimit\n}; + close $ETC_CMDLINE; + $additional_options= qq{--include /tmp/cmdline /etc/cmdline}; + } + + # force the dracut run in non-hostonly mode for dracut higher than version 033 + if ($dracutver > "033") { + $additional_options .= " -N"; + } + system("chroot $rootimg_dir dracut $additional_options -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + + if($mode eq "statelite") { + push @ndrivers, "nfs.ko"; + + open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); + my @moddeps = <$moddeps>; + my @checkdeps = ("nfs.ko"); + 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"; + } + } + } + } + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox.anaconda mount -t proc /proc /proc\n"; + print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev on s390x +if ($arch eq "s390x") { + print $inifile < /etc/sysconfig/network + +echo "ONBOOT=yes" > /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "BOOTPROTO=dhcp" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "DEVICE=$prinic" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo 'OPTIONS="layer2=1"' >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "SUBCHANNELS=$subchn" >> /etc/sysconfig/network-scripts/ifcfg-$prinic + +# Turn on network devices +echo $subchn > /sys/bus/ccwgroup/drivers/qeth/group +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/layer2 +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/online +echo "alias $prinic qeth" >> /etc/modprobe.conf +echo `ifup $prinic` +sleep 4 +EOMS +} + + print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' + +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}'|sed -e s/^01-// -e s/-/:/g` + #BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + BOOTIF=\`ip -oneline link show |grep -i \$VALUE|awk -F ':' '{print \$2}'|grep -o \"[^ ]\+\( \+[^ ]\+\)*\"\` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 +echo network --device \$IFACE --bootproto dhcp >> /bin/netstart + +netstart \$IFACE +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + + + + + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ ! -z "\$NODENAME" ]; then + ME=\$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + close($inifile); + + #/tmp/updateflag: a script to feedback node provision status to xcatd + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod", "bin/bash", "usr/sbin/chroot", "sbin/mount.nfs", "usr/bin/rsync", "usr/bin/wc") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + push @filestoadd,"lib/libresolv.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + system("mkdir -p /tmp/xcatinitrd.$$/etc/sysconfig"); + system("cp -r $rootimg_dir/etc/sysconfig/* /tmp/xcatinitrd.$$/etc/sysconfig"); + system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + 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; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +sub using_systemd { + my $os = shift; + if ($os =~ /fedora(\d+)/) { + if ($1 >= 15) { + return 1; + } + }elsif ($os =~ /rhels(\d+)/) { + if ($1 >= 7) { + return 1; + } + } + + return 0; +} + + +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 (!&using_systemd($osver)) { + 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); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + + # gettyset is not found on s390x + if ($arch ne "s390x") { + if (!&using_systemd($osver)) { + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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 " if [ -x /sbin/initctl ]; then\n"; # Upstart style + # The syntax of next line is not correct, that means it does NOthing. (rh6 and higher) + # And it should NOT work for rh6 and higher, otherwise it will cauase multiple agetty for ttySx + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\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 " fi\n"; + print $cfgfile "done\n"; + + close($cfgfile); + + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/gettyset S60gettyset"); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd () +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + my $rc = system ("umount -f $dd_dir/mnt"); + if ($rc) { + print "umount the directory $dd_dir/mnt failed\n"; + exit 1; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT-server/share/xcat/netboot/fedora/geninitrd b/xCAT-server/share/xcat/netboot/fedora/geninitrd deleted file mode 120000 index 2271c3f0f..000000000 --- a/xCAT-server/share/xcat/netboot/fedora/geninitrd +++ /dev/null @@ -1 +0,0 @@ -genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/fedora/geninitrd b/xCAT-server/share/xcat/netboot/fedora/geninitrd new file mode 100755 index 000000000..8c4ced961 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/fedora/geninitrd @@ -0,0 +1,2081 @@ +#!/usr/bin/env perl + +# The possible files which getting from local OS that may affect he genimage cross distor level +# /proc/self/oom_adj + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $krpmver; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; +my $ignorekernelchk; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#check whether a dir is NFS mounted +sub isNFSdir{ + my $dir=shift; + my $out=qx(df -T -P $dir|tail -n 1|awk '{print \$2}'); + + if($out =~ /nfs/i) + { + return 1; + } + + return 0; +} + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; + } + + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; +} elsif ($arch eq 's390x') { + push @ndrivers, qw/qdio ccwgroup/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless ($onlyinitrd) { + @yumdirs=(); + + my @pkgdirs = split(",", $srcdir); + my $dir; + foreach $dir (@pkgdirs) { + find(\&isyumdir, <$dir/>); + if (!grep /$dir/, @yumdirs) { + print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n"; + } + } + + # Add the dir for kernel rpm to be installed + if ($kernelver) { + find(\&isyumdir, <$kerneldir/>); + if (!grep /$kerneldir/, @yumdirs) { + print "The repository for $kerneldir should be created before running the genimge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@yumdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + + mkpath "$rootimg_dir"; + my $yumconfig; + open($yumconfig,">","/tmp/genimage.$$.yum.conf"); + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + print $yumconfig "[main]\ndiskspacecheck=0\n\n"; + } + + my $repnum=0; + foreach $srcdir (@yumdirs) { + print $yumconfig "[$osver-$arch-$repnum]\nname=$osver-$arch-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n"; + $repnum += 1; + } + $repnum-=1; + close($yumconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my $yumcmd = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + + mkpath("$rootimg_dir/var/lib/yum"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + if ($p =~ /^kernel$/ && $kernelver) { + my $kernelname; + if ($krpmver) { + $kernelname = "kernel-".$krpmver; + } else { + $kernelname = "kernel-".$kernelver; + } + my $searchkern = $yumcmd . " list $kernelname -q"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*kernel[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + if ($kernelver =~ /$version/) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= " " . join(' ', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $yumcmd install $pkgnames\n"; + my $rc = system("$envlist $yumcmd install $pkgnames"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + my %repohash; + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $repohash{$pass}{$index} = 1; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + my $yumcmd_base = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + $yumcmd_base .= "--setopt=diskspacecheck=0 "; + } + + foreach (0..$repnum) { + $yumcmd_base .= "--enablerepo=$osver-$arch-$_ "; + } +# for (1..$index) { +# $yumcmd .= "--enablerepo=otherpkgs$_ "; +# } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + $yumcmd = $yumcmd_base; + foreach my $repo_index ( keys %{$repohash{$pass}} ) { + $yumcmd .= "--enablerepo=otherpkgs$repo_index "; + } + + system("$yumcmd clean all"); + + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + +# # mount /proc file system since several packages need it. +# print "mount /proc file system\nchroot $rootimg_dir /bin/mount -t proc proc /proc\n"; +# system("chroot $rootimg_dir /bin/mount -t proc proc /proc"); + + # install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + $yumcmd =~ s/ $/\n/; + + # debug + #print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $yumcmd\n"; + my $rc = system("$envlist $yumcmd"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + +# # umount /proc file system that just mounted +# print "umount /proc file system\nchroot $rootimg_dir /bin/umount /proc\n"; +# system("chroot $rootimg_dir /bin/umount /proc"); + + # 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) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} + +#get the rpm version, if the rpm version is different then the db verison may change. +my $mnrpmver = `rpm --version | awk '{print \$3}'`; +my $cnrpmver = `chroot $rootimg_dir rpm --version | awk '{print \$3}'`; +if ( $mnrpmver ne $cnrpmver ){ + #fine all db file witch should be rebuided + my $filelist = `file $rootimg_dir/var/lib/rpm/* | grep 'Berkeley DB' | awk -F : '{print \$1}'`; + + my @files = split '\n', $filelist; + + system("rm -rf $rootimg_dir/var/lib/rpm/__db*"); + foreach my $file ( @files ){ + my $filename = basename($file); + #dump the db file to a normal test file with the db_dump on the mn + system("db_dump $file > $rootimg_dir/tmp/$filename.dbtmp9"); + unlink("$rootimg_dir/var/lib/rpm/$filename"); + #chroot to the rootimage and run db_load + system(" chroot $rootimg_dir db_load -f /tmp/$filename.dbtmp9 /var/lib/rpm/$filename"); + } + system("rm -rf $rootimg_dir/tmp/*.dbtmp9"); + #rebuild rpm db file in rootimage for cn + system(" chroot $rootimg_dir rpm --rebuilddb"); +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +unlink "/tmp/genimage.$$.yum.conf"; +if ( (-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut") ) { + $dracutmode = 1; + # get dracut version + my $dracutver = `rpm --root $rootimg_dir -qi dracut | grep Version | awk -F' ' '{print \$3}'`; + chomp($dracutver); + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "033") { + $dracutdir = "dracut_033"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + + +#-- for centos, disable the internet repository +if( -e "$rootimg_dir/etc/yum.repos.d/CentOS-Base.repo" ) { + my $repo_content=`sed -e '/enabled/d' $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo | sed -e '/^gpgkey/i enabled=0'`; + system("echo '$repo_content' > $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo"); +} +# + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +#if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + if (-f "$rootimg_dir/etc/rc.sysinit") { + my $SYSINITFILE; + my $TMPSYSINITFILE; + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +#} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("stateless"); + mkinitrd_dracut("statelite"); +} else { + mkinitrd("statelite"); + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + + my $dracutmoduledir="$rootimg_dir/usr/share/dracut/modules.d/"; + if ( (! -d $dracutmoduledir) and (-d "$rootimg_dir/usr/lib/dracut/modules.d/")) + { + $dracutmoduledir="$rootimg_dir/usr/lib/dracut/modules.d/"; + } + + my $dracutmpath = $dracutmoduledir."97xcat/"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + # Add drivers to support local disk + push @ndrivers, "ext3"; + push @ndrivers, "ext4"; + #remove the duplicated drivers + my @fulldrivers; + foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } + } + @ndrivers = @fulldrivers; + + my $add_drivers = join(' ', @ndrivers); + print "Try to load drivers: $add_drivers to initrd.\n"; + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + cp("$fullpath/$dracutdir/xcat-premount.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-premount.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-premount.sh"); + + #update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + my $additional_options=undef; + if($rootlimit) + { + open(my $ETC_CMDLINE,">","$rootimg_dir/tmp/cmdline"); + print $ETC_CMDLINE qq{rootlimit=$rootlimit\n}; + close $ETC_CMDLINE; + $additional_options= qq{--include /tmp/cmdline /etc/cmdline}; + } + + # force the dracut run in non-hostonly mode for dracut higher than version 033 + if ($dracutver > "033") { + $additional_options .= " -N"; + } + system("chroot $rootimg_dir dracut $additional_options -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + + if($mode eq "statelite") { + push @ndrivers, "nfs.ko"; + + open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); + my @moddeps = <$moddeps>; + my @checkdeps = ("nfs.ko"); + 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"; + } + } + } + } + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox.anaconda mount -t proc /proc /proc\n"; + print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev on s390x +if ($arch eq "s390x") { + print $inifile < /etc/sysconfig/network + +echo "ONBOOT=yes" > /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "BOOTPROTO=dhcp" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "DEVICE=$prinic" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo 'OPTIONS="layer2=1"' >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "SUBCHANNELS=$subchn" >> /etc/sysconfig/network-scripts/ifcfg-$prinic + +# Turn on network devices +echo $subchn > /sys/bus/ccwgroup/drivers/qeth/group +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/layer2 +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/online +echo "alias $prinic qeth" >> /etc/modprobe.conf +echo `ifup $prinic` +sleep 4 +EOMS +} + + print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' + +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}'|sed -e s/^01-// -e s/-/:/g` + #BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + BOOTIF=\`ip -oneline link show |grep -i \$VALUE|awk -F ':' '{print \$2}'|grep -o \"[^ ]\+\( \+[^ ]\+\)*\"\` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 +echo network --device \$IFACE --bootproto dhcp >> /bin/netstart + +netstart \$IFACE +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + + + + + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ ! -z "\$NODENAME" ]; then + ME=\$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + close($inifile); + + #/tmp/updateflag: a script to feedback node provision status to xcatd + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod", "bin/bash", "usr/sbin/chroot", "sbin/mount.nfs", "usr/bin/rsync", "usr/bin/wc") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + push @filestoadd,"lib/libresolv.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + system("mkdir -p /tmp/xcatinitrd.$$/etc/sysconfig"); + system("cp -r $rootimg_dir/etc/sysconfig/* /tmp/xcatinitrd.$$/etc/sysconfig"); + system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + 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; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +sub using_systemd { + my $os = shift; + if ($os =~ /fedora(\d+)/) { + if ($1 >= 15) { + return 1; + } + }elsif ($os =~ /rhels(\d+)/) { + if ($1 >= 7) { + return 1; + } + } + + return 0; +} + + +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 (!&using_systemd($osver)) { + 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); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + + # gettyset is not found on s390x + if ($arch ne "s390x") { + if (!&using_systemd($osver)) { + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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 " if [ -x /sbin/initctl ]; then\n"; # Upstart style + # The syntax of next line is not correct, that means it does NOthing. (rh6 and higher) + # And it should NOT work for rh6 and higher, otherwise it will cauase multiple agetty for ttySx + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\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 " fi\n"; + print $cfgfile "done\n"; + + close($cfgfile); + + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/gettyset S60gettyset"); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd () +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + my $rc = system ("umount -f $dd_dir/mnt"); + if ($rc) { + print "umount the directory $dd_dir/mnt failed\n"; + exit 1; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT-server/share/xcat/netboot/ol/compute.exlist b/xCAT-server/share/xcat/netboot/ol/compute.exlist deleted file mode 120000 index faac2cf6a..000000000 --- a/xCAT-server/share/xcat/netboot/ol/compute.exlist +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.exlist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/ol/compute.exlist b/xCAT-server/share/xcat/netboot/ol/compute.exlist new file mode 100644 index 000000000..be73e79d5 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ol/compute.exlist @@ -0,0 +1,14 @@ +./usr/share/man/* +./usr/share/locale/* +./usr/share/i18n* +./var/cache/yum* +./usr/share/doc* +./usr/share/gnome* +./usr/share/zoneinfo* +./usr/share/cracklib* +./usr/share/info* +./usr/share/omf* +./usr/lib/locale* +./usr/lib/perl5* +./usr/share/backgrounds* +./boot* diff --git a/xCAT-server/share/xcat/netboot/ol/compute.ol6.pkglist b/xCAT-server/share/xcat/netboot/ol/compute.ol6.pkglist deleted file mode 120000 index a2ac48243..000000000 --- a/xCAT-server/share/xcat/netboot/ol/compute.ol6.pkglist +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.rhels6.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/ol/compute.ol6.pkglist b/xCAT-server/share/xcat/netboot/ol/compute.ol6.pkglist new file mode 100644 index 000000000..555ec63cc --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ol/compute.ol6.pkglist @@ -0,0 +1,15 @@ +bash +dracut-network +nfs-utils +openssl +dhclient +kernel +openssh-server +openssh-clients +wget +vim-minimal +ntp +rpm +rsync +rsyslog +e2fsprogs diff --git a/xCAT-server/share/xcat/netboot/ol/compute.pkglist b/xCAT-server/share/xcat/netboot/ol/compute.pkglist deleted file mode 120000 index 8011acba5..000000000 --- a/xCAT-server/share/xcat/netboot/ol/compute.pkglist +++ /dev/null @@ -1 +0,0 @@ -../rh/compute.pkglist \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/ol/compute.pkglist b/xCAT-server/share/xcat/netboot/ol/compute.pkglist new file mode 100644 index 000000000..30d4e4feb --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ol/compute.pkglist @@ -0,0 +1,14 @@ +bash +nfs-utils +openssl +dhclient +kernel +openssh-server +openssh-clients +busybox-anaconda +wget +vim-minimal +ntp +sysklogd +rpm +rsync diff --git a/xCAT-server/share/xcat/netboot/ol/dracut b/xCAT-server/share/xcat/netboot/ol/dracut deleted file mode 120000 index 11bde8445..000000000 --- a/xCAT-server/share/xcat/netboot/ol/dracut +++ /dev/null @@ -1 +0,0 @@ -../rh/dracut \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/ol/genimage b/xCAT-server/share/xcat/netboot/ol/genimage deleted file mode 120000 index 1c50b1848..000000000 --- a/xCAT-server/share/xcat/netboot/ol/genimage +++ /dev/null @@ -1 +0,0 @@ -../rh/genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/ol/genimage b/xCAT-server/share/xcat/netboot/ol/genimage new file mode 100755 index 000000000..8c4ced961 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ol/genimage @@ -0,0 +1,2081 @@ +#!/usr/bin/env perl + +# The possible files which getting from local OS that may affect he genimage cross distor level +# /proc/self/oom_adj + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $krpmver; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; +my $ignorekernelchk; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#check whether a dir is NFS mounted +sub isNFSdir{ + my $dir=shift; + my $out=qx(df -T -P $dir|tail -n 1|awk '{print \$2}'); + + if($out =~ /nfs/i) + { + return 1; + } + + return 0; +} + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; + } + + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; +} elsif ($arch eq 's390x') { + push @ndrivers, qw/qdio ccwgroup/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless ($onlyinitrd) { + @yumdirs=(); + + my @pkgdirs = split(",", $srcdir); + my $dir; + foreach $dir (@pkgdirs) { + find(\&isyumdir, <$dir/>); + if (!grep /$dir/, @yumdirs) { + print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n"; + } + } + + # Add the dir for kernel rpm to be installed + if ($kernelver) { + find(\&isyumdir, <$kerneldir/>); + if (!grep /$kerneldir/, @yumdirs) { + print "The repository for $kerneldir should be created before running the genimge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@yumdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + + mkpath "$rootimg_dir"; + my $yumconfig; + open($yumconfig,">","/tmp/genimage.$$.yum.conf"); + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + print $yumconfig "[main]\ndiskspacecheck=0\n\n"; + } + + my $repnum=0; + foreach $srcdir (@yumdirs) { + print $yumconfig "[$osver-$arch-$repnum]\nname=$osver-$arch-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n"; + $repnum += 1; + } + $repnum-=1; + close($yumconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my $yumcmd = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + + mkpath("$rootimg_dir/var/lib/yum"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + if ($p =~ /^kernel$/ && $kernelver) { + my $kernelname; + if ($krpmver) { + $kernelname = "kernel-".$krpmver; + } else { + $kernelname = "kernel-".$kernelver; + } + my $searchkern = $yumcmd . " list $kernelname -q"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*kernel[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + if ($kernelver =~ /$version/) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= " " . join(' ', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $yumcmd install $pkgnames\n"; + my $rc = system("$envlist $yumcmd install $pkgnames"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + my %repohash; + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $repohash{$pass}{$index} = 1; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + my $yumcmd_base = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + $yumcmd_base .= "--setopt=diskspacecheck=0 "; + } + + foreach (0..$repnum) { + $yumcmd_base .= "--enablerepo=$osver-$arch-$_ "; + } +# for (1..$index) { +# $yumcmd .= "--enablerepo=otherpkgs$_ "; +# } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + $yumcmd = $yumcmd_base; + foreach my $repo_index ( keys %{$repohash{$pass}} ) { + $yumcmd .= "--enablerepo=otherpkgs$repo_index "; + } + + system("$yumcmd clean all"); + + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + +# # mount /proc file system since several packages need it. +# print "mount /proc file system\nchroot $rootimg_dir /bin/mount -t proc proc /proc\n"; +# system("chroot $rootimg_dir /bin/mount -t proc proc /proc"); + + # install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + $yumcmd =~ s/ $/\n/; + + # debug + #print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $yumcmd\n"; + my $rc = system("$envlist $yumcmd"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + +# # umount /proc file system that just mounted +# print "umount /proc file system\nchroot $rootimg_dir /bin/umount /proc\n"; +# system("chroot $rootimg_dir /bin/umount /proc"); + + # 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) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} + +#get the rpm version, if the rpm version is different then the db verison may change. +my $mnrpmver = `rpm --version | awk '{print \$3}'`; +my $cnrpmver = `chroot $rootimg_dir rpm --version | awk '{print \$3}'`; +if ( $mnrpmver ne $cnrpmver ){ + #fine all db file witch should be rebuided + my $filelist = `file $rootimg_dir/var/lib/rpm/* | grep 'Berkeley DB' | awk -F : '{print \$1}'`; + + my @files = split '\n', $filelist; + + system("rm -rf $rootimg_dir/var/lib/rpm/__db*"); + foreach my $file ( @files ){ + my $filename = basename($file); + #dump the db file to a normal test file with the db_dump on the mn + system("db_dump $file > $rootimg_dir/tmp/$filename.dbtmp9"); + unlink("$rootimg_dir/var/lib/rpm/$filename"); + #chroot to the rootimage and run db_load + system(" chroot $rootimg_dir db_load -f /tmp/$filename.dbtmp9 /var/lib/rpm/$filename"); + } + system("rm -rf $rootimg_dir/tmp/*.dbtmp9"); + #rebuild rpm db file in rootimage for cn + system(" chroot $rootimg_dir rpm --rebuilddb"); +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +unlink "/tmp/genimage.$$.yum.conf"; +if ( (-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut") ) { + $dracutmode = 1; + # get dracut version + my $dracutver = `rpm --root $rootimg_dir -qi dracut | grep Version | awk -F' ' '{print \$3}'`; + chomp($dracutver); + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "033") { + $dracutdir = "dracut_033"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + + +#-- for centos, disable the internet repository +if( -e "$rootimg_dir/etc/yum.repos.d/CentOS-Base.repo" ) { + my $repo_content=`sed -e '/enabled/d' $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo | sed -e '/^gpgkey/i enabled=0'`; + system("echo '$repo_content' > $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo"); +} +# + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +#if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + if (-f "$rootimg_dir/etc/rc.sysinit") { + my $SYSINITFILE; + my $TMPSYSINITFILE; + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +#} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("stateless"); + mkinitrd_dracut("statelite"); +} else { + mkinitrd("statelite"); + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + + my $dracutmoduledir="$rootimg_dir/usr/share/dracut/modules.d/"; + if ( (! -d $dracutmoduledir) and (-d "$rootimg_dir/usr/lib/dracut/modules.d/")) + { + $dracutmoduledir="$rootimg_dir/usr/lib/dracut/modules.d/"; + } + + my $dracutmpath = $dracutmoduledir."97xcat/"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + # Add drivers to support local disk + push @ndrivers, "ext3"; + push @ndrivers, "ext4"; + #remove the duplicated drivers + my @fulldrivers; + foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } + } + @ndrivers = @fulldrivers; + + my $add_drivers = join(' ', @ndrivers); + print "Try to load drivers: $add_drivers to initrd.\n"; + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + cp("$fullpath/$dracutdir/xcat-premount.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-premount.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-premount.sh"); + + #update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + my $additional_options=undef; + if($rootlimit) + { + open(my $ETC_CMDLINE,">","$rootimg_dir/tmp/cmdline"); + print $ETC_CMDLINE qq{rootlimit=$rootlimit\n}; + close $ETC_CMDLINE; + $additional_options= qq{--include /tmp/cmdline /etc/cmdline}; + } + + # force the dracut run in non-hostonly mode for dracut higher than version 033 + if ($dracutver > "033") { + $additional_options .= " -N"; + } + system("chroot $rootimg_dir dracut $additional_options -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + + if($mode eq "statelite") { + push @ndrivers, "nfs.ko"; + + open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); + my @moddeps = <$moddeps>; + my @checkdeps = ("nfs.ko"); + 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"; + } + } + } + } + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox.anaconda mount -t proc /proc /proc\n"; + print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev on s390x +if ($arch eq "s390x") { + print $inifile < /etc/sysconfig/network + +echo "ONBOOT=yes" > /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "BOOTPROTO=dhcp" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "DEVICE=$prinic" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo 'OPTIONS="layer2=1"' >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "SUBCHANNELS=$subchn" >> /etc/sysconfig/network-scripts/ifcfg-$prinic + +# Turn on network devices +echo $subchn > /sys/bus/ccwgroup/drivers/qeth/group +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/layer2 +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/online +echo "alias $prinic qeth" >> /etc/modprobe.conf +echo `ifup $prinic` +sleep 4 +EOMS +} + + print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' + +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}'|sed -e s/^01-// -e s/-/:/g` + #BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + BOOTIF=\`ip -oneline link show |grep -i \$VALUE|awk -F ':' '{print \$2}'|grep -o \"[^ ]\+\( \+[^ ]\+\)*\"\` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 +echo network --device \$IFACE --bootproto dhcp >> /bin/netstart + +netstart \$IFACE +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + + + + + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ ! -z "\$NODENAME" ]; then + ME=\$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + close($inifile); + + #/tmp/updateflag: a script to feedback node provision status to xcatd + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod", "bin/bash", "usr/sbin/chroot", "sbin/mount.nfs", "usr/bin/rsync", "usr/bin/wc") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + push @filestoadd,"lib/libresolv.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + system("mkdir -p /tmp/xcatinitrd.$$/etc/sysconfig"); + system("cp -r $rootimg_dir/etc/sysconfig/* /tmp/xcatinitrd.$$/etc/sysconfig"); + system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + 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; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +sub using_systemd { + my $os = shift; + if ($os =~ /fedora(\d+)/) { + if ($1 >= 15) { + return 1; + } + }elsif ($os =~ /rhels(\d+)/) { + if ($1 >= 7) { + return 1; + } + } + + return 0; +} + + +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 (!&using_systemd($osver)) { + 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); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + + # gettyset is not found on s390x + if ($arch ne "s390x") { + if (!&using_systemd($osver)) { + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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 " if [ -x /sbin/initctl ]; then\n"; # Upstart style + # The syntax of next line is not correct, that means it does NOthing. (rh6 and higher) + # And it should NOT work for rh6 and higher, otherwise it will cauase multiple agetty for ttySx + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\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 " fi\n"; + print $cfgfile "done\n"; + + close($cfgfile); + + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/gettyset S60gettyset"); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd () +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + my $rc = system ("umount -f $dd_dir/mnt"); + if ($rc) { + print "umount the directory $dd_dir/mnt failed\n"; + exit 1; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT-server/share/xcat/netboot/rh/geninitrd b/xCAT-server/share/xcat/netboot/rh/geninitrd deleted file mode 120000 index 2271c3f0f..000000000 --- a/xCAT-server/share/xcat/netboot/rh/geninitrd +++ /dev/null @@ -1 +0,0 @@ -genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/rh/geninitrd b/xCAT-server/share/xcat/netboot/rh/geninitrd new file mode 100755 index 000000000..8c4ced961 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/rh/geninitrd @@ -0,0 +1,2081 @@ +#!/usr/bin/env perl + +# The possible files which getting from local OS that may affect he genimage cross distor level +# /proc/self/oom_adj + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $krpmver; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; +my $ignorekernelchk; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#check whether a dir is NFS mounted +sub isNFSdir{ + my $dir=shift; + my $out=qx(df -T -P $dir|tail -n 1|awk '{print \$2}'); + + if($out =~ /nfs/i) + { + return 1; + } + + return 0; +} + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; + } + + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/e1000 e1000e igb ibmveth ehea/; +} elsif ($arch eq 's390x') { + push @ndrivers, qw/qdio ccwgroup/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless ($onlyinitrd) { + @yumdirs=(); + + my @pkgdirs = split(",", $srcdir); + my $dir; + foreach $dir (@pkgdirs) { + find(\&isyumdir, <$dir/>); + if (!grep /$dir/, @yumdirs) { + print "The repository for $dir should be created before running the genimge. Try to run [createrepo $dir].\n"; + } + } + + # Add the dir for kernel rpm to be installed + if ($kernelver) { + find(\&isyumdir, <$kerneldir/>); + if (!grep /$kerneldir/, @yumdirs) { + print "The repository for $kerneldir should be created before running the genimge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@yumdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + + mkpath "$rootimg_dir"; + my $yumconfig; + open($yumconfig,">","/tmp/genimage.$$.yum.conf"); + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + print $yumconfig "[main]\ndiskspacecheck=0\n\n"; + } + + my $repnum=0; + foreach $srcdir (@yumdirs) { + print $yumconfig "[$osver-$arch-$repnum]\nname=$osver-$arch-$repnum\nbaseurl=file://$srcdir\ngpgpcheck=0\n\n"; + $repnum += 1; + } + $repnum-=1; + close($yumconfig); + mkpath "$rootimg_dir/etc"; + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my $yumcmd = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + foreach (0..$repnum) { + $yumcmd .= "--enablerepo=$osver-$arch-$_ "; + } + + mkpath("$rootimg_dir/var/lib/yum"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + if ($p =~ /^kernel$/ && $kernelver) { + my $kernelname; + if ($krpmver) { + $kernelname = "kernel-".$krpmver; + } else { + $kernelname = "kernel-".$kernelver; + } + my $searchkern = $yumcmd . " list $kernelname -q"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*kernel[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + if ($kernelver =~ /$version/) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= " " . join(' ', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $yumcmd install $pkgnames\n"; + my $rc = system("$envlist $yumcmd install $pkgnames"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + my %repohash; + if (keys(%extra_hash) > 0) { + open($yumconfig,">>","/tmp/genimage.$$.yum.conf"); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + print $yumconfig "[otherpkgs$index]\nname=otherpkgs$index\nbaseurl=file://$srcdir_otherpkgs/$_\ngpgpcheck=0\n\n"; + $repohash{$pass}{$index} = 1; + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + close($yumconfig); + $index--; + my $yumcmd_base = "yum $non_interactive -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir/ --disablerepo=* "; + + #yum/rpm/zypper has defect on calculating diskspace usage when installing rpm on a NFS mounted installroot + if(isNFSdir("$rootimg_dir")){ + $yumcmd_base .= "--setopt=diskspacecheck=0 "; + } + + foreach (0..$repnum) { + $yumcmd_base .= "--enablerepo=$osver-$arch-$_ "; + } +# for (1..$index) { +# $yumcmd .= "--enablerepo=otherpkgs$_ "; +# } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + $yumcmd = $yumcmd_base; + foreach my $repo_index ( keys %{$repohash{$pass}} ) { + $yumcmd .= "--enablerepo=otherpkgs$repo_index "; + } + + system("$yumcmd clean all"); + + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "$yumcmd erase "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + +# # mount /proc file system since several packages need it. +# print "mount /proc file system\nchroot $rootimg_dir /bin/mount -t proc proc /proc\n"; +# system("chroot $rootimg_dir /bin/mount -t proc proc /proc"); + + # install extra packages + my $yumcmd_base = $yumcmd; + $yumcmd .= "install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $yumcmd .= " $extrapkgnames{$pass} "; + $yumcmd =~ s/ $/\n/; + + # debug + #print "yumcmd=$yumcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $yumcmd\n"; + my $rc = system("$envlist $yumcmd"); + if ($rc) { + print "yum invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + +# # umount /proc file system that just mounted +# print "umount /proc file system\nchroot $rootimg_dir /bin/umount /proc\n"; +# system("chroot $rootimg_dir /bin/umount /proc"); + + # 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) { + print "$envlist $yumcmd_remove $rm_packges\n"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + $yumcmd = $yumcmd_base; + + # run yum update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update = $yumcmd_base . " update "; + $rc = system("$yumcmd_update"); + + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} + +#get the rpm version, if the rpm version is different then the db verison may change. +my $mnrpmver = `rpm --version | awk '{print \$3}'`; +my $cnrpmver = `chroot $rootimg_dir rpm --version | awk '{print \$3}'`; +if ( $mnrpmver ne $cnrpmver ){ + #fine all db file witch should be rebuided + my $filelist = `file $rootimg_dir/var/lib/rpm/* | grep 'Berkeley DB' | awk -F : '{print \$1}'`; + + my @files = split '\n', $filelist; + + system("rm -rf $rootimg_dir/var/lib/rpm/__db*"); + foreach my $file ( @files ){ + my $filename = basename($file); + #dump the db file to a normal test file with the db_dump on the mn + system("db_dump $file > $rootimg_dir/tmp/$filename.dbtmp9"); + unlink("$rootimg_dir/var/lib/rpm/$filename"); + #chroot to the rootimage and run db_load + system(" chroot $rootimg_dir db_load -f /tmp/$filename.dbtmp9 /var/lib/rpm/$filename"); + } + system("rm -rf $rootimg_dir/tmp/*.dbtmp9"); + #rebuild rpm db file in rootimage for cn + system(" chroot $rootimg_dir rpm --rebuilddb"); +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); +my @moddeps = <$moddeps>; +my @checkdeps = @ndrivers; +while (scalar @checkdeps) { + my $driver = pop @checkdeps; + my @lines = grep /\/$driver:/,@moddeps; + foreach (@lines) { + chomp; + s/.*://; + s/^\s*//; + my @deps = split /\s+/,$_; + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +unlink "/tmp/genimage.$$.yum.conf"; +if ( (-d "$rootimg_dir/usr/share/dracut") or (-d "$rootimg_dir/usr/lib/dracut") ) { + $dracutmode = 1; + # get dracut version + my $dracutver = `rpm --root $rootimg_dir -qi dracut | grep Version | awk -F' ' '{print \$3}'`; + chomp($dracutver); + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "033") { + $dracutdir = "dracut_033"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + + +#-- for centos, disable the internet repository +if( -e "$rootimg_dir/etc/yum.repos.d/CentOS-Base.repo" ) { + my $repo_content=`sed -e '/enabled/d' $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo | sed -e '/^gpgkey/i enabled=0'`; + system("echo '$repo_content' > $rootimg_dir/etc/yum.repos.d/CentOS-Base.repo"); +} +# + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +system("cp $cwd/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +#if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + if (-f "$rootimg_dir/etc/rc.sysinit") { + my $SYSINITFILE; + my $TMPSYSINITFILE; + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +#} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("stateless"); + mkinitrd_dracut("statelite"); +} else { + mkinitrd("statelite"); + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + + my $dracutmoduledir="$rootimg_dir/usr/share/dracut/modules.d/"; + if ( (! -d $dracutmoduledir) and (-d "$rootimg_dir/usr/lib/dracut/modules.d/")) + { + $dracutmoduledir="$rootimg_dir/usr/lib/dracut/modules.d/"; + } + + my $dracutmpath = $dracutmoduledir."97xcat/"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + # Add drivers to support local disk + push @ndrivers, "ext3"; + push @ndrivers, "ext4"; + #remove the duplicated drivers + my @fulldrivers; + foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } + } + @ndrivers = @fulldrivers; + + my $add_drivers = join(' ', @ndrivers); + print "Try to load drivers: $add_drivers to initrd.\n"; + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + cp("$fullpath/$dracutdir/xcat-premount.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-premount.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-premount.sh"); + + #update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + cp("$fullpath/$dracutdir/xcat-updateflag",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-updateflag"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-updateflag"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + if (-d glob($dracutmoduledir."[0-9]*fadump")){ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules fadump"\n}; + } + else{ + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + } + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + my $additional_options=undef; + if($rootlimit) + { + open(my $ETC_CMDLINE,">","$rootimg_dir/tmp/cmdline"); + print $ETC_CMDLINE qq{rootlimit=$rootlimit\n}; + close $ETC_CMDLINE; + $additional_options= qq{--include /tmp/cmdline /etc/cmdline}; + } + + # force the dracut run in non-hostonly mode for dracut higher than version 033 + if ($dracutver > "033") { + $additional_options .= " -N"; + } + system("chroot $rootimg_dir dracut $additional_options -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + + if($mode eq "statelite") { + push @ndrivers, "nfs.ko"; + + open($moddeps,"<","$rootimg_dir/lib/modules/$kernelver/modules.dep"); + my @moddeps = <$moddeps>; + my @checkdeps = ("nfs.ko"); + 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"; + } + } + } + } + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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/dhclient"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/sbin/busybox.anaconda sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox.anaconda mount -t proc /proc /proc\n"; + print $inifile "busybox.anaconda --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev on s390x +if ($arch eq "s390x") { + print $inifile < /etc/sysconfig/network + +echo "ONBOOT=yes" > /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "BOOTPROTO=dhcp" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "DEVICE=$prinic" >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo 'OPTIONS="layer2=1"' >> /etc/sysconfig/network-scripts/ifcfg-$prinic +echo "SUBCHANNELS=$subchn" >> /etc/sysconfig/network-scripts/ifcfg-$prinic + +# Turn on network devices +echo $subchn > /sys/bus/ccwgroup/drivers/qeth/group +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/layer2 +echo 1 > /sys/bus/ccwgroup/drivers/qeth/$readChn/online +echo "alias $prinic qeth" >> /etc/modprobe.conf +echo `ifup $prinic` +sleep 4 +EOMS +} + + print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' + +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}'|sed -e s/^01-// -e s/-/:/g` + #BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + BOOTIF=\`ip -oneline link show |grep -i \$VALUE|awk -F ':' '{print \$2}'|grep -o \"[^ ]\+\( \+[^ ]\+\)*\"\` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 +echo network --device \$IFACE --bootproto dhcp >> /bin/netstart + +netstart \$IFACE +while ! ifconfig | grep inet; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + + + + + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ ! -z "\$NODENAME" ]; then + ME=\$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + if ! exec /sbin/switch_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't switch_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/sbin/nash\n"; + close($inifile); + + #/tmp/updateflag: a script to feedback node provision status to xcatd + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod", "bin/bash", "usr/sbin/chroot", "sbin/mount.nfs", "usr/bin/rsync", "usr/bin/wc") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + push @filestoadd,"lib/libresolv.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + system("mkdir -p /tmp/xcatinitrd.$$/etc/sysconfig"); + system("cp -r $rootimg_dir/etc/sysconfig/* /tmp/xcatinitrd.$$/etc/sysconfig"); + system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + 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; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +sub using_systemd { + my $os = shift; + if ($os =~ /fedora(\d+)/) { + if ($1 >= 15) { + return 1; + } + }elsif ($os =~ /rhels(\d+)/) { + if ($1 >= 7) { + return 1; + } + } + + return 0; +} + + +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 (!&using_systemd($osver)) { + 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); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/network","$rootimg_dir/etc/rc3.d/S10network"; + } + + # gettyset is not found on s390x + if ($arch ne "s390x") { + if (!&using_systemd($osver)) { + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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 " if [ -x /sbin/initctl ]; then\n"; # Upstart style + # The syntax of next line is not correct, that means it does NOthing. (rh6 and higher) + # And it should NOT work for rh6 and higher, otherwise it will cauase multiple agetty for ttySx + print $cfgfile " initctl emit --no-wait fedora.serial-console-available \$COTTY \$COSPEED\n"; + print $cfgfile " else\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 " fi\n"; + print $cfgfile "done\n"; + + close($cfgfile); + + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/gettyset S60gettyset"); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc3.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd () +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + my $rc = system ("umount -f $dd_dir/mnt"); + if ($rc) { + print "umount the directory $dd_dir/mnt failed\n"; + exit 1; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT-server/share/xcat/netboot/sles/geninitrd b/xCAT-server/share/xcat/netboot/sles/geninitrd deleted file mode 120000 index 2271c3f0f..000000000 --- a/xCAT-server/share/xcat/netboot/sles/geninitrd +++ /dev/null @@ -1 +0,0 @@ -genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/sles/geninitrd b/xCAT-server/share/xcat/netboot/sles/geninitrd new file mode 100755 index 000000000..daedcca5a --- /dev/null +++ b/xCAT-server/share/xcat/netboot/sles/geninitrd @@ -0,0 +1,2136 @@ +#!/usr/bin/env perl +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use File::Temp qw/mkdtemp/; + +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#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; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; +my $basekernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $mode; +my $permission; #the permission works only for statelite mode currently +my $krpmver; +my $tempfile; +my $prompt; +my $timezone; #the TIMEZONE of the stateless and statelite node +my $ignorekernelchk; + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#-- 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); +# } +# } + + +$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, + 'k=s' => \$kernelver, + 'g=s' => \$krpmver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'timezone=s' => \$timezone, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'driverupdatesrc=s' => \$driverupdatesrc, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, + 'ignorekernelchk' => \$ignorekernelchk, + ); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ($tempfile); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); +#$srcdir = $srcdir . "/1"; + +$srcdir_otherpkgs = "$installroot/post/otherpkgs/$osver/$arch" unless ($srcdir_otherpkgs); +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +if ($kernelver && (!$krpmver)) { + print "The -g flag for the rpm version of kernel packages needs to be specified when kernel version has been specified.\n"; + exit 1; +} +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +unless ($osver and $profile) { + usage(); + exit 1; +} +my @ndrivers; + +if ($netdriver) { + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + + # Do not include qeth module here + # This module is included later on + unless ( $_ =~ m/qeth/i ) { + push @ndrivers, $_; + } + } + + if ( ($updates{'netdrivers'} ne $netdriver) and $tempfile ) { + $updates{'netdrivers'} = $netdriver; + } +} + +# Add the default driver list +if ($arch eq 'x86' or $arch eq 'x86_64') { + push @ndrivers, qw/tg3 bnx2 bnx2x e1000 e1000e virtio_net virtio_balloon igb mlx_en be2net/; +} elsif ($arch eq 'ppc64') { + push @ndrivers, qw/tg3 e1000 e1000e igb ibmveth ehea be2net/; +} elsif ($arch eq "s390x") { + push @ndrivers, qw/qdio ccwgroup qeth qeth_l2 qeth_l3/; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +unless (grep /af_packet/,@ndrivers) { + unshift(@ndrivers,"af_packet.ko"); +} + +my $osver_host; +if(`grep VERSION /etc/SuSE-release` =~ /VERSION = (\d+)/) { + $osver_host=$1; +} else { + $osver_host=11; +} + +unless ($onlyinitrd) { + + # 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 ($tempfile and $otherpkglist); + } + my %extra_hash=(); + %extra_hash=imgutils::get_package_names($otherpkglist) if ($otherpkglist); + + + # prepare the chroot environment for the root image + + mkpath "$rootimg_dir/etc"; + mkpath "$rootimg_dir/dev"; + #system "mount -o bind /dev $rootimg_dir/dev"; + unless ( -e "$rootimg_dir/dev/zero") { + system "mknod $rootimg_dir/dev/zero c 1 5"; + } + unless ( -e "$rootimg_dir/dev/null") { + system "mknod $rootimg_dir/dev/null c 1 3"; #that's neccessary for SLES11 + } + + unless ( -e "$rootimg_dir/dev/random") { + system "mknod $rootimg_dir/dev/random c 1 8"; #that's neccessary for SLES11 + } + unless ( -e "$rootimg_dir/dev/urandom") { + system "mknod $rootimg_dir/dev/urandom c 1 9"; #that's neccessary for SLES11 + } + + for (my $i = 0; $i <= 12; $i++) + { + unless ( -e "$rootimg_dir/dev/tty$i") { + system "mknod $rootimg_dir/dev/tty$i c 4 $i"; #that's neccessary for SLES11 + } + } + + open($fd,">>","$rootimg_dir/etc/fstab"); # TODO: is it necessary? + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="--non-interactive --no-gpg-checks"; } + + if($osver_host == 11) {#zypper in SLES11 is different + + system("rm -rf $rootimg_dir/etc/zypp/repos.d/$osver-*.repo"); + my @pkgdirs = split(",", $srcdir); + my $dir; + my $i = 0; + # To support multiple paths for osimage.pkgdir + foreach $dir (@pkgdirs) { + if( -d "$dir/1") { + $dir .= "/1"; + } + system("zypper -R $rootimg_dir $non_interactive ar file:$dir $osver-$i"); + $i++; + } + + #if(-e "$rootimg_dir/etc/zypp/repos.d/$osver.repo") { + # system("rm -rf $rootimg_dir/etc/zypp/repos.d/$osver.repo"); + #} + #system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir $osver"); + #if(-e "$rootimg_dir/etc/zypp/repos.d/${osver}sdk.repo") { + # system("rm -rf $rootimg_dir/etc/zypp/repos.d/${osver}sdk.repo"); + #} + my $srcdir_sdk = "$installroot/$osver/$arch/sdk1"; + if ( -e "$srcdir_sdk") { + system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir_sdk ${osver}sdk"); + } + + }else { + $srcdir = $srcdir . "/1"; + system("zypper -R $rootimg_dir $non_interactive sa file:$srcdir"); + } + + # Add the rep for kernel packages + if ($kernelver) { + if (! -d $kerneldir) { + print "Cannot find the directory for the kernel at $kerneldir.\n"; + exit 1; + } + if ($osver_host == 11) { + if (-e "$rootimg_dir/etc/zypp/repos.d/$kernelver.repo") { + system("rm -rf $rootimg_dir/etc/zypp/repos.d/$kernelver.repo"); + } + system("zypper -R $rootimg_dir $non_interactive ar file:$kerneldir $kernelver"); + } else { + system("zypper -R $rootimg_dir $non_interactive sa file:$kerneldir"); + } + } + + #remove the old repository for extra packages + if ($osver_host == 11) { + my $result=`zypper -R $rootimg_dir $non_interactive lr |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive rr $result"); + } + } else { + my $result=`zypper -R $rootimg_dir $non_interactive sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive sd $result"); + } + } + + #add the new repository for extra packages + my %extrapkgnames; + if($osver_host == 11) { #SLES11 + if(-e "$rootimg_dir/etc/zypp/repos.d/otherpkg.repo") { + system("rm -rf $rootimg_dir/etc/zypp/repos.d/otherpkg.repo"); + } + } + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $whole_path="$srcdir_otherpkgs/$_"; + if (-r "$srcdir_otherpkgs/$_/repodata/repomd.xml") { + if($osver_host == 11) { + system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir_otherpkgs/$_ otherpkg$index"); + }else { + system("zypper -R $rootimg_dir $non_interactive sa file:$srcdir_otherpkgs/$_"); + } + } else { + if($osver_host == 11) { + system("zypper -R $rootimg_dir $non_interactive ar -t Plaindir file:$srcdir_otherpkgs/$_ otherpkg$index"); + }else { + system("zypper -R $rootimg_dir $non_interactive sa -t Plaindir file:$srcdir_otherpkgs/$_"); + } + } + $index++; + + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + + #-- 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 + # not sure, but it is convenient + my $repolist; + $repolist = imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "repolist"); + unless ($repolist) { + $repolist = imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "repolist"); + } + + if ( -r "$repolist") { + print "Reading custom repositories\n"; + open($repoconfig,"<","$repolist"); + while (<$repoconfig>) { + chomp; + next if /^\s*#/; + my ($repotype,$repourl,$repoalias) = split m/\|/; + if($osver_host == 11) { + system("zypper -R $rootimg_dir $non_interactive ar $repourl $repoalias"); + }else { + system("zypper -R $rootimg_dir $non_interactive sa $repourl $repoalias"); + } + } + } + + # Refresh the zypper cache in case there is still old data out there + system("zypper -R $rootimg_dir $non_interactive refresh"); + + #my $yumcmd = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir --disablerepo=* "; + #$yumcmd .= "install "; + #mkpath("$rootimg_dir/var/lib/yum"); + my $yumcmd; + if($osver =~ /sles11/ && $osver_host == 11) { + $yumcmd = "zypper -R $rootimg_dir $non_interactive install -l --no-recommends "; #add -l for SLES11 + }else { + $yumcmd = "zypper -R $rootimg_dir $non_interactive install "; + } + + #install packages from pkglist file + my $pkgnames; + 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"); } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + $pkgnames = ""; + $group_pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + # replace the kernel package with the name has the specific version + my @npa = (); + my @npa_group = (); + foreach my $p (@$pa) { + if ($p =~ /^kernel/ && $kernelver) { + # get all files in $srcdir and $kerneldir + my @alldirs = ("$srcdir", "$kerneldir"); + my @allrpms = (); + foreach my $dir (@alldirs) { + my @files = `find $dir -name *.rpm`; + push @allrpms, @files; + } + my @kernelpkgs = (); + if ($p =~ /^kernel$/) { + @kernelpkgs = ("kernel-default","kernel-default-base"); + } elsif ($p =~ /^kernel-ppc64$/) { + @kernelpkgs = ($p, $p."-base"); + } else { + @kernelpkgs = ($p); + } + foreach my $kern (@kernelpkgs) { + my @rpm = grep /$kern-$krpmver/, @allrpms; + if (!@rpm) { + print "Cannot find the kernel package with the versioin $krpmver.\n"; + exit 1; + } + my $kernelname = "$kern-".$krpmver; + push @npa, $kernelname; + } + } else { + if($p =~ s/^@//) + { + push @npa_group, $p; + } + else + { + push @npa, $p; + } + } + } + if (@npa) { + $pkgnames .= " " . join(' ', @npa); + } + if (@npa_group) { + $group_pkgnames .= " " . join(' ', @npa_group); + } + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$pkg_hash{$pass}{ENVLIST}}); + } + if($pkgnames) + { + print "$envlist $yumcmd $pkgnames\n"; + $rc = system("$envlist $yumcmd $pkgnames"); + $rc = $rc >> 8; + if (($rc) && ($rc != '104')) { + print "zypper invocation failed with rc: $rc\n"; + exit 1; + } + } + if($group_pkgnames) + { + print "$envlist $yumcmd -t pattern $group_pkgnames\n"; + $rc = system("$envlist $yumcmd -t pattern $group_pkgnames"); + $rc = $rc >> 8; + if (($rc) && ($rc != '104')) { + print "zypper invocation failed with rc: $rc\n"; + exit 1; + } + } + } + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + + my $index=1; + #remove the old repository for extra packages + if ($osver_host == 11) { + my $result=`zypper -R $rootimg_dir $non_interactive lr |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive rr $result"); + } + } else { + my $result=`zypper -R $rootimg_dir $non_interactive sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive sd $result"); + } + } + + foreach (keys(%{$extra_hash{$pass}})) { + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + if (-r "$srcdir_otherpkgs/$_/repodata/repomd.xml") { + if($osver_host == 11) { + system("zypper -R $rootimg_dir $non_interactive ar file:$srcdir_otherpkgs/$_ otherpkg$index"); + } else { + system("zypper -R $rootimg_dir $non_interactive sa file:$srcdir_otherpkgs/$_"); + } + } else { + if($osver_host == 11) { + system("zypper -R $rootimg_dir $non_interactive ar -t Plaindir file:$srcdir_otherpkgs/$_ otherpkg$index"); + }else { + system("zypper -R $rootimg_dir $non_interactive sa -t Plaindir file:$srcdir_otherpkgs/$_"); + } + } + $index++; + } + + # Refresh the zypper cache in case there is still old data out there + system("zypper -R $rootimg_dir $non_interactive refresh"); + + #remove the packages that are specified in the otherpkgs.list files with leading '-' + my $envlist; + if(exists $extra_hash{$pass}{ENVLIST}){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + + my $yumcmd_remove= "zypper -R $rootimg_dir $non_interactive remove "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $yumcmd_remove $rm_packges"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + + + #add extra packages in the list + if ($extrapkgnames{$pass}) { + print "$envlist $yumcmd $extrapkgnames{$pass}\n"; + $rc = system("$envlist $yumcmd $extrapkgnames{$pass}"); + $rc = $rc >> 8; + if (($rc) && ($rc != '104')) { + print "zypper invocation failed with rc: $rc\n"; + exit 1; + } + } + + #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) { + print "$envlist $yumcmd_remove $rm_packges"; + $rc = system("$envlist $yumcmd_remove $rm_packges"); + } + } + + # run zypper update to update any installed rpms + # needed when running genimage again after updating software in repositories + my $yumcmd_update; + if ($osver_host == 11) { + $yumcmd_update = "zypper -R $rootimg_dir $non_interactive update "; + } else { + $yumcmd_update = "zypper -R $rootimg_dir $non_interactive update "; + } + $rc = system("$yumcmd_update"); + } + + #remove the old repository for extra packages + if ($osver_host == 11) { + my $result=`zypper -R $rootimg_dir $non_interactive lr |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive rr $result"); + } + } else { + my $result=`zypper -R $rootimg_dir $non_interactive sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir $non_interactive sd $result"); + } + } + + # ignore any return code + + postscripts(); #run 'postscripts' +} +unlink "/tmp/genimage.$$.yum.conf"; + +# 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; + } + } + } + + @KVERS=<$rootimg_dir/lib/modules/*> unless (scalar @KVERS); + $basekernelver = basename(pop @KVERS) if (scalar @KVERS); + $basekernelver = `uname -r` unless ($basekernelver); +} + +$kernelver = $basekernelver unless ($kernelver); +chomp $kernelver; +#$updates{kernelver} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + copy("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + copy("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + copy("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie "couldn't find the kernel file matched $kernelver in $rootimg_dir/boot !"; +} + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + #print "postinstall_filename=$postinstall_filename\n"; + + #For Mellonax IB script. In diskless image, the uname -r not returning the rootimg level, + #because the "uname -r" only returns the version of the kernel in use + #create a temporary uname script. for every flag except for -r, it should just call the real + #uname with the same flags and return that info. + if(!( -e "$rootimg_dir/bin/orig_uname")) { + system("mv $rootimg_dir/bin/uname $rootimg_dir/bin/orig_uname"); + } + my $tmpuname; + open($tmpuname,">","$rootimg_dir/bin/uname"); + print $tmpuname <>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osdistroname'} = 'sles'; # not used currently + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts; +mkpath "$rootimg_dir/.sllocal/localmnt"; # create place for localdisk mount +mkpath "$rootimg_dir/.sllocal/log"; # create place for localdisk log + +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"); +system("cp $pathtofiles/../add-on/statelite/rc.localdisk $rootimg_dir/etc/init.d/localdisk"); + +# 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. +my $MFD; +open MFD, "/proc/mounts"; +my @lines = ; +close MFD; + +my $ret = grep m{$rootimg_dir/proc}, @lines; +if($ret > 0) { + system("umount -l $rootimg_dir/proc"); +} + +# 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 or driver rpm\n"; +} + +if (@new_order) { + @ndrivers = (@new_order, @ndrivers); +} + +# add drivers for local disk support +push @ndrivers, ("ext3.ko", "ext4.ko", "virtio_pci.ko", "virtio_blk.ko", "ata_piix.ko", "libata.ko", "scsi_mod.ko", "scsi_dh.ko", "ahci.ko", "ibmvscsi.ko", "ibmvscsic.ko", "megaraid_sas.ko", "pcieport.ko", "sd_mod.ko"); + +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+/,$_; + if ($driver =~ /libcrc32c.ko/) { + push @deps, 'crc32c.ko'; + } + my $dep; + foreach $dep (@deps) { + $dep =~ s/.*\///; + unless (grep { $_ eq $dep } @ndrivers) { #only add if not added + print "Added $dep as an autodetected depedency\n"; + } + unshift (@checkdeps,$dep); #recursively check dependencies + unshift (@ndrivers,$dep); + } + } +} +close($moddeps); + +#remove the duplicated drivers +my @fulldrivers; +foreach my $dn (@ndrivers) { + unless (grep {$_ eq $dn} @fulldrivers) { + push @fulldrivers, $dn; + } +} +@ndrivers = @fulldrivers; + +# 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"); + + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + if ($liblist =~ /not a dynamic executable/) { + return; + } + my @libs = split/\n/,$liblist; + my @return; + foreach (@libs) { + unless (/=>/) { + (my $wjnk, my $lib,my $jnk) = split /\s+/,$_,3; + $lib =~ s/^\///; + $libhash{$lib}=1; + next; + } + (my $temp1,my $temp2) = split />/,$_,2; + (my $whitespace,$temp1,$temp2) = split /\s+/,$temp2,4; + unless ($temp1 =~ /\//) { + next; + } + $temp1 =~ s/^\///; + $libhash{$temp1}=1; + } +} + +sub mkinitrd { + 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 + my @modlist = qw{sunrpc.ko lockd.ko nfs_acl.ko fscache.ko auth_rpcgss.ko exportfs.ko nfsd.ko nfs.ko}; + unshift(@ndrivers, @modlist); + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + 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"; + +# copied from genimage for rh +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + + +EOS1 + + print $inifile "mount -t proc /proc /proc\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + + print $inifile "mknod /dev/random c 1 8\n"; + print $inifile "mknod /dev/urandom c 1 9\n"; + 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"; + + # Install modules before starting udev + # because networking modules (qeth/qeth_l2/qeth_l3) are needed + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + # Start udev + print $inifile < /dev/null && export DEBUG=1\n"; + } + + print $inifile < /tmp/ifcfg-\$IFACE + +ip addr add dev lo 127.0.0.1/8 +ip link set lo up + + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + +if [ -z \$XCATIPORT ]; then + XCATIPORT="3002" +fi + +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +cd / +for i in `cat /proc/cmdline`; do + KEY=`echo \$i |awk -F= '{print \$1}'` + if [ "\$KEY" == 'imgurl' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + if [ "http" == "`echo \$VALUE|awk -F: '{print \$1}'`" ]; then + #NOTE needs FT retry code to scale + #NOTE: should prob have max count + FILENAME=`echo \$VALUE|awk -F/ '{print \$NF}'` + while [ ! -r "\$FILENAME" ]; do + echo Getting \$VALUE... + if ! wget \$VALUE; then + sleep 5 #should be random, exponential for scale + rm -f \$FILENAME + fi + done + fi + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ]; then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + elif [ "\$KEY" == 'NODE' ]; then + NODENAME=`echo \$i |awk -F= '{print \$2}'` + fi +done + +# show xCAT logo +fancydisplay + +# Statelite code is here +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=15 + ITER=0 + ME=`hostname` + if [ ! -z "$NODENAME" ]; then + ME=$NODENAME + fi + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" = "\$MAXTRIES" ]; then + echo "You're dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wan't created for the statelite node? +2. IS DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this initial ramdisk?" + shell + exit + fi + echo -e "\${RED}Couldn't mount \$SERVER:\$ROOTDIR on \$NEWROOT \$RESET" + RS=\$(expr \$RANDOM % 30) + echo -e "Trying again in \$RS seconds" + sleep \$RS + done + else + # for statelite mode on top of the ramdisk +EOMS + + print $inifile "if [ -r /rootimg-statelite.gz ]; then \n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o size=$rootlimit,mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT \n"; + } + + print $inifile </dev/null && shell + mount -t tmpfs rw -o mode=$permission \$NEWROOT/\$RWDIR + mkdir -p \$NEWROOT/\$RWDIR/tmpfs + + #mount the /root/.ssh, it needs more strict permission in order for ssh work + #if [ ! -e "\$NEWROOT/root/.ssh" ] + #then + # mkdir -p \$NEWROOT/root/.ssh + #fi + #mount -t tmpfs -o mode=755 ssh \$NEWROOT/root/.ssh + + # mount the SNAPSHOT directory here for persistent use. + if [ ! -z \$SNAPSHOTSERVER ] + then + mkdir -p \$NEWROOT/\$RWDIR/persistent + MAXTRIES=5 + ITER=0 + while ! mount \$SNAPSHOTSERVER:\$SNAPSHOTROOT \$NEWROOT/\$RWDIR/persistent -o nolock,\$XCATMNTOPTS + 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} \$XCATMNTOPTS" + RS=`expr \$RANDOM % 20` + echo -e "Trying again in \$RS seconds" + sleep \$RS + done + + # create directory which is named after my node name + mkdir -p \$NEWROOT/\$RWDIR/persistent/\$ME + ITER=0 + # umount current persistent mount + while ! umount -l \$NEWROOT/\$RWDIR/persistent; do + ITER=\$(( ITER + 1 )) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "Your are dead, rpower \$ME boot to play again." + echo "Cannot umount \$NEWROOT/\$RWDIR/persistent." + /bin/sh + exit + fi + RS= \$(( \$RANDOM % 20 )) + echo "Trying again in \$RS seconds..." + sleep \$RS + done + + # mount persistent to server:/rootpath/nodename + ITER=0 + while ! mount \$SNAPSHOTSERVER:/\$SNAPSHOTROOT/\$ME \$NEWROOT/\$RWDIR/persistent -o nolock,\$XCATMNTOPTS; do + ITER=\$(( ITER + 1 )) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "Your are dead, rpower \$ME boot to play again." + echo "Possible problems: cannot mount to \$SNAPSHOTSERVER:/\$SNAPSHOTROOT/\$ME." + /bin/sh + exit + fi + RS= \$(( \$RANDOM % 20 )) + echo "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-\$IFACE.info \${NEWROOT}/\${RWDIR}/tmpfs/var/lib/dhcpcd/dhcpcd-\$IFACE.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. + while [ ! -e \$NEWROOT/etc/init.d/statelite ] + do + echo "\$NEWROOT/etc/init.d/statelite does not exist in image!" + shell + done + + # try to configure the local disk + \$NEWROOT/etc/init.d/localdisk + + # do all the mounts: + \$NEWROOT/etc/init.d/statelite +EOMS + + # udevd needed by s390x for networking + # but for other type of machine, udevd will affect the start of devices which detected + # after the chroot, so kill it before the switching root + if ($arch ne "s390x") { + print $inifile "\n killall -9 udevd\n"; + } + + print $inifile < /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 + +if [ -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,mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\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 <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/bin/bash \n"; + if ($osver_host == 10) { + print $inifile "dhcpcd \${1}\n"; + } else { # for sles11 or higher + # -p is used to keep the network connection during the shutdown. Used for nfs-based statelite shutdown + print $inifile "dhcpcd \${1} -p\n"; + } + + #-- Bring other NICs up in /bin/netstart in initrd for NIC failover + foreach (split /,/,$othernics) { + if (/^$/) { next; } + print $inifile "dhcpcd $_\n"; + } + + print $inifile <> /etc/HOSTNAME +END + + close($inifile); + + #if "nonodestatus" specified,do not update the nodestatus + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile <); + my $pathonrootimage = "$rootimg_dir/tmpfiles"; + my $pathinrootimage = "/tmpfiles"; + mkpath($pathonrootimage); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcfile = $_->[0]; + system("chroot $rootimg_dir cp $srcfile $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_->[0]); + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + system("chroot $rootimg_dir cp $_ $pathinrootimage"); + my $srcpath = "$pathonrootimage/".basename($_); + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + rmtree($pathonrootimage); + + #copy conf files needed by nfs mount in sles11.2 + if($osver_host == 11) + { + system("cp -r $rootimg_dir/etc/protocols /tmp/xcatinitrd.$$/etc/"); + system("cp -r $rootimg_dir/etc/netconfig /tmp/xcatinitrd.$$/etc/"); + } + + + # Copy udev libraries + system("mkdir -p /tmp/xcatinitrd.$$/etc/udev"); + system("mkdir -p /tmp/xcatinitrd.$$/lib/firmware"); + system("cp -r $rootimg_dir/etc/udev/* /tmp/xcatinitrd.$$/etc/udev"); + system("cp -r $rootimg_dir/bin/uname /tmp/xcatinitrd.$$/bin/"); + if ( -d "$rootimg_dir/lib/firmware/" ) { + system("cp -r $rootimg_dir/lib/firmware/* /tmp/xcatinitrd.$$/lib/firmware"); + } + system("cp -r $rootimg_dir/usr/bin/killall /tmp/xcatinitrd.$$/usr/bin"); + + # 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 = $&; + #} + + # Somehow checking for *$nic.rules does not work + #if ( -f "/etc/udev/rules.d/*$nic.rules" ) { + # system("cp -r /etc/udev/rules.d/*$nic.rules /tmp/xcatinitrd.$$/etc/udev/rules.d"); + #} + #if ( -f "/etc/udev/rules.d/*persistent-net.rules" ) { + # system("cp -r /etc/udev/rules.d/*persistent-net.rules /tmp/xcatinitrd.$$/etc/udev/rules.d"); + #} + + system("mkdir -p /tmp/xcatinitrd.$$/lib/udev"); + system("cp -r $rootimg_dir/lib/udev/* /tmp/xcatinitrd.$$/lib/udev"); + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$/bin/; ln -sf bash sh"); #neccessary for SLES11 + 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 stateless has been generated successfully!\n"; + } + 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; + $filetoadd =~ s!$rootimg_dir!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + print "Added driver $_ to initrd\n"; + } + } +} + + + + + + + +sub postscripts { # TODO: customized postscripts + generic_post(); + unless( -d "$rootimg_dir/opt/xcat/") { + mkdir "$rootimg_dir/opt/xcat/"; + } + copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/"); #TODO: it is not used in stateless + chmod '0755', "$rootimg_dir/opt/xcat/xcatdsklspost"; +} + +sub generic_post { # This function is meant to leave the image in a state approximating a normal install + my $cfgfile; + + #modify /etc/sysconfig/clock in the image:HWCLOCK="--local", TIMEZONE=site:timezone + if ($timezone) { + system("sed -i '".'s!\(TIMEZONE=\).*!\1'."\"$timezone\"!"."' $rootimg_dir/etc/sysconfig/clock"); + system("chroot $rootimg_dir zic -l $timezone"); + } + + system("sed -i 's!\\(HWCLOCK=\\).*!\\1\"--localtime\"!' $rootimg_dir/etc/sysconfig/clock"); + + 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); + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\nSTARTMODE=auto\n"; + close($cfgfile); + } + + foreach (split /,/,$othernics) { + next if (/^$/); + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\nSTARTMODE=auto\n"; + close($cfgfile); + } + + # 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); + } + + 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/"; + } + + # 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 "VERS=`grep VERSION /etc/SuSE-release`\n"; + print $cfgfile "if [ -n \"\$VERS\" ]; then\n"; + print $cfgfile " VERNUM=`echo \$VERS|awk -F= \'{print \$2}\'|sed -e \'s/ //g\'`\n"; + print $cfgfile "fi\n"; + print $cfgfile "if [ \"\$VERNUM\" -gt 10 ]; then\n"; + print $cfgfile " exit\n"; + print $cfgfile "fi\n"; + print $cfgfile "\n"; + 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" ); + } + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + #insserv with -f option to ignore the dependency on sles10.4 + system("chroot $rootimg_dir insserv -f network sshd gettyset xcatpostinit"); + + my $rc = system("grep sshd $rootimg_dir/etc/init.d/.depend.start | grep TARGETS"); + 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 | grep TARGETS"); + 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"); + } +} + + +my $driver_name; +my $real_path; +sub get_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + $real_path = $File::Find::name; + } +} + +my @all_real_path; +sub get_all_path () +{ + if ($File::Find::name =~ /\/$driver_name/) { + push @all_real_path, $File::Find::name; + } +} + +# Load driver disk and driver rpm to the initrd +# Get the driver disk or driver rpm from the osimage.driverupdatesrc +# The valid value: dud:/install/dud/dd.img,rpm:/install/rpm/d.rpm, if missing the tag: 'dud'/'rpm' +# the 'rpm' is default. +# +# If cannot find the driver disk from osimage.driverupdatesrc, will try to search driver disk +# from /install/driverdisk// +# +# For driver rpm, the driver list will be gotten from osimage.netdrivers. If not set, copy all the drivers from driver +# rpm to the initrd. +# +# Return the driver names by loading order + +sub load_dd() +{ + my @dd_list; + my @rpm_list; + my @driver_list; + + my $Injectalldriver; + my @rpm_drivers; + + # Parse the parameters to the the source of Driver update disk and Driver rpm, and driver list as well + if ($driverupdatesrc) { + my @srcs = split(',', $driverupdatesrc); + foreach my $src (@srcs) { + if ($src =~ /dud:(.*)/i) { + push @dd_list, $1; + } elsif ($src =~ /rpm:(.*)/i) { + push @rpm_list, $1; + } else { + push @rpm_list, $src; + } + } + } + if (! @dd_list) { + # get Driver update disk from the default path if not specified in osimage + # check the Driver Update Disk images, it can be .img or .iso + if (-d "$installroot/driverdisk/$osver/$arch") { + @dd_list = `find $installroot/driverdisk/$osver/$arch -type f`; + } + } + + foreach (split /,/,$netdriver) { + if (/^allupdate$/) { + $Injectalldriver = 1; + next; + } + unless (/\.ko$/) { + s/$/.ko/; + } + push @driver_list, $_; + } + + chomp(@dd_list); + chomp(@rpm_list); + + unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) { + return (); + } + + # Create the work space, it should be cleaned at end of genimage + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #driver 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: /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 = ) { + 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; + } + } + + # Loading the drivers from rpm packages + if (@rpm_list && ($Injectalldriver || @driver_list)) { + # Extract the files from rpm to the tmp dir + mkpath "$dd_dir/rpm"; + foreach my $rpm (@rpm_list) { + if (-r $rpm) { + if (system ("cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum")) { + print "Error: Cannot extract the files from the rpm $rpm.\n"; + } + } else { + print "Error: Cannot read the rpm $rpm.\n"; + } + } + + # To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver + # Change it back to xxx.ko here + $driver_name = "\*ko.new"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/*>); + foreach my $file (@all_real_path) { + my $newname = $file; + $newname =~ s/\.new$//; + if (system ("mv -f $file $newname")) { + print "Error: Could not rename $file\n"; + + } + } + + # Copy the firmware to the rootimage + if (-d "$dd_dir/rpm/lib/firmware") { + system ("cp -rf $dd_dir/rpm/lib/firmware $rootimg_dir/lib"); + } + + # if $ignorekernelchk is specified, copy all driver files to target kernel dir + if ($ignorekernelchk) { + my @kernelpath4vrpm = <$dd_dir/rpm/lib/modules/*>; + foreach my $path (@kernelpath4vrpm) { + if ($path eq "$dd_dir/rpm/lib/modules/$kernelver") { + next; + } + + unless (-d "$dd_dir/rpm/lib/modules/$kernelver") { + mkpath "$dd_dir/rpm/lib/modules/$kernelver"; + } + system ("/bin/cp -rf $path/* $dd_dir/rpm/lib/modules/$kernelver"); + } + } + + # Copy the drivers to the rootimage + if (-d "$dd_dir/rpm/lib/modules/$kernelver") { + #mkpath "$rootimg_dir/lib/modules/$kernelver/updates/"; + if (@driver_list) { + foreach my $driver (@driver_list) { + $driver_name = $driver; + $real_path = ""; + find(\&get_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) { + # remove the old one if existing + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@all_real_path) { + if (-r $_) { + unlink ($_); + } + } + + if (! -d "$rootimg_dir$1") { + mkpath "$rootimg_dir$1"; + } + system ("cp -rf $real_path $rootimg_dir$1"); + push @rpm_drivers, $driver; + } else { + print "Warning: cannot find the driver $driver from the driver rpms\n"; + } + } + } elsif ($Injectalldriver) { + # copy all the drviers to the rootimage + $driver_name = "\*\.ko"; + @all_real_path = (); + find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>); + my @all_drivers = @all_real_path; + foreach my $new_driver (@all_drivers) { + if (basename($new_driver) =~ /\.ko$/) { + # remove the old one if existing + $driver_name = basename($new_driver); + @all_real_path = (); + find(\&get_all_path, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach my $old_driver (@all_real_path) { + if (-r $old_driver) { + unlink ($old_driver); + } + } + push @rpm_drivers, basename($new_driver); + } + } + + system ("cp -rf $dd_dir/rpm/lib/modules/$kernelver $rootimg_dir/lib/modules/"); + } + } else { + print "Warning: cannot find the kernel $kernelver from drvier rpms\n"; + } + + push @dd_drivers, @rpm_drivers; + } + + # Generate the dependency relationship + system ("chroot '$rootimg_dir' depmod $kernelver"); + + # Clean the env + rmtree "$dd_dir"; + + return @dd_drivers; +} + +sub usage { + print 'Usage: genimage -o [-a ] -p -i -n [-r ] [-k ] [-g ] [-l rootlimitsize] [--permission ] [--interactive]'."\n"; + print " --permission is used for statelite only\n"; + print "Examples:\n"; + 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 --interactive\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"; + return 0; +} diff --git a/xCAT-server/share/xcat/netboot/suse/geninitrd b/xCAT-server/share/xcat/netboot/suse/geninitrd deleted file mode 120000 index 2271c3f0f..000000000 --- a/xCAT-server/share/xcat/netboot/suse/geninitrd +++ /dev/null @@ -1 +0,0 @@ -genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/suse/geninitrd b/xCAT-server/share/xcat/netboot/suse/geninitrd new file mode 100755 index 000000000..01c55a785 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/suse/geninitrd @@ -0,0 +1,892 @@ +#!/usr/bin/env perl +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +#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; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kernelver = ""; #`uname -r`; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + die @_; +} + +#-- 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); +# } +# } + + +$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, + 'k=s' => \$kernelver, + 'onlyinitrd' =>\$onlyinitrd, +); +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'}; +} + +if (!$arch) { + $arch = `uname -m`; + 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"; + +#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 +my @KVERS= <$rootimg_dir/lib/modules/*>; +if (scalar(@KVERS)) { + $basekernelver = basename($KVERS[0]); +} +unless ($basekernelver) { + $basekernelver = `uname -r`; +} +unless ($kernelver) { + $kernelver=$basekernelver; +} +chomp($kernelver); +unless ($osver and $profile and $netdriver and $prinic) { + print 'Usage: genimage -i -n [-r ] -k -o -p -a '."\n"; + print ' genimage -i -n [-r ] -k '."\n"; + 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"; + print " genimage -i eth0 -ntg3 myimagename\n"; + exit 1; +} +my @ndrivers; +foreach (split /,/,$netdriver) { + unless (/\.ko$/) { + s/$/.ko/; + } + if (/^$/) { + next; + } + push @ndrivers,$_; +} +unless (grep /af_packet/,@ndrivers) { + unshift(@ndrivers,"af_packet.ko"); +} + +my $osver_host; +if(`grep VERSION /etc/SuSE-release` =~ /VERSION = (\d+)/) { + $osver_host=$1; +} else { + $osver_host=11; +} + +unless ($onlyinitrd) { + my %extra_hash=get_extra_package_names(); + + + mkpath "$rootimg_dir/etc"; + mkpath "$rootimg_dir/dev"; + #system "mount -o bind /dev $rootimg_dir/dev"; + system "mknod $rootimg_dir/dev/zero c 1 5"; + system "mknod $rootimg_dir/dev/null c 1 3"; #that's neccessary for SLES11 + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for rpm postscripts to see\n"; + close($fd); + if($osver_host == 11) {#zypper in SLES11 is different + 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 { + system("zypper -R $rootimg_dir sa file:$srcdir"); + } + + #remove the old repository for extra packages + my $result=`zypper -R $rootimg_dir sl |grep otherpkg|cut -f2 -d '|'|tr "\n" " "`; + if ($result =~ /\S/) { + system("zypper -R $rootimg_dir sd $result"); + } + + #add the new repository for extra packages + my $extrapkgnames; + if($osver_host == 11) { #SLES11 + if(-e "$rootimg_dir/etc/zypp/repos.d/otherpkg.repo") { + system("rm -rf $rootimg_dir/etc/zypp/repos.d/otherpkg.repo"); + } + } + my $index=1; + foreach (keys(%extra_hash)) { + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE")) { next;} + my $whole_path="$srcdir_otherpkgs/$_"; + if (-r "$srcdir_otherpkgs/$_/repodata/repomd.xml") { + if($osver_host == 11) { + system("zypper -R $rootimg_dir ar file:$srcdir_otherpkgs/$_ otherpkg$index"); + }else { + system("zypper -R $rootimg_dir sa file:$srcdir_otherpkgs/$_"); + } + } else { + if($osver_host == 11) { + system("zypper -R $rootimg_dir ar -t Plaindir file:$srcdir_otherpkgs/$_ otherpkg$index"); + }else { + system("zypper -R $rootimg_dir sa -t Plaindir file:$srcdir_otherpkgs/$_"); + } + } + $index++; + + my $pa=$extra_hash{$_}; + $extrapkgnames .= " " . join(' ', @$pa); + } + + #-- add custom repositories to the image + my $repolist; + if ( -r "$pathtofiles/$profile.$osver.$arch.repolist") { + $repolist = "$pathtofiles/$profile.$osver.$arch.repolist"; + }elsif ( -r "$pathtofiles/$profile.$osver.repolist") { + $repolist = "$pathtofiles/$profile.$osver.repolist"; + }elsif ( -r "$pathtofiles/$profile.repolist") { + $repolist = "$pathtofiles/$profile.repolist"; + } + + if ( -r "$repolist") { + print "Reading custom repositories\n"; + open($repoconfig,"<","$repolist"); + while (<$repoconfig>) { + chomp; + next if /^\s*#/; + my ($repotype,$repourl,$repoalias) = split m/\|/; + system("zypper -R $rootimg_dir ar $repourl $repoalias"); + } + } + + + # Refresh the zypper cache in case there is still old data out there + system("zypper -R $rootimg_dir refresh"); + + #my $yumcmd = "yum -y -c /tmp/genimage.$$.yum.conf --installroot=$rootimg_dir --disablerepo=* "; + #$yumcmd .= "install "; + #mkpath("$rootimg_dir/var/lib/yum"); + my $yumcmd; + if($osver =~ /suse11/ && $osver_host == 11) { + $yumcmd = "zypper -R $rootimg_dir install -l "; #add -l for SLES11 + }else { + $yumcmd = "zypper -R $rootimg_dir install "; + } + if (!$imagename) { + $pkglist= get_pkglist_file_name($customdir); + if (!$pkglist) { + $pkglist= get_pkglist_file_name($pathtofiles); + } + } + #print "pkglist=$pkglist\n"; + + if (!$pkglist) { + print "Unable to find package list for $profile!"; + exit 1; + } + + my $pkgnames; + open($yumconfig,"<","$pkglist"); + while (<$yumconfig>) { + chomp; + s/\s*#.*//; #-- remove comments + next if /^\s*$/; #-- skip empty lines + $pkgnames .= $_ . " "; + } + close($yumconfig); + + + #$yumcmd =~ s/ $/\n/; + #print "$yumcmd $pkgnames\n"; + my $rc = system("$yumcmd $pkgnames"); + if ($rc) { + print "zypper invocation failed\n"; + exit 1; + } + + #remove the packages that are specified in the otherpkgs.list files with leading '-' + my $yumcmd_remove= "zypper -R $rootimg_dir remove "; + if ((%extra_hash) && (exists ($extra_hash{'PRE_REMOVE'}))) { + my $pa=$extra_hash{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + $rc = system("$yumcmd_remove $rm_packges"); + } + } + + #add extra packages in the list + if ($extrapkgnames) { + #print "$yumcmd $extrapkgnames\n"; + $rc = system("$yumcmd $extrapkgnames"); + if ($rc) { + print "zypper invocation failed\n"; + exit 1; + } + } + + #remove the packages that are specified in the otherpkgs.list files with leading '--' + if ((%extra_hash) && (exists ($extra_hash{'POST_REMOVE'}))) { + my $pa=$extra_hash{'POST_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + $rc = system("$yumcmd_remove $rm_packges"); + } + + # 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 + + + postscripts(); #run 'postscripts' +} +unlink "/tmp/genimage.$$.yum.conf"; + +#-- run postinstall script +if (!$imagename) { + $postinstall_filename= get_postinstall_file_name($customdir); + if (!$postinstall_filename) { + $postinstall_filename= get_postinstall_file_name($pathtofiles); + } +} + +if ( $postinstall_filename ) { + + my @postinstalls = split /,/, $postinstall_filename; + foreach my $postinstall ( split /,/, $postinstall_filename ) { + if ( !-x $postinstall ) { + print "postinstall script $postinstall is not executable\n"; + exit 1; + } + my $rc = system($postinstall, $rootimg_dir,$osver,$arch,$profile); + if($rc) { + print "postinstall script $postinstall failed\n"; + exit 1; + } + } +} + +#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. +my $MTABFD; +open MTABFD, "/etc/mtab"; +my @lines = ; +close MTABFD; + +my $ret = grep m{$rootimg_dir/proc}, @lines; +if($ret > 0) { + system("umount $rootimg_dir/proc"); +} + +mkinitrd(); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + 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 { + mkpath("/tmp/xcatinitrd.$$/bin"); + if($basekernelver eq $kernelver) { + if (-f "$rootimg_dir/boot/vmlinuz-$kernelver") { + rename(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); + } elsif (-f "$rootimg_dir/boot/vmlinux-$kernelver"){ + rename(<$rootimg_dir/boot/vmlinux*>,"$destdir/kernel"); + } + } + else { + if(-r "$rootimg_dir/boot/vmlinuz-$kernelver") { + rename("$rootimg_dir/boot/vmlinuz-$kernelver","$destdir/kernel"); + } elsif(-r "$rootimg_dir/boot/vmlinux-$kernelver") { + rename("$rootimg_dir/boot/vmlinux-$kernelver","$destdir/kernel"); + } elsif(-r "/boot/vmlinuz-$kernelver") { + copy("/boot/vmlinuz-$kernelver","$destdir/kernel"); + } elsif(-r "/boot/vmlinux-$kernelver") {#for SLES10,11 + copy("/boot/vmlinux-$kernelver","$destdir/kernel"); + } + else { + xdie("Cannot read /boot/vmlinuz-$kernelver"); + } + } + 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 + mkpath("/tmp/xcatinitrd.$$/lib64/power6"); + } + mkpath("/tmp/xcatinitrd.$$/lib/power6");#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 -x\n"; + print $inifile "mount -t proc /proc /proc\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + 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"; + + print $inifile "mknod /dev/random c 1 8\n"; + print $inifile "mknod /dev/urandom c 1 9\n"; + 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"; + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/bin/bash\n"; + print $inifile "dhcpcd $prinic\n"; + + #-- Bring other NICs up in /bin/netstart in initrd for NIC failover + foreach (split /,/,$othernics) { + if (/^$/) { next; } + print $inifile "dhcpcd $_\n"; + } + + print $inifile <> /etc/resolv.conf +cat /var/lib/dhcpcd/*info | grep HOSTNAME | uniq | awk -F= '{print \$2}'| sed \"s/'//g\" >> /etc/HOSTNAME +for names in \$(cat /var/lib/dhcpcd/*info | grep DNS | uniq | awk -F= '{print \$2}' | sed 's/,/\\n/'); do + echo nameserver \$names >> /etc/resolv.conf +done +END + + close($inifile); + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + foreach ("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") { + getlibs($_); #there's one small bug for getlibs + push @filestoadd,$_; + } + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + } + else { + push @filestoadd,"lib/libnss_dns.so.2"; + } + push @filestoadd,keys %libhash; + if($basekernelver ne $kernelver) { + system("rm -rf $rootimg_dir/lib/modules/$basekernelver"); + unless (-d "$rootimg_dir/lib/modules/$kernelver") { + if(-d "/lib/modules/$kernelver") { + system("cd /lib/modules;cp -r $kernelver $rootimg_dir/lib/modules/"); + } + else { + xdie("Cannot read /lib/modules/$kernelver"); + } + } + } + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcpath = "$rootimg_dir/".$_->[0]; + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + my $srcpath = "$rootimg_dir/$_"; + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$/bin/; ln -sf bash sh"); #neccessary for SLES11 + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd.gz"); + 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; + $filetoadd =~ s!$rootimg_dir!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + } + } +} + + + + + + + +sub postscripts { # TODO: customized postscripts + generic_post(); + if (-d "$installroot/postscripts/hostkeys") { + for my $key (<$installroot/postscripts/hostkeys/*key>) { + copy ($key,"$rootimg_dir/etc/ssh/"); + } + chmod 0600,; + } + if (-d "/$installroot/postscripts/.ssh") { + mkpath("$rootimg_dir/root/.ssh"); + chmod(0700,"$rootimg_dir/root/.ssh/"); + for my $file () { + copy ($file,"$rootimg_dir/root/.ssh/"); + } + chmod(0600,); + } + +} + +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 0 0\n"; + print $cfgfile "tmpfs /var/tmp tmpfs defaults 0 0\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); + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$prinic"); + print $cfgfile "ONBOOT=no\nBOOTPROTO=dhcp\nDEVICE=$prinic\n"; + close($cfgfile); + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">","$rootimg_dir/etc/sysconfig/network-scripts/ifcfg-$_"); + print $cfgfile "ONBOOT=yes\nBOOTPROTO=dhcp\nDEVICE=$_\n"; + close($cfgfile); + } + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + print $cfgfile "console\n"; + close($cfgfile); + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + open($cfgfile,">","$rootimg_dir/etc/init.d/gettyset"); + print $cfgfile "#!/bin/bash\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"; + print $cfgfile "/opt/xcat/xcatdsklspost\n"; + close($cfgfile); + chmod(0755,"$rootimg_dir/etc/init.d/gettyset"); + #link("$rootimg_dir/sbin/init","$rootimg_dir/init"); + 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"); + } + if(($osver =~ /sles11/) || ($osver =~ /suse11/) || ($osver =~ /sles10/)) {#for sles11,sles10,suse11 + rename(<$rootimg_dir/boot/vmlinux*>,"$destdir/kernel"); + }else { + rename(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); + } +} + +sub get_extra_pkglist_file_name { + my $base=shift; + if (-r "$base/$profile.$osver.$arch.otherpkgs.pkglist") { + return "$base/$profile.$osver.$arch.otherpkgs.pkglist"; + } elsif (-r "$base/$profile.$arch.otherpkgs.pkglist") { + return "$base/$profile.$arch.otherpkgs.pkglist"; + } elsif (-r "$base/$profile.$osver.otherpkgs.pkglist") { + return "$base/$profile.$osver.otherpkgs.pkglist"; + } elsif (-r "$base/$profile.otherpkgs.pkglist") { + return "$base/$profile.otherpkgs.pkglist"; + } + return ""; +} + +sub get_pkglist_file_name { + my $base=shift; + if (-r "$base/$profile.$osver.$arch.pkglist") { + return "$base/$profile.$osver.$arch.pkglist"; + } elsif (-r "$base/$profile.$arch.pkglist") { + return "$base/$profile.$arch.pkglist"; + } elsif (-r "$base/$profile.$osver.pkglist") { + return "$base/$profile.$osver.pkglist"; + } elsif (-r "$base/$profile.pkglist") { + return "$base/$profile.pkglist"; + } + + return ""; +} + + +sub get_postinstall_file_name { + my $base=shift; + if (-x "$base/$profile.$osver.$arch.postinstall") { + return "$base/$profile.$osver.$arch.postinstall"; + } elsif (-x "$base/$profile.$arch.postinstall") { + return "$base/$profile.$arch.postinstall"; + } elsif (-x "$base/$profile.$osver.postinstall") { + return "$base/$profile.$osver.postinstall"; + } elsif (-x "$base/$profile.postinstall") { + return "$base/$profile.postinstall"; + } + + return ""; +} + + diff --git a/xCAT-server/share/xcat/netboot/ubuntu/geninitrd b/xCAT-server/share/xcat/netboot/ubuntu/geninitrd deleted file mode 120000 index 2271c3f0f..000000000 --- a/xCAT-server/share/xcat/netboot/ubuntu/geninitrd +++ /dev/null @@ -1 +0,0 @@ -genimage \ No newline at end of file diff --git a/xCAT-server/share/xcat/netboot/ubuntu/geninitrd b/xCAT-server/share/xcat/netboot/ubuntu/geninitrd new file mode 100755 index 000000000..204b3fc86 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ubuntu/geninitrd @@ -0,0 +1,1773 @@ +#!/usr/bin/env perl +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; + +use File::Basename; +use File::Path; +use File::Copy qw/copy cp mv move/; +use File::Find; +use Getopt::Long; +use Cwd qw(realpath); +use xCAT::Utils; +use xCAT::TableUtils; +use File::Temp qw/mkdtemp/; + +use FindBin; +use lib "$FindBin::Bin/../imgutils"; +use imgutils; + +#use strict; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $dracutmode; #Indicate whether this is a dracut style initrd +my $dracutdir = "dracut"; # The default directory name of dracut +my $prinic; #TODO be flexible on node primary nic +my $othernics; #TODO be flexible on node primary nic +my $netdriver; +my @yumdirs; +my $arch; +my %libhash; +my @filestoadd; +my $profile; +my $osver; +my $pathtofiles=dirname($0); +my $fullpath=realpath($pathtofiles); +my $name = basename($0); +my $onlyinitrd=0; +#that this method of calling genimage is no longer used +if ($name =~ /geninitrd/) { + $onlyinitrd=1; +} +my $rootlimit; +my $tmplimit; +my $installroot = "/install"; +my $kerneldir; +my $kernelver = ""; #`uname -r`; +my $basekernelver; # = $kernelver; +my $customdir=$fullpath; +$customdir =~ s/.*share\/xcat/$installroot\/custom/; +my $imagename; +my $pkglist; +my $srcdir; +my $destdir; +my $srcdir_otherpkgs; +my $otherpkgsdir_local; +my $otherpkgsdir_internet; +my $otherpkglist; +my $postinstall_filename; +my $rootimg_dir; +my $permission; # the permission works only for statelite mode currently +my $tempfile; +my $prompt; + + +sub xdie { + system("rm -rf /tmp/xcatinitrd.$$"); + umount_chroot($rootimg_dir); + die @_; +} + +$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, + 'k=s' => \$kernelver, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'tempfile=s' =>\$tempfile, #internal flag + 'pkglist=s' => \$pkglist, #internal flag + 'srcdir=s' => \$srcdir, #internal flag + 'otherpkgdir=s' => \$srcdir_otherpkgs, #internal flag + 'otherpkglist=s' => \$otherpkglist, #internal flag + 'postinstall=s' => \$postinstall_filename, #internal flag + 'rootimgdir=s' => \$destdir, #internal flag + 'interactive' =>\$prompt, + 'onlyinitrd' =>\$onlyinitrd, +); + +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + + +my %updates_os = (); # the hash for updating osimage table +my %updates = (); # the hash for updating linuximage table + + +$permission = "755" unless ($permission); +$updates{'permission'} = $permission if ( $tempfile ); + +unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); +} + +$srcdir="$installroot/$osver/$arch" unless ($srcdir); +$updates{'pkgdir'} = $srcdir if ($tempfile); + +if ($srcdir_otherpkgs){ + my @tempdirarray = split /,/, $srcdir_otherpkgs; + foreach my $tempdir (@tempdirarray){ + if ($tempdir =~ /^http.*/){ + $otherpkgsdir_internet .= "deb " . $tempdir . "\n"; + } + else{ + $otherpkgsdir_local = $tempdir; + } + } +} +$updates{'otherpkgdir'} = $srcdir_otherpkgs if ($tempfile); + +$destdir="$installroot/netboot/$osver/$arch/$profile" unless ($destdir); +$updates{'rootimgdir'} = $destdir if ($tempfile); + +$rootimg_dir="$destdir/rootimg"; + +$kerneldir = "$installroot/kernels" unless ($kerneldir); # the default directory for 3rd-party kernel is "$installroot/kernels"; +#$updates{'kerneldir'} = $kerneldir if ($tempfile); + +# Get the subchannels of the given interface +my $subchn; +my $readChn; +my @chn; +if ($arch eq "s390x") { + $subchn = `cat /etc/sysconfig/network-scripts/ifcfg-$prinic | grep "SUBCHANNELS"`; + + if (!$subchn) { + print "SUBCHANNELS need to be given in /etc/sysconfig/network-scripts/ifcfg-$prinic"; + exit 1; + } else { + # Trim right + $subchn =~ s/\s*$//; + + # Trim left + $subchn =~ s/^\s*//; + + # Extract subchannels + $subchn =~ s/SUBCHANNELS=//g; + + # Extract read channel + @chn = split( ",", $subchn ); + $readChn = @chn[0]; + } +} + +unless ($osver and $profile) { + usage(); + exit 1; +} + +my @ndrivers; +if ($netdriver) { + if ( ($updates{'netdrivers'} ne $netdriver) and ($tempfile) ) { + $updates{'netdrivers'} = $netdriver; + } +} else { + if ($arch eq 'x86' or $arch eq 'x86_64') { + @ndrivers = qw/tg3 bnx2 bnx2x e1000 e1000e igb mlx_en virtio_net/; + } elsif ($arch eq 'ppc64el') { + @ndrivers = qw/bnx2 bnx2x e1000 e1000e igb/; + } elsif ($arch eq 'ppc64') { + @ndrivers = qw/e1000 e1000e igb ibmveth ehea/; + } elsif ($arch eq 's390x') { + @ndrivers = qw/qdio ccwgroup/; + } +} +foreach (split /,/,$netdriver) { + unless (/\.ko$/) { + s/$/.ko/; + } + next if (/^$/); + push @ndrivers, $_; +} + +foreach (@ndrivers) { + unless (/\.ko$/) { + s/$/.ko/; + } +} + +my $uarch=$arch; +$uarch="amd64" if ($arch eq x86_64); + + +unless ($onlyinitrd) { + @aptdirs=(); + find(\&isaptdir, <$installroot/$osver/$arch/>); + # Add the dir for kernel deb to be installed + if ($kernelver) { + find(\&isaptdir, <$kerneldir/>); + if (!grep /$kerneldir/, @aptdirs) { + print "The repository for $kerneldir should be created before running the geniamge. Try to run [createrepo $kerneldir].\n"; + } + } + unless (scalar(@aptdirs)) { + print "Need $installroot/$osver/$arch/ available from a system that has ran copycds on $osver $arch\n"; + exit 1; + } + + my $aptconfig; + open($aptconfig,">","/tmp/genimage.$$.apt.list"); + my $repnum=0; + foreach $srcdir (@aptdirs) { + print $aptconfig "deb file://$srcdir main stable\n\n"; + $repnum += 1; + } + $repnum-=1; + close($aptconfig); + mkpath "$rootimg_dir/etc"; + + + + my $fd; + open($fd,">>","$rootimg_dir/etc/fstab"); + print $fd "#Dummy fstab for dpkg postscripts to see\n"; + close($fd); + + my $non_interactive; + if (!$prompt) { $non_interactive="-y"; } + + my @line=split(" ",`ls -lh $installroot/$osver/$arch/dists/ | grep dr`); + my $dist = $line[@line-1]; + + my $aptgetcmd = "chroot $rootimg_dir apt-get update && chroot $rootimg_dir apt-get $non_interactive "; + my $aptcachecmd = "chroot $rootimg_dir apt-get update && chroot $rootimg_dir apt-cache $non_interactive "; + my $aptcmd1 = "debootstrap"; + #my $aptcmd2 = "--arch $uarch $dist $rootimg_dir file://$installroot/$osver/$arch/"; + my $aptcmd2; + if ($uarch eq 'ppc64el') { + $aptcmd2 = "--verbose --arch $uarch $dist $rootimg_dir http://ports.ubuntu.com/ubuntu-ports/"; + } else { + $aptcmd2 = "--verbose --arch $uarch $dist $rootimg_dir http://archive.ubuntu.com/ubuntu/"; + } + mkpath("$rootimg_dir/var/lib/dpkg"); + mkpath("$rootimg_dir/var/lib/apt"); + + 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"); + } + } + + if ($pkglist) { + $updates{'pkglist'} = $pkglist if ($tempfile); + } else { + print "Unable to find package list for $profile!"; + exit 1; + } + + my %pkg_hash=imgutils::get_package_names($pkglist); + my $index=1; + my $pass; + foreach $pass (sort {$a <=> $b} (keys(%pkg_hash))) { + my $pkgnames = ""; + foreach (keys(%{$pkg_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$pkg_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + my $pa=$pkg_hash{$pass}{$_}; + my @npa = (); + # replace the kernel package with the name has the specific version + foreach my $p (@$pa) { + print "$p\n"; + if ($p =~ /^linux-image-server$/ && $kernelver) { + my $kernelname = "linux-image-".$kernelver."-server"; + my $searchkern = $aptcachecmd . " search $kernelname"; + my @kernpkgs = `$searchkern`; + my $found = 0; + foreach my $k (@kernpkgs) { + if ($k =~ /\s*linux-image-server[^\s]*\s+([\w\.-]+)/) { + my $version = $1; + my $relversion = $kernelver; + $relversion =~ s/\.[^\.]+$//; + if ($version == $relversion) { + $found++; + } + } + } + if ($found eq 0) { + print "Cannot find the kernel with version $kernelver.\n"; + exit 1; + } + push @npa, $kernelname; + } + elsif ($p =~ /^@/) { + push @npa, "\"$p\""; + } + else { + push @npa, $p; + } + } + $pkgnames .= join(',', @npa); + } + my $envlist; + if(exists $pkg_hash{$pass}{ENVLIST}){ + $envlist = join(',', @{$pkg_hash{$pass}{ENVLIST}}); + } + + print "$envlist $aptcmd1 --include=$pkgnames $aptcmd2\n"; + my $rc = system("$envlist $aptcmd1 --include=$pkgnames $aptcmd2"); + if ($rc) { + print "apt invocation failed\n"; + exit 1; + } + } + + print("Mount /proc, /dev, /sys, pkgdir and otherpkgdir to the rootimg.\n"); + mount_chroot($rootimg_dir, $otherpkgsdir_local, $srcdir); + + # Add the local repo from MN temporarily for apt-get update/upgrade + open($aptconfig,">","$rootimg_dir/etc/apt/sources.list"); + print $aptconfig "deb file:///mnt/pkgdir/ $dist main\n"; + close($aptconfig); + + #add the other package directory to for apt-get install + open ($aptconfig,">","$rootimg_dir/etc/apt/sources.list.d/genimage.apt.list"); + if ($otherpkgsdir_local){ + print $aptconfig "deb file://$otherpkgsdir_local ./\n"; + } + if ($otherpkgsdir_internet){ + print $aptconfig $otherpkgsdir_internet; + } + close($aptconfig); + + #backup the /etc/hosts & /etc/resolv.conf + move("$rootimg_dir/etc/hosts", "$rootimg_dir/etc/hosts.bak"); + move("$rootimg_dir/etc/resolv.conf", "$rootimg_dir/etc/resolv.conf.bak"); + + #copy the mn's /etc/hosts & /etc/resolv.conf to the rootimage + copy("/etc/hosts", "$rootimg_dir/etc/hosts"); + copy("/etc/resolv.conf", "$rootimg_dir/etc/resolv.conf"); + + #Now let's handle 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"); } + } + my %extra_hash=(); + if ($otherpkglist) { + $updates{'otherpkglist'} = $otherpkglist if ($tempfile); + %extra_hash = imgutils::get_package_names($otherpkglist); + } + my %extrapkgnames; + + if (keys(%extra_hash) > 0) { + my $index=1; + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + foreach (keys(%{$extra_hash{$pass}})) { + if($_ eq "INCLUDEBAD") { + print "Unable to open the following pkglist files:\n".join("\n",@{$extra_hash{$pass}{INCLUDEBAD}}); + exit 1; + } + + if (($_ eq "PRE_REMOVE") || ($_ eq "POST_REMOVE") || ($_ eq "ENVLIST")) { next;} + $index++; + my $pa=$extra_hash{$pass}{$_}; + $extrapkgnames{$pass} .= " " . join(' ', @$pa); + } + } + $index--; + + foreach $pass (sort {$a <=> $b} (keys(%extra_hash))) { + my $envlist; + if(exists($extra_hash{$pass}{ENVLIST})){ + $envlist = join(' ', @{$extra_hash{$pass}{ENVLIST}}); + } + # remove the packages that are specified in the otherpkgs.list files with leading '-' + my $aptgetcmd_remove= "$aptgetcmd remove "; + if (exists ($extra_hash{$pass}{'PRE_REMOVE'})) { + my $pa=$extra_hash{$pass}{'PRE_REMOVE'}; + my $rm_packges= join(' ', @$pa); + if ($rm_packges) { + print "$envlist $aptgetcmd_remove $rm_packges\n"; + $rc = system("$envlist $aptgetcmd_remove $rm_packges"); + } + } + + # mount /proc file system since several packages need it. + + # install extra packages + my $aptgetcmd_base = $aptgetcmd; + $aptgetcmd .= " install "; + # append extra pkg names to yum command + if ($extrapkgnames{$pass}) { + $aptgetcmd .= " $extrapkgnames{$pass} "; + $aptgetcmd =~ s/ $/\n/; + + # debug + #print "aptgetcmd=$aptgetcmd\n"; + #my $repo=`cat /tmp/genimage.$$.yum.conf`; + #print "repo=$repo"; + + print "$envlist $aptgetcmd\n"; + my $rc = system("$envlist $aptgetcmd"); + if ($rc) { + print "apt-get invocation failed\n"; + exit 1; + } + } else { + print "No Packages marked for install\n"; + } + + # 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) { + print "$envlist $aptgetcmd_remove $rm_packges\n"; + $rc = system("$envlist $aptgetcmd_remove $rm_packges"); + } + } + $aptgetcmd = $aptgetcmd_base; + } + } + + # run apt-get upgrade to update any installed debs + # needed when running genimage again after updating software in repositories + my $aptgetcmd_update = $yumcmd_base . " upgrade "; + $rc = system("$aptgetcmd_update"); + print("Umount /proc, /dev, /sys, pkgdir and otherpkgdir to the rootimg.\n"); + umount_chroot($rootimg_dir); + # ignore any return code + + # Add the local repo from MN + my $master = xCAT::TableUtils->get_site_Master(); + open($aptconfig,">","$rootimg_dir/etc/apt/sources.list"); + print $aptconfig "deb http://$master$installroot/$osver/$arch/ $dist main\n"; + close($aptconfig); + + #recover the /etc/hosts & /etc/reslov.conf + `cd $rootimg_dir/etc/;mv -f hosts.bak hosts;mv -f resolv.conf.bak resolv.conf`; + + postscripts(); #run 'postscripts' +} + +# 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 + +# Kernel name for s390x should be the same: vmlinuz-2.6.18-164.el5 +my @KVERS= <$rootimg_dir/boot/vmlinuz-*>; +foreach (@KVERS) { + s/vmlinuz-//; +} + +@KVERS= <$rootimg_dir/lib/modules/*> unless (scalar(@KVERS)); + +$basekernelver = basename(pop @KVERS) if (scalar(@KVERS)); + +$basekernelver = `uname -r` unless ($basekernelver); + +$kernelver = $basekernelver unless ($kernelver); +chomp($kernelver); + +#$updates{'kernelver'} = $kernelver if ($tempfile); + +# copy the kernel to $destdir +if ( -e "$rootimg_dir/boot/vmlinux-$kernelver") { + cp("$rootimg_dir/boot/vmlinux-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/vmlinuz-$kernelver") { + cp("$rootimg_dir/boot/vmlinuz-$kernelver", "$destdir/kernel"); +} elsif ( -e "$rootimg_dir/boot/image-$kernelver") { + cp("$rootimg_dir/boot/image-$kernelver", "$destdir/kernel"); +} else { + xdie("couldn't find the kernel file matched $kernelver in $rootimg_dir/boot"); +} + +# 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); + +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); +if (-d "$rootimg_dir/usr/share/dracut") { + $dracutmode = 1; + # get dracut version + my $dracutver = `chroot $rootimg_dir dpkg-query -W dracut | awk '{print \$2}'| aek -F- {print \$1}'`; + if ($dracutver =~ /^\d\d\d$/) { + if ($dracutver >= "009") { + $dracutdir = "dracut_009"; + } else { + $dracutdir = "dracut"; # The default directory + } + } + print "Enter the dracut mode. Dracut version: $dracutver. Dracut directory: $dracutdir.\n"; +} + +#-- run postinstall script +unless ($imagename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $customdir, "postinstall"); + unless ($postinstall_filename) { + $postinstall_filename= imgutils::get_profile_def_filename($osver, $profile, $arch, $pathtofiles, "postinstall"); + } +} + +if ( $postinstall_filename ) { + + $updates{'postinstall'} = $postinstall_filename if ($tempfile); + + foreach my $postinstall ( split /,/, $postinstall_filename ) { + if ( !-x $postinstall ) { + print "postinstall script $postinstall is not executable\n"; + exit 1; + } + my $rc = system($postinstall, $rootimg_dir,$osver,$arch,$profile); + if($rc) { + print "postinstall script $postinstall failed\n"; + exit 1; + } + } +} + +# all the attributes have been gathered +# now, update the linuximage and osimage tables +# TODO: do statelite and stateless share the same attributes? +#BEGIN: PLEASE DO NOT CHANGE THE FOLLOWING CODE, genimage PLUGIN NEEDS TO PARSE THR OUTPUT +if ($tempfile) { + open(FILE, ">>$tempfile"); + if ($imagename) { + if (keys(%updates) > 0) { + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$imagename\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + } else { + $updates_os{'profile'} = $profile; + $updates_os{'imagetype'} = 'linux'; + $updates_os{'provmethod'} = 'netboot'; + $updates_os{'osname'} = 'Linux'; + $updates_os{'osvers'} = $osver; + $updates_os{'osarch'} = $arch; + # update the imagename for stateless + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-netboot-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + # update the imagename for statelite + $updates_os{'provmethod'} = 'statelite'; + print FILE "The output for table updates starts here\n"; + print FILE "table::osimage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates_os; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + + print FILE "The output for table updates starts here\n"; + print FILE "table::linuximage\n"; + print FILE "imagename::$osver-$arch-statelite-$profile\n"; + my @a=%updates; + print FILE join('::',@a) . "\n"; + print FILE "The output for table updates ends here\n"; + } + close FILE; +} +#END + + +# statelite .statelite directory added here. +# this is where tmpfs will be created. + +mkpath "$rootimg_dir/.statelite"; # create place for NFS mounts. + +# this script will get the directories. +# TODO: the file is re-copied in liteimg.pm +my $cwd = $FindBin::Bin; +unless (-f "$cwd/../add-on/statelite/rc.statelite") { + print "Can't find $cwd/../add-on/statelite/rc.statelite!\n"; + exit 1; +} + +system("cp $cwd/../add-on/statelite/rc.statelite $rootimg_dir/etc/init.d/statelite"); +# also need to add this file: +# may have already been made into a symbolic link, if so ignore it + +unless ($dracutmode) { #in dracut mode, we delegate all this activity + unless (-l "$rootimg_dir/var/lib/dhclient" ) { + mkpath "$rootimg_dir/var/lib/dhclient/"; + system("touch $rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + } + + unless (-l "$rootimg_dir/var/lib/dhcp" ) { + mkpath "$rootimg_dir/var/lib/dhcp/"; + system("touch $rootimg_dir/var/lib/dhcp/dhclient-$prinic.leases"); + } +} + +if ($dracutmode) { + # modify etc/rc.sysinit, prevent remounting + # TODO: need to find one way to prevent remounting + my $SYSINITFILE; + my $TMPSYSINITFILE; + if (-f "$rootimg_dir/etc/rc.sysinit") { + # backup etc/rc.sysinit file before modifing it + system("cp -a $rootimg_dir/etc/rc.sysinit $rootimg_dir/etc/rc.sysinit.backup"); + open($SYSINITFILE, "$rootimg_dir/etc/rc.sysinit"); + open($TMPSYSINITFILE, '>', "/tmp/rc.sysinit.tmp"); + # find the following lines, + # if remount_needed ; then + # action $"Remounting root filesystem in read-write mode: " mount -n -o remount,rw / + # fi + # and change "if remount_needed ; then" to "if false; then" + while(<$SYSINITFILE>) { + if ($_ eq "if remount_needed ; then\n") { + $_ = "if false; then\n"; + } + print $TMPSYSINITFILE $_; + } + close($SYSINITFILE); + close($TMPSYSINITFILE); + cp("/tmp/rc.sysinit.tmp", "$rootimg_dir/etc/rc.sysinit"); + } +} + +# before mkinitrd, run depmod to generate modules.dep +system("chroot $rootimg_dir depmod $kernelver"); + +#delete the apt cache +system("rm -rf $rootimg_dir/var/cache/apt/*"); + +# for the genimage-enchement, need to create two initial ramdisks, +# one is for stateless +# the other one is for statelite + +if ($dracutmode) { + mkinitrd_dracut("statelite"); + mkinitrd_dracut("stateless"); +} else { + my @drivers; # backup of @ndrivers + push @drivers, @ndrivers; + mkinitrd("statelite"); + @ndrivers=(); + push @ndrivers, @drivers; + mkinitrd("stateless"); +} + +sub getlibs { + my $file = shift; + my $liblist = `chroot $rootimg_dir ldd $file`; + 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_dracut { + my ($mode) = @_; # the mode is for statelite or stateless + my $dracutmpath = "$rootimg_dir/usr/share/dracut/modules.d/97xcat"; + mkpath($dracutmpath); + + my $perm = (stat("$fullpath/$dracutdir/check"))[2]; + cp("$fullpath/$dracutdir/check", $dracutmpath); + chmod($perm&07777, "$dracutmpath/check"); + + foreach (@ndrivers) { s/\.ko$//; } + + my $add_drivers = join(' ', @ndrivers); + my $DRACUTCONF; + + if ($mode eq "statelite") { + # for statelite + cp("$fullpath/$dracutdir/install.statelite","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.statelite"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-prepivot.sh",$dracutmpath); + $perm = (stat("$fullpath/$dracutdir/xcat-prepivot.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-prepivot.sh"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + print $DRACUTCONF qq{filesystems+="nfs"\n}; + close $DRACUTCONF; + } elsif ($mode eq "stateless") { + cp("$fullpath/$dracutdir/install.netboot","$dracutmpath/install"); + $perm = (stat("$fullpath/$dracutdir/install.netboot"))[2]; + chmod($perm&07777, "$dracutmpath/install"); + + cp("$fullpath/$dracutdir/xcat-cmdline.sh","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcat-cmdline.sh"))[2]; + chmod($perm&07777, "$dracutmpath/xcat-cmdline.sh"); + + if ($prinic) { + my $optspec; + open($optspec,'>>',"$dracutmpath/xcat-cmdline.sh"); + print $optspec "PRINIC=$prinic\n"; + close $optspec; + } + + cp("$fullpath/$dracutdir/xcatroot","$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/xcatroot"))[2]; + chmod($perm&07777, "$dracutmpath/xcatroot"); + + cp("$fullpath/$dracutdir/installkernel", "$dracutmpath/"); + $perm = (stat("$fullpath/$dracutdir/installkernel"))[2]; + chmod($perm&07777, "$dracutmpath/installkernel"); + + # update etc/dracut.conf + open($DRACUTCONF, '>', "$rootimg_dir/etc/dracut.conf"); + print $DRACUTCONF qq{dracutmodules+="xcat nfs base network kernel-modules"\n}; + print $DRACUTCONF qq{add_drivers+="$add_drivers"\n}; + close $DRACUTCONF; + } else { + xdie "the mode: $mode is not supported by genimage"; + } + + system("chroot $rootimg_dir dracut -f /tmp/initrd.$$.gz $kernelver"); + print "the initial ramdisk for $mode is generated successfully.\n"; + move("$rootimg_dir/tmp/initrd.$$.gz", "$destdir/initrd-$mode.gz"); +} + +sub mkinitrd { + my ($mode) = @_; # statelite or stateless + if($mode eq "statelite") { + push @ndrivers, "fscache.ko"; + push @ndrivers, "sunrpc.ko"; + push @ndrivers, "lockd.ko"; + push @ndrivers, "nfs_acl.ko"; + push @ndrivers, "auth_rpcgss.ko"; + push @ndrivers, "nfs.ko"; + + # Additional modules needed on s390x + if ($arch eq "s390x") { + # The network drivers need to be loaded in this order + unshift @ndrivers, "ccwgroup.ko"; + unshift @ndrivers, "qdio.ko"; + } + } + + mkpath("/tmp/xcatinitrd.$$/bin"); + + 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.$$/lib64/firmware"); + 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.$$/etc/udhcpc"); + mkpath("/tmp/xcatinitrd.$$/usr/share/udhcpc"); + mkpath("/tmp/xcatinitrd.$$/var/lib/dhclient"); + mkpath("/tmp/xcatinitrd.$$/lib/modules/$kernelver"); + my $inifile; + +# start writing to the init script. + open($inifile,">","/tmp/xcatinitrd.$$/init"); + print $inifile "#!/bin/busybox sh\n"; + +# add some functions + print $inifile < <\\ \\____/ | \\ | + /__/\\_ \\\\______ /\\____|__ /____| + \\/ \\/ \\/ +' + echo -e "\$RESET" +} + +EOS1 + + + print $inifile "busybox mount -t proc /proc /proc\n"; + print $inifile "busybox --install\n"; + print $inifile "mount -t sysfs /sys /sys\n"; + print $inifile "mount -o mode=0755 -t tmpfs /dev /dev\n"; + print $inifile "mkdir /dev/pts\n"; + print $inifile "mount -t devpts -o gid=5,mode=620 /dev/pts /dev/pts\n"; + print $inifile "mkdir /run\n"; + print $inifile "mount -t tmpfs -o \"nosuid,size=20%,mode=0755\" tmpfs /run\n"; + print $inifile "mkdir /dev/shm\n"; + print $inifile "mkdir /dev/mapper\n"; + 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"; + + foreach (@ndrivers) { + print $inifile "insmod /lib/$_\n"; + } + + +# Start udev +print $inifile < /dev/null && export DEBUG=1 + +# check the kernel parameter at first + +# if one parameter for the booting device is there, we will use it +# TODO +# ( netdevice is recognized by SLES, ) +# ( Dracut has one "network" module to handle the booting network devices, which use "ifname" ) +# ( What should the other redhat versions use ? netdev= and BOOTIF= ) + +# besides this action, the following code is also used to get the XCAT= value, which is for XCAT server +# TODO: does "anaconda.busybox sh" support "set " ? + +PRINIC=$prinic +NODESTATUS='y' +XCATIPORT="3002" + +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}'|sed -e s/^01-// -e s/-/:/g` + BOOTIF=`ifconfig -a|grep -i "hwaddr \$VALUE"|awk '{print \$1}'` + elif [ "\$KEY" == 'XCAT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATSERVER=\$VALUE + elif [ "\$KEY" == 'XCATIPORT' ]; then + VALUE=`echo \$i |awk -F= '{print \$2}'` + # format: XCAT=xcatmaster:3001 + XCATIPORT=\$VALUE + fi + + #if "nonodestatus" specified,do not update the nodestatus + if [ \$i == 'nonodestatus' ]; then + NODESTATUS='n' + 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 + +ifconfig \$IFACE up +netstart \$IFACE +while ! ifconfig | grep 'inet addr'; do + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" + sleep 5 + netstart \$IFACE +done +ifconfig lo 127.0.0.1 +ifconfig lo up + + +XCATMASTER=`echo \$XCATSERVER|awk -F: '{print \$1}'` + + +#update nodelist.nodestatus to "netbooting" +if [ \$NODESTATUS != 'n' ]; then + /tmp/updateflag \$XCATMASTER \$XCATIPORT "installstatus netbooting" +fi + +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 + ST=`expr \$RANDOM % 5` + sleep \$ST + rm -f \$FILENAME + fi + done + 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 + # for NFS root + elif [ "\$KEY" == 'NFSROOT' ]; then + 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}'` + elif [ "\$KEY" == 'STATEMNT' ]; then + STATELITE=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + # the VALUE may be null + if [ ! -z \$VALUE ]; then + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` + # may be that there is not server and just a directory. + if [ -z \$SNAPSHOTROOT ] + then + SNAPSHOTROOT=\$SNAPSHOTSERVER + SNAPSHOTSERVER= + fi + fi + fi +done + +# show xCAT logo +fancydisplay + + +echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# STATELITE code here: +if [ "\$STATELITE" = "1" ]; then + echo Setting up Statelite + # for loop back mouting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + if [ "\$NFSROOT" = "1" ]; then + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,tcp,nfsvers=3,timeo=14; do + ITER=\$(expr \$ITER + 1) + if [ "\$ITER" == "\$MAXTRIES" ]; then + echo "You are dead. rpower \$ME boot to play again." + echo "Possible problems: +1. This initrd wasn't craeted for the statelite node? +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this 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 + elif [ "\$NFS" = "1" ]; then + echo -e "\${RED}The \"imgurl=\" value should not be nfs-type if statelite mode is enabled \$RESET" + shell + exit + else + # for statelite mode on top of the ramdisk +EOMS + print $inifile "if [ -r /rootimg-statelite.gz ]; then\n"; + print $inifile "echo Setting up RAM-root tmpfs.\n"; + if ($rootlimit) { + print $inifile " mount -o \"size=$rootlimit,mode=755\" -t tmpfs rootfs \$NEWROOT \n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile </dev/null && shell + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + mount -n --bind /dev/ \$NEWROOT/dev + + umount /sys + umount /proc + + cp /etc/hostname /sysroot/etc/hostname + cp /etc/resolv.conf /sysroot/etc/resolv.conf + + if ! exec /sbin/pivot_root -c /dev/console \$NEWROOT /sbin/init; then + echo "" + echo -e "\${RED}Couldn't pivot_root. Something must be wrong with the root image.\${RESET}" + shell + fi + +fi +# END NFSROOT/Statelite code + +if [ -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 \$NEWROOT + mkdir -p \$NEWROOT/ro + mkdir -p \$NEWROOT/rw + mount --move /ro \$NEWROOT/ro + mount --move /rw \$NEWROOT/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,mode=755\" -t tmpfs rootfs \$NEWROOT\n"; + } else { + print $inifile " mount -o mode=755 -t tmpfs rootfs \$NEWROOT\n"; + } + print $inifile " cd \$NEWROOT\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 5\n"; + print $inifile " echo -n \$i...\n"; + print $inifile " done\n"; + print $inifile " echo\n"; + print $inifile <"."/tmp/xcatinitrd.$$/bin/netstart"); + print $inifile "#!/bin/bash\n"; + print $inifile "udhcpc -n -q -i \${1} -s /usr/share/udhcpc/default.script\n"; + close($inifile); + + open($inifile,">"."/tmp/xcatinitrd.$$/usr/share/udhcpc/default.script"); + +print $inifile <<'EOF'; +#!/bin/sh + +# udhcpc script edited by Tim Riker + +[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 + +RESOLV_CONF="/etc/resolv.conf" +[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" +[ -n "$subnet" ] && NETMASK="netmask $subnet" + +case "$1" in + deconfig) + /sbin/ifconfig $interface 0.0.0.0 + ;; + + renew|bound) + /sbin/ifconfig $interface $ip $BROADCAST $NETMASK + + if [ -n "$hostname" ] ; then + hostname $hostname + echo $hostname > /etc/hostname + fi + + if [ -n "$router" ] ; then + echo "deleting routers" + while route del default gw 0.0.0.0 dev $interface ; do + : + done + + for i in $router ; do + route add default gw $i dev $interface + done + fi + + echo -n > $RESOLV_CONF + [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF + for i in $dns ; do + echo adding dns $i + echo nameserver $i >> $RESOLV_CONF + done + ;; +esac + +exit 0 +EOF + + close($inifile); + + #if "nonodestatus" specified,do not update the nodestatus + system("mkdir -p /tmp/xcatinitrd.$$/tmp/"); + open($inifile, ">","/tmp/xcatinitrd.$$/tmp/updateflag"); + + print $inifile < /tmp/ncarg + nc \$1 \$2 -w 60 -e /tmp/updateflag +else + retrytimes=0 + cmd="" + while [ "\$cmd" != "done" ]; do + retrytimes=`expr \$retrytimes + 1` + if [ \$retrytimes -eq 60 ]; then + break; + fi + read -t 60 cmd + if [ "\$cmd" == "ready" ]; then + head -n 1 /tmp/ncarg + rm -rf /tmp/ncarg + fi + done + +fi +EOMS + close($inifile); + + chmod(0755,"/tmp/xcatinitrd.$$/usr/share/udhcpc/default.script"); + + chmod(0755,"/tmp/xcatinitrd.$$/init"); + chmod(0755,"/tmp/xcatinitrd.$$/bin/netstart"); + chmod(0755,"/tmp/xcatinitrd.$$/tmp/updateflag"); + @filestoadd=(); + foreach (@ndrivers) { + if (-f "$customdir/$_") { + push @filestoadd,[$_,"lib/$_"]; + } elsif (-f "$pathtofiles/$_") { + push @filestoadd,[$_,"lib/$_"]; + } + } + # add rsync for statelite + foreach ("bin/busybox","bin/bash", "sbin/mount.nfs", "usr/bin/rsync", "sbin/insmod", "sbin/udevd", "sbin/udevadm", "sbin/modprobe", "sbin/blkid", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + + # Additional binaries needed for udev on s390x + if ($arch eq "s390x") { + foreach ("sbin/udevsettle", "sbin/udevtrigger", "sbin/udevd", "sbin/depmod") { + getlibs($_); + push @filestoadd,$_; + } + } + + if ($arch =~ /x86_64/) { + push @filestoadd,"lib64/libnss_dns.so.2"; + push @filestoadd,"lib64/libresolv.so.2"; + } else { + push @filestoadd,"lib/libnss_dns.so.2"; + } + push @filestoadd,keys %libhash; + + find(\&isnetdriver, <$rootimg_dir/lib/modules/$kernelver/*>); + + foreach (@filestoadd) { + if (ref($_)) { + #print "$_->[0], $_->[1]\n"; + my $srcpath = "$rootimg_dir/".$_->[0]; + if (-f "$customdir/".$_->[0]) { + $srcpath="$customdir/".$_->[0]; + } elsif (-f "$pathtofiles/".$_->[0]) { + $srcpath="$pathtofiles/".$_->[0]; + } + mkpath(dirname("/tmp/xcatinitrd.$$/".$_->[1])); + copy($srcpath,"/tmp/xcatinitrd.$$/".$_->[1]); + chmod 0755,"/tmp/xcatinitrd.$$/".$_->[1]; + } else { + #print "$_\n"; + my $srcpath = "$rootimg_dir/$_"; + if (-f "$customdir/$_") { + $srcpath = "$customdir/$_"; + } elsif (-f "$pathtofiles/$_") { + $srcpath = "$pathtofiles/$_"; + } + mkpath(dirname("/tmp/xcatinitrd.$$/$_")); + copy("$srcpath","/tmp/xcatinitrd.$$/$_"); + chmod 0755,"/tmp/xcatinitrd.$$/".$_; + } + } + + if ( -d "$rootimg_dir/lib/firmware/" ){ + system("cp -r $rootimg_dir/lib/firmware/* /tmp/xcatinitrd.$$/lib/firmware"); + } + + if ( -d "$rootimg_dir/lib/modules/$kernelver/" ){ + system("cp $rootimg_dir/lib/modules/$kernelver/modules.builtin /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.builtin"); + system("cp $rootimg_dir/lib/modules/$kernelver/modules.order /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.order"); + } + + system("chroot /tmp/xcatinitrd.$$/ depmod $kernelver"); + # Copy udev and network scripts into initrd for s390x, which also works for other platforms + # udev + 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"); + system("mkdir -p /tmp/xcatinitrd.$$/proc/self"); + system("cp -r /proc/self/oom_adj /tmp/xcatinitrd.$$/proc/self"); + + # Network related scripts + #system("echo $kernelver\n"); + #system("mkdir -p /tmp/xcatinitrd.$$/sbin"); + #system("cp -r $rootimg_dir/sbin/* /tmp/xcatinitrd.$$/sbin"); + #system("mkdir -p /tmp/xcatinitrd.$$/lib/modules/$kernelver"); + #system("cp -r $rootimg_dir/lib/modules/$kernelver/modules.dep /tmp/xcatinitrd.$$/lib/modules/$kernelver/modules.dep"); + #system("mkdir -p /tmp/xcatinitrd.$$/etc/init.d"); + #system("cp -r $rootimg_dir/etc/init.d/* /tmp/xcatinitrd.$$/etc/init.d"); + #system("mkdir -p /tmp/xcatinitrd.$$/lib64"); + #system("cp -r $rootimg_dir/lib64/* /tmp/xcatinitrd.$$/lib64"); + #system("mkdir -p /tmp/xcatinitrd.$$/var/run/netreport"); + symlink("busybox","/tmp/xcatinitrd.$$/bin/pivot_root"); + symlink("busybox", "/tmp/xcatinitrd.$$/bin/udhcpc"); + symlink("busybox", "/tmp/xcatinitrd.$$/sbin/ifconfig"); + symlink("busybox", "/tmp/xcatinitrd.$$/bin/hostname"); + symlink("busybox", "/tmp/xcatinitrd.$$/bin/route"); + symlink("busybox", "/tmp/xcatinitrd.$$/bin/nc"); + symlink("bash", "/tmp/xcatinitrd.$$/bin/sh"); + symlink("bash", "/tmp/xcatinitrd.$$/sbin/sh"); + + + #copy("$rootimg_dir/lib/modules/*d","/tmp/xcatinitrd.$$/$_"); + system("cd /tmp/xcatinitrd.$$;find .|cpio -H newc -o|gzip -9 -c - > $destdir/initrd-$mode.gz"); + system("rm -rf /tmp/xcatinitrd.$$"); + +} + +sub isaptdir { + if ($File::Find::name =~ /\/Packages.gz$/) { + my $location = $File::Find::name; + $location =~ s/\/Packages.gz$//; + push @aptdirs,$location; + } +} + +sub isnetdriver { + foreach (@ndrivers) { + if ($File::Find::name =~ /\/$_/) { + my $filetoadd = $File::Find::name; + $filetoadd =~ s!$rootimg_dir/!!; + push @filestoadd,[$filetoadd,"lib/$_"]; + } + } +} + +sub postscripts { + generic_post(); + + # TODO: workaround for kdump on RHEL6 + # add one fake command: fsck.nfs + unless ( -x "$rootimg_dir/sbin/fsck.nfs" ) { + system("echo true > $rootimg_dir/sbin/fsck.nfs; chmod a+x $rootimg_dir/sbin/fsck.nfs"); + } + + + 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"; +} + + +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"; + + open($cfgfile,">","$rootimg_dir/etc/resolv.conf"); + print $cfgfile "#Dummy resolv.conf to make boot cleaner"; + close($cfgfile); + + # Create the ifcfg-x file for diskless node. But keep the ONBOOT=no + # to skip the break of nfs-based boot + if ($prinic) { + open($cfgfile,">","$rootimg_dir/etc/network/interfaces"); + print $cfgfile "auto $prinic\niface $prinic inet dhcp\n"; + close($cfgfile); + } + foreach (split /,/,$othernics) { + if (/^$/) { next; } + open($cfgfile,">>","$rootimg_dir/etc/network/interfaces"); + print $cfgfile "auto $_\niface $_ inet dhcp\n"; + close($cfgfile); + } + + # securetty not needed on s390x + if ($arch ne "s390x") { + open($cfgfile,">>","$rootimg_dir/etc/securetty"); + print $cfgfile "ttyS0\n"; + print $cfgfile "ttyS1\n"; + close($cfgfile); + } + + 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/.*>) { + if (basename($_) eq '.' or basename($_) eq '..') { + next; + } + copy $_,"$rootimg_dir/root/"; + } + unless ( -r <$rootimg_dir/etc/rc3.d/S??network>) { + symlink "/etc/init.d/networking","$rootimg_dir/etc/rc3.d/S10networking"; + } + + # setup the ttyS configure file + open($cfgfile, ">", "$rootimg_dir/etc/init/ttyS.conf"); + print $cfgfile "start on stopped rc RUNLEVEL=[2345] and "; + print $cfgfile "(not-container or container container CONTAINER=lxc or container CONTAINER=lxc-libvirt) \n"; + print $cfgfile "stop on runlevel [!2345] \n"; + print $cfgfile "respawn \n"; + print $cfgfile "script\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 " exec /sbin/getty -L \$COSPEED \$COTTY vt102 \n"; + print $cfgfile " break \n"; + print $cfgfile " fi \n"; + print $cfgfile " done\n"; + print $cfgfile "end script\n"; + + copy("$installroot/postscripts/xcatpostinit", "$rootimg_dir/etc/init.d/xcatpostinit"); + #the ubuntu default run level is 2 + chmod(0755, "$rootimg_dir/etc/init.d/xcatpostinit"); + system("cd $rootimg_dir/etc/rc2.d; ln -sf ../init.d/xcatpostinit S61xcatpostinit"); + #change the /bin/sh link to /bin/bash + system("cd $rootimg_dir/bin/; ln -sf bash sh"); +} + + +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 () +{ + # Get 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 for initrd hack + my $dd_dir = mkdtemp("/tmp/ddtmpXXXXXXX"); + mkpath "$dd_dir/mnt"; + mkpath "$dd_dir/mods"; + + my @dd_drivers = (); #dirver name + + # Loading drivers from each Driver Disk + foreach my $dd (@dd_list) { + my $rc = system ("mount -o loop $dd $dd_dir/mnt"); + if ($rc) { + print "mount the Driver Disk $dd failed.\n"; + next; + } + + if (! (-f "$dd_dir/mnt/rhdd" || -f "$dd_dir/mnt/modinfo" + || -f "$dd_dir/mnt/modules.dep" || -f "$dd_dir/mnt/modules.cgz")) { + print "The Driver Disk $dd has not correct format.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + # Load the modinfo + open($modinfo, "<", "$dd_dir/mnt/modinfo"); + my @modinfo_lines = <$modinfo>; + my $mod_ver = shift @modinfo_lines; + chomp($mod_ver); + if ($mod_ver !~ /^Version 0/) { + print "The Driver Disk $dd has unknown version.\n"; + system ("umount -f $dd_dir/mnt"); + next; + } + + foreach my $line (@modinfo_lines) { + if ($line !~ /^Version/ && $line =~ /^(\w+)/) { + chomp($line); + if ($line =~ /^\s*$/) { next; } + $line =~ s/$/\.ko/; + push @dd_drivers, $line; + } + } + close($modinfo); + + # Copy the firmware + if (-d "$dd_dir/mnt/firmware") { + system ("cp -rf $dd_dir/mnt/firmware $rootimg_dir/lib/firmware"); + } + + # Load the modules.cgz + system ("cd $dd_dir/mods; gunzip -c $dd_dir/mnt/modules.cgz |cpio -id"); + 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 + my @drivers = `find $dd_dir/mods/$kernelver/$arch/ -type f`; + + foreach my $d (@drivers) { + chomp($d); + $driver_name = $d; + $driver_name =~ s/.*\///; + $real_path = ""; + find (\&get_path, <$rootimg_dir/lib/modules/$kernelver/*>); + if ($real_path eq "") { + system ("cp $d $rootimg_dir/lib/modules/$kernelver/kernel/drivers/driverdisk"); + } else { + system ("cp $d $real_path"); + } + } + + rmtree "$dd_dir/mods/*"; + + 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; +} + +sub mount_chroot { + my $rootimage_dir = shift; + my $otherpkgdir = shift; + my $pkgdir = shift; + mkdir("$rootimage_dir/mnt/pkgdir"); + mkdir("$rootimage_dir/mnt/otherpkgdir"); + #system("mount -o bind /dev $rootimage_dir/dev"); + #system("mount -o bind /proc $rootimage_dir/proc"); + #system("mount -o bind /sys $rootimage_dir/sys"); + system("mount -o bind $pkgdir $rootimage_dir/mnt/pkgdir"); + if ($otherpkgdir){ + system("mount -o bind $otherpkgdir $rootimage_dir/mnt/otherpkgdir"); + } +} + +sub umount_chroot { + my $rootimage_dir = shift; + #system("umount $rootimage_dir/dev"); + #system("umount $rootimage_dir/proc"); + #system("umount $rootimage_dir/sys"); + system("umount $rootimage_dir/mnt/pkgdir"); + system("umount $rootimage_dir/mnt/otherpkgdir"); + rmdir("$rootimage_dir/mnt/pkgdir"); + rmdir("$rootimage_dir/mnt/otherpkgdir"); +} + +sub usage { + print 'Usage: genimage [ -i ] [ -n ] [-r ] -o -p -k [--permission ] [--interactive]'."\n"; + print " --permission only works with statelite mode\n"; + 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 --interactive\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot\n"; + print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; + + return 0; +} + + diff --git a/xCAT/templates/cmos_settings/nosol/default/6391 b/xCAT/templates/cmos_settings/nosol/default/6391 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/6391 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/6391 b/xCAT/templates/cmos_settings/nosol/default/6391 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/6391 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/nosol/default/7321 b/xCAT/templates/cmos_settings/nosol/default/7321 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7321 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7321 b/xCAT/templates/cmos_settings/nosol/default/7321 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7321 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/nosol/default/7323 b/xCAT/templates/cmos_settings/nosol/default/7323 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7323 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7323 b/xCAT/templates/cmos_settings/nosol/default/7323 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7323 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/nosol/default/7870 b/xCAT/templates/cmos_settings/nosol/default/7870 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7870 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7870 b/xCAT/templates/cmos_settings/nosol/default/7870 new file mode 100644 index 000000000..a2b2c563f --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7870 @@ -0,0 +1,8 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware +set uEFI.LegacyOptionRomPort "COM Port 1" diff --git a/xCAT/templates/cmos_settings/nosol/default/7871 b/xCAT/templates/cmos_settings/nosol/default/7871 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7871 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7871 b/xCAT/templates/cmos_settings/nosol/default/7871 new file mode 100644 index 000000000..a2b2c563f --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7871 @@ -0,0 +1,8 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware +set uEFI.LegacyOptionRomPort "COM Port 1" diff --git a/xCAT/templates/cmos_settings/nosol/default/7901 b/xCAT/templates/cmos_settings/nosol/default/7901 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7901 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7901 b/xCAT/templates/cmos_settings/nosol/default/7901 new file mode 100644 index 000000000..18cb05e74 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7901 @@ -0,0 +1,16 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 1" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/nosol/default/7902 b/xCAT/templates/cmos_settings/nosol/default/7902 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7902 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7902 b/xCAT/templates/cmos_settings/nosol/default/7902 new file mode 100644 index 000000000..18cb05e74 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7902 @@ -0,0 +1,16 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 1" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/nosol/default/7944 b/xCAT/templates/cmos_settings/nosol/default/7944 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7944 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7944 b/xCAT/templates/cmos_settings/nosol/default/7944 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7944 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/nosol/default/7945 b/xCAT/templates/cmos_settings/nosol/default/7945 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7945 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7945 b/xCAT/templates/cmos_settings/nosol/default/7945 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7945 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/nosol/default/7946 b/xCAT/templates/cmos_settings/nosol/default/7946 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7946 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7946 b/xCAT/templates/cmos_settings/nosol/default/7946 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7946 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/nosol/default/7947 b/xCAT/templates/cmos_settings/nosol/default/7947 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/default/7947 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/default/7947 b/xCAT/templates/cmos_settings/nosol/default/7947 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/default/7947 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7321 b/xCAT/templates/cmos_settings/nosol/hpc/7321 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7321 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7321 b/xCAT/templates/cmos_settings/nosol/hpc/7321 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7321 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7323 b/xCAT/templates/cmos_settings/nosol/hpc/7323 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7323 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7323 b/xCAT/templates/cmos_settings/nosol/hpc/7323 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7323 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7391 b/xCAT/templates/cmos_settings/nosol/hpc/7391 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7391 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7391 b/xCAT/templates/cmos_settings/nosol/hpc/7391 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7391 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7870 b/xCAT/templates/cmos_settings/nosol/hpc/7870 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7870 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7870 b/xCAT/templates/cmos_settings/nosol/hpc/7870 new file mode 100644 index 000000000..68bca4221 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7870 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware +set uEFI.LegacyOptionRomPort "COM Port 1" +set uEFI.ProcessorHyperThreading Disable +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" + diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7871 b/xCAT/templates/cmos_settings/nosol/hpc/7871 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7871 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7871 b/xCAT/templates/cmos_settings/nosol/hpc/7871 new file mode 100644 index 000000000..68bca4221 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7871 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware +set uEFI.LegacyOptionRomPort "COM Port 1" +set uEFI.ProcessorHyperThreading Disable +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" + diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7901 b/xCAT/templates/cmos_settings/nosol/hpc/7901 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7901 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7901 b/xCAT/templates/cmos_settings/nosol/hpc/7901 new file mode 100644 index 000000000..b82ce0ced --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7901 @@ -0,0 +1,17 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 1" +set CMOS_RemoteConsoleBaud "115200" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7902 b/xCAT/templates/cmos_settings/nosol/hpc/7902 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7902 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7902 b/xCAT/templates/cmos_settings/nosol/hpc/7902 new file mode 100644 index 000000000..b82ce0ced --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7902 @@ -0,0 +1,17 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 1" +set CMOS_RemoteConsoleBaud "115200" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7944 b/xCAT/templates/cmos_settings/nosol/hpc/7944 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7944 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7944 b/xCAT/templates/cmos_settings/nosol/hpc/7944 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7944 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7945 b/xCAT/templates/cmos_settings/nosol/hpc/7945 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7945 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7945 b/xCAT/templates/cmos_settings/nosol/hpc/7945 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7945 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7946 b/xCAT/templates/cmos_settings/nosol/hpc/7946 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7946 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7946 b/xCAT/templates/cmos_settings/nosol/hpc/7946 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7946 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7947 b/xCAT/templates/cmos_settings/nosol/hpc/7947 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/nosol/hpc/7947 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/nosol/hpc/7947 b/xCAT/templates/cmos_settings/nosol/hpc/7947 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/nosol/hpc/7947 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/default/6391 b/xCAT/templates/cmos_settings/sol/default/6391 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/default/6391 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/6391 b/xCAT/templates/cmos_settings/sol/default/6391 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/6391 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7321 b/xCAT/templates/cmos_settings/sol/default/7321 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7321 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7321 b/xCAT/templates/cmos_settings/sol/default/7321 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7321 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7323 b/xCAT/templates/cmos_settings/sol/default/7323 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7323 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7323 b/xCAT/templates/cmos_settings/sol/default/7323 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7323 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7870 b/xCAT/templates/cmos_settings/sol/default/7870 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7870 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7870 b/xCAT/templates/cmos_settings/sol/default/7870 new file mode 100644 index 000000000..9565e1835 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7870 @@ -0,0 +1,7 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7871 b/xCAT/templates/cmos_settings/sol/default/7871 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7871 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7871 b/xCAT/templates/cmos_settings/sol/default/7871 new file mode 100644 index 000000000..9565e1835 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7871 @@ -0,0 +1,7 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7901 b/xCAT/templates/cmos_settings/sol/default/7901 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7901 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7901 b/xCAT/templates/cmos_settings/sol/default/7901 new file mode 100644 index 000000000..033593175 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7901 @@ -0,0 +1,16 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 2" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/sol/default/7902 b/xCAT/templates/cmos_settings/sol/default/7902 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7902 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7902 b/xCAT/templates/cmos_settings/sol/default/7902 new file mode 100644 index 000000000..033593175 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7902 @@ -0,0 +1,16 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 2" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/sol/default/7944 b/xCAT/templates/cmos_settings/sol/default/7944 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7944 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7944 b/xCAT/templates/cmos_settings/sol/default/7944 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7944 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7945 b/xCAT/templates/cmos_settings/sol/default/7945 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7945 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7945 b/xCAT/templates/cmos_settings/sol/default/7945 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7945 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7946 b/xCAT/templates/cmos_settings/sol/default/7946 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7946 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7946 b/xCAT/templates/cmos_settings/sol/default/7946 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7946 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/default/7947 b/xCAT/templates/cmos_settings/sol/default/7947 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/default/7947 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/default/7947 b/xCAT/templates/cmos_settings/sol/default/7947 new file mode 100644 index 000000000..06276ae1b --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/default/7947 @@ -0,0 +1,9 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware diff --git a/xCAT/templates/cmos_settings/sol/hpc/7321 b/xCAT/templates/cmos_settings/sol/hpc/7321 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7321 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7321 b/xCAT/templates/cmos_settings/sol/hpc/7321 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7321 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7323 b/xCAT/templates/cmos_settings/sol/hpc/7323 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7323 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7323 b/xCAT/templates/cmos_settings/sol/hpc/7323 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7323 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7391 b/xCAT/templates/cmos_settings/sol/hpc/7391 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7391 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7391 b/xCAT/templates/cmos_settings/sol/hpc/7391 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7391 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7870 b/xCAT/templates/cmos_settings/sol/hpc/7870 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7870 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7870 b/xCAT/templates/cmos_settings/sol/hpc/7870 new file mode 100644 index 000000000..c5ad21663 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7870 @@ -0,0 +1,15 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware +set uEFI.ProcessorHyperThreading Disable +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" + diff --git a/xCAT/templates/cmos_settings/sol/hpc/7871 b/xCAT/templates/cmos_settings/sol/hpc/7871 deleted file mode 120000 index 2b1bd49f4..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7871 +++ /dev/null @@ -1 +0,0 @@ -hs22.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7871 b/xCAT/templates/cmos_settings/sol/hpc/7871 new file mode 100644 index 000000000..c5ad21663 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7871 @@ -0,0 +1,15 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.RemoteConsoleRedirection Enable +set uEFI.Com2TextEmul VT100 +set uEFI.Com2ActiveAfterBoot Enable +set uEFI.Com2FlowControl Hardware +set uEFI.ProcessorHyperThreading Disable +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" + diff --git a/xCAT/templates/cmos_settings/sol/hpc/7901 b/xCAT/templates/cmos_settings/sol/hpc/7901 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7901 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7901 b/xCAT/templates/cmos_settings/sol/hpc/7901 new file mode 100644 index 000000000..cdce68f43 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7901 @@ -0,0 +1,17 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 2" +set CMOS_RemoteConsoleBaud "115200" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7902 b/xCAT/templates/cmos_settings/sol/hpc/7902 deleted file mode 120000 index 74e83f5f0..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7902 +++ /dev/null @@ -1 +0,0 @@ -ls22-42.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7902 b/xCAT/templates/cmos_settings/sol/hpc/7902 new file mode 100644 index 000000000..cdce68f43 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7902 @@ -0,0 +1,17 @@ +loaddefault all +set CMOS_SerialA "Auto-Configure" +set CMOS_SerialB "Auto-Configure" +set CMOS_RemoteConsoleEnable "Enabled" +set CMOS_RemoteConsoleComPort "COM 2" +set CMOS_RemoteConsoleBaud "115200" +set CMOS_RemoteConsoleEmulation "VT100/VT220" +set CMOS_RemoteConsoleKybdEmul "VT100/VT220" +set CMOS_RemoteConsoleBootEnable "Enabled" +set CMOS_RemoteConsoleFlowCtrl "Hardware" +set CMOS_ENET2_PXE_ENABLE "Disabled" +set CMOS_ENET3_PXE_ENABLE "Disabled" +set CMOS_ENET4_PXE_ENABLE "Disabled" +set CMOS_PostBootFailRequired "Disabled" +set CMOS_ROMControlSlot1 "Disabled" +set CMOS_ROMControlSlot2 "Disabled" +set CMOS_IOMMU_PLANAR_ENABLE "Enabled" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7912 b/xCAT/templates/cmos_settings/sol/hpc/7912 deleted file mode 120000 index 4f51e8aa9..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7912 +++ /dev/null @@ -1 +0,0 @@ -m4.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7912 b/xCAT/templates/cmos_settings/sol/hpc/7912 new file mode 100644 index 000000000..25e158a7a --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7912 @@ -0,0 +1,14 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "PXE Network=Hard Disk 0" +set Processors.Hyper-Threading "Disable" +set DevicesandIOPorts.RemoteConsole "Enable" +set DevicesandIOPorts.SerialPortSharing "Enable" +set DevicesandIOPorts.SerialPortAccessMode "Dedicated" +set DevicesandIOPorts.Com1TerminalEmulation "VT100" +set DevicesandIOPorts.Com1ActiveAfterBoot "Enable" +set OperatingModes.ChooseOperatingMode "Custom Mode" +set Processors.C1EnhancedMode "Disable" +set Processors.TurboMode "Enable" +set Processors.PackageACPIC-StateLimit "ACPI C3" +set Processors.QPILinkFrequency "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7944 b/xCAT/templates/cmos_settings/sol/hpc/7944 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7944 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7944 b/xCAT/templates/cmos_settings/sol/hpc/7944 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7944 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7945 b/xCAT/templates/cmos_settings/sol/hpc/7945 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7945 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7945 b/xCAT/templates/cmos_settings/sol/hpc/7945 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7945 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7946 b/xCAT/templates/cmos_settings/sol/hpc/7946 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7946 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7946 b/xCAT/templates/cmos_settings/sol/hpc/7946 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7946 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance" diff --git a/xCAT/templates/cmos_settings/sol/hpc/7947 b/xCAT/templates/cmos_settings/sol/hpc/7947 deleted file mode 120000 index 68df77c29..000000000 --- a/xCAT/templates/cmos_settings/sol/hpc/7947 +++ /dev/null @@ -1 +0,0 @@ -m2-m3.bat \ No newline at end of file diff --git a/xCAT/templates/cmos_settings/sol/hpc/7947 b/xCAT/templates/cmos_settings/sol/hpc/7947 new file mode 100644 index 000000000..b05488029 --- /dev/null +++ b/xCAT/templates/cmos_settings/sol/hpc/7947 @@ -0,0 +1,16 @@ +loaddefault uEFI +loaddefault BootOrder +set BootOrder.BootOrder "Legacy Only=PXE Network=Hard Disk 0" +set uEFI.ProcessorHyperThreading Disable +set uEFI.RemoteConsoleRedirection Enable +set uEFI.SerialPortSharing Enable +set uEFI.SerialPortAccessMode Dedicated +set uEFI.Com1TextEmul VT100 +set uEFI.Com1ActiveAfterBoot Enable +set uEFI.Com1FlowControl Hardware +set uEFI.OperatingMode "Custom Mode" +set uEFI.ProcessorEistEnable "Enable" +set uEFI.ProcessorC1eEnable "Disable" +set uEFI.TurboModeEnable "Enable" +set uEFI.PackageCState "ACPI C3" +set uEFI.QPISpeed "Max Performance"