From 09c3dfb79c698924480a4bf46701cb28c1b8bbce Mon Sep 17 00:00:00 2001 From: vallard Date: Fri, 4 Dec 2009 00:53:47 +0000 Subject: [PATCH] added statelite options git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@4717 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/share/xcat/netboot/rh/genimage | 315 ++++++++++++++++++++- 1 file changed, 304 insertions(+), 11 deletions(-) diff --git a/xCAT-server/share/xcat/netboot/rh/genimage b/xCAT-server/share/xcat/netboot/rh/genimage index 644e383a4..9c43c4e7d 100755 --- a/xCAT-server/share/xcat/netboot/rh/genimage +++ b/xCAT-server/share/xcat/netboot/rh/genimage @@ -46,6 +46,7 @@ my $srcdir_otherpkgs; my $otherpkglist; my $postinstall_filename; my $rootimg_dir; +my $rwfiles; # these files are used by statelite for tmpfs rw sub xdie { system("rm -rf /tmp/xcatinitrd.$$"); @@ -62,7 +63,8 @@ GetOptions( 'r=s' => \$othernics, 'l=s' => \$rootlimit, 't=s' => \$tmplimit, - 'k=s' => \$kernelver + 'k=s' => \$kernelver, + 'm=s' => \$mode ); if (@ARGV > 0) { $imagename=$ARGV[0]; @@ -149,15 +151,18 @@ if (!$destdir) } $rootimg_dir="$destdir/rootimg"; + unless ($osver and $profile and $netdriver and $prinic) { - print 'Usage: genimage -i -n [-r ] -o -p -k '."\n"; + print 'Usage: genimage -i -n [-r ] -o -p -k -m '."\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 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot -m statelite\n"; print " genimage -i eth0 -n tg3 myimage\n"; exit 1; } + my @ndrivers; foreach (split /,/,$netdriver) { unless (/\.ko$/) { @@ -168,6 +173,14 @@ foreach (split /,/,$netdriver) { } push @ndrivers,$_; } +if($mode eq "statelite"){ + push @ndrivers,"fscache.ko"; + push @ndrivers,"sunrpc.ko"; + push @ndrivers,"lockd.ko"; + push @ndrivers,"nfs_acl.ko"; + push @ndrivers,"nfs.ko"; + +} unless ($onlyinitrd) { @yumdirs=(); @@ -188,6 +201,35 @@ unless ($onlyinitrd) { $repnum-=1; close($yumconfig); mkpath "$rootimg_dir/etc"; + + # statelite snapshots directory added here. + # this is where tmpfs will be created. + if($mode eq "statelite"){ + mkpath "$rootimg_dir/.snapshot"; # create place for NFS mounts. + # get all the rw files that go in tmpfs + $rwfiles = get_rwfiles_file_name($customdir); + if (!$rwfiles) { + $rwfiles= get_rwfiles_file_name($pathtofiles); + } + if(!$rwfiles){ + print "Unable to find r/w file list. Make a file called $profile.rwfiles with all the necessary read/write files\n"; + exit 1; + } + # copyt the rwfiles to /.snapshot/files for the initfs to use. + copy("$rwfiles","$rootimg_dir/.snapshot/files"); + + # also need to create stub file for booting since this is read only + mkpath "$rootimg_dir/var/lib/dhclient/"; + # create an empty file + open(FH,">$rootimg_dir/var/lib/dhclient/dhclient-$prinic.leases"); + close(FH); + open(FH,">$rootimg_dir/var/lib/random-seed"); + close(FH); + + # link mtab. + system("ln -sf /proc/mounts $rootimg_dir/etc/mtab"); + } + my $fd; open($fd,">>","$rootimg_dir/etc/fstab"); print $fd "#Dummy fstab for rpm postscripts to see\n"; @@ -385,8 +427,117 @@ sub mkinitrd { 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"; @@ -423,9 +574,11 @@ sub mkinitrd { print $inifile "insmod /lib/$_\n"; } print $inifile < /dev/null && DEBUG=1 netstart while ! ifconfig | grep inet; do - echo Failed to acquire address, retrying + echo -e "\${RED}Failed to acquire address, retrying \${RESET}" sleep 1 netstart done @@ -443,7 +596,8 @@ for i in `cat /proc/cmdline`; do while [ ! -r "\$FILENAME" ]; do echo Getting \$VALUE... if ! wget \$VALUE; then - sleep 5 #should be random, exponential for scale + ST=`expr \$RANDOM % 5` + sleep \$ST rm -f \$FILENAME fi done @@ -454,9 +608,127 @@ for i in `cat /proc/cmdline`; do 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" == 'SNAPSHOT' ]; then + NFSROOT=1 + VALUE=`echo \$i |awk -F= '{print \$2}'` + SNAPSHOTSERVER=`echo \$VALUE|awk -F: '{print \$1}'` + SNAPSHOTROOT=`echo \$VALUE|awk -F/ '{for(i=2;i<=NF;i++) printf "/%s",\$i}'` fi done + +# show xCAT logo +fancydisplay + +# go to debug shell if shell is specified. +grep '\(shell\)' /proc/cmdline > /dev/null && shell + echo 0 > /proc/sys/vm/zone_reclaim_mode #Avoid kernel bug + +# NFSROOT code here: +if [ "\$NFSROOT" = "1" ]; then + echo Setting up nfs with ram overlay. + # for loop back mounting capability! + mknod /dev/loop0 b 7 0 + mkdir -p \$NEWROOT + MAXTRIES=5 + ITER=0 + ME=`hostname` + while ! mount.nfs \${SERVER}:\${ROOTDIR}/rootimg \$NEWROOT -r -n -o nolock,rsize=32768,udp,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 wasn't created for statelite node? rerun genimage with the -m statelite flag, then rerun 'nodeset \$ME statelite' +2. Is DNS set up? Maybe that's why I can't mount \${SERVER}. +3. The nfs modules aren't set right in this initfs?" + + shell + exit + fi + echo -e "\${RED}Could not mount \$SERVER:\$ROOTDIR on \$NEWROOT \$RESET" + RS=`expr \$RANDOM % 30` + echo -e "Trying again in \$RS seconds" + sleep \$RS + done + +# now we need to mount the rest of the system. This is the read/write portions +#echo "Mounting Snapshot directories" + + if [ ! -e "\$NEWROOT/\$RWDIR" ] + then + echo "" + echo -e "\${RED}Hmmm... this NFS root directory doesn't have a /.snapshot directory for me to mount a rw filesystem. You'd better create it... \${NORMAL}" + echo "." + shell + fi + + grep '\(shell\)' /proc/cmdline >/dev/null && shell + if [ -e "\$NEWROOT/\$RWDIR/files" ]; then + mkdir -p /rw + mount -t tmpfs rw /rw + cp \$NEWROOT/\$RWDIR/files /rw/ # copy the files from .snapshot here now + mount -n --bind /rw \$NEWROOT/\$RWDIR # remount read/writable + + for i in `grep -v "^#" \$NEWROOT/\$RWDIR/files`; do + if [ -e \$NEWROOT/\$i ]; then + mountfile \$i \$ME + fi; + done + else + echo -e "\${RED}\$NEWROOT/\$RWDIR/files does not exist! I need a list of files to mount read write... or else we'll try mounting everything read only. \$RESET" + shell + fi + + + # have to preserve the initial DHCP request. So we link it. + + if [ ! -d \$NEWROOT/\$RWDIR/\$ME/var/lib/dhclient ] + then + mkdir -p \$NEWROOT/\$RWDIR/\$ME/var/lib/dhclient + fi + + cp -fp /var/lib/dhclient/dhclient.leases \$NEWROOT/\$RWDIR/\$ME/var/lib/dhclient/dhclient-$prinic.leases + + while ! mount -n --bind \$NEWROOT/\$RWDIR/\$ME/var/lib/dhclient/dhclient-$prinic.leases \$NEWROOT/var/lib/dhclient/dhclient-$prinic.leases; + do + echo -e "\${RED}The file /var/lib/dhclient/dhclient-$prinic.leases on your NFS root doesn't exist. I can't bind mount to it :-( \${RESET}" + echo -e "\${PINK}You'd better create it! :-) \${RESET}" + shell + done + + # mount /etc/resolv.conf! + mkdir -p \$NEWROOT/\$RWDIR/\$ME/etc + cp /etc/resolv.conf \$NEWROOT/\$RWDIR/\$ME/etc/ + mount -n --bind \$NEWROOT/\$RWDIR/\$ME/etc/resolv.conf \$NEWROOT/\$RWDIR/\$ME/etc/resolv.conf + + echo 0x100 > /proc/sys/kernel/real-root-dev + export keep_old_ip=yes + export fastboot=yes + export READONLY=yes + mount -n --bind /dev /sysroot/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 NFS root image.\${RESET}" + mount -t proc proc /proc + shell + fi + exit +fi +# END NFSROOT/Statelite code + +# RAM root Hybrid with NFS root if [ "\$NFS" = "1" ]; then echo Setting up nfs with ram overlay. mknod /dev/loop0 b 7 0 @@ -466,7 +738,8 @@ if [ "\$NFS" = "1" ]; then while [ ! -d /ro/bin ]; do echo mounting \$SERVER:\$ROOTDIR on /ro mount.nfs \$SERVER:\$ROOTDIR /ro -r -n -o nolock,rsize=32768,udp,nfsvers=3,timeo=14 - sleep 5 #should be random, exponential for scale + ST=`expr \$RANDOM % 5` + sleep \$ST done mount -t tmpfs rw /rw mkdir -p /rw/etc @@ -536,6 +809,11 @@ EOMS print $inifile "mknod /sysroot/dev/console c 5 1\n"; print $inifile "exec switch_root -c /dev/console /sysroot /sbin/init\n"; close($inifile); + + + + + open($inifile,">"."/tmp/xcatinitrd.$$/bin/netstart"); print $inifile "#!/sbin/nash\n"; print $inifile "network --device $prinic --bootproto dhcp\n"; @@ -550,8 +828,8 @@ EOMS push @filestoadd,[$_,"lib/$_"]; } } - - foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod","sbin/mount.nfs") { + # add rsync for statelite + foreach ("bin/cpio","sbin/nash","sbin/busybox.anaconda","sbin/rmmod","sbin/mount.nfs","/usr/bin/rsync") { getlibs($_); push @filestoadd,$_; } @@ -728,9 +1006,7 @@ sub generic_post { #This function is meant to leave the image in a state approxi chmod(0755,"$rootimg_dir/etc/rc3.d/S60gettyset"); #link("$rootimg_dir/sbin/init","$rootimg_dir/init"); - rename(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); -} - + rename(<$rootimg_dir/boot/vmlinuz*>,"$destdir/kernel"); } #get th extra package name sub get_extra_package_names { @@ -848,10 +1124,26 @@ sub get_pkglist_file_name { } elsif (-r "$base/$profile.pkglist") { return "$base/$profile.pkglist"; } - return ""; } +sub get_rwfiles_file_name { + my $base=shift; + if (-r "$base/$profile.$osver.$arch.rwfiles") { + return "$base/$profile.$osver.$arch.rwfiles"; + } elsif (-r "$base/$profile.$arch.rwfiles") { + return "$base/$profile.$arch.rwfiles"; + } elsif (-r "$base/$profile.$osver.rwfiles") { + return "$base/$profile.$osver.rwfiles"; + } elsif (-r "$base/$profile.rwfiles") { + return "$base/$profile.rwfiles"; + } + return ""; +} + + + + sub get_postinstall_file_name { my $base=shift; if (-x "$base/$profile.$osver.$arch.postinstall") { @@ -867,3 +1159,4 @@ sub get_postinstall_file_name { return ""; } +