From f712b51ad6a93f36e5aa4db5f455d64c61ac9fc8 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Mon, 29 Jun 2009 18:37:45 +0000 Subject: [PATCH] -Move to using gPXE/http for a lot of traffic -Have pxe plugin handle addkcmdline git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3656 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/lib/xcat/plugins/dhcp.pm | 34 +++++++---- xCAT-server/lib/xcat/plugins/mknb.pm | 7 ++- xCAT-server/lib/xcat/plugins/pxe.pm | 91 ++++++++++++++++++++-------- 3 files changed, 93 insertions(+), 39 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/dhcp.pm b/xCAT-server/lib/xcat/plugins/dhcp.pm index d84cc16db..a6d85440c 100644 --- a/xCAT-server/lib/xcat/plugins/dhcp.pm +++ b/xCAT-server/lib/xcat/plugins/dhcp.pm @@ -226,21 +226,23 @@ sub addnode $lstatements = "next-server $nxtsrv;$statements"; } } + my $doiscsi=0; if ($ient and $ient->{server} and $ient->{target}) { + $doiscsi=1; if (defined ($ient->{lun})) { $lstatements = 'option root-path \"iscsi:'.$ient->{server}.':::'.$ient->{lun}.':'.$ient->{target}.'\";'.$lstatements; } else { $lstatements = 'option root-path \"iscsi:'.$ient->{server}.':::'.$ient->{lun}.':'.$ient->{target}.'\";'.$lstatements; } - if ($nrent and $nrent->{netboot} and $nrent->{netboot} eq 'pxe') { - if (-f "$tftpdir/undionly.kpxe") { - if ($chainent and $chainent->{currstate} and $chainent->{currstate} eq 'iscsiboot') { - $lstatements = 'if exists gpxe.bus-id { filename = \"\"; } else if exists client-architecture { filename = \"undionly.kpxe\"; } '.$lstatements; - } else { - $lstatements = 'if exists gpxe.bus-id { filename = \"pxelinux.0\"; } else if exists client-architecture { filename = \"undionly.kpxe\"; } '.$lstatements; #Only PXE compliant clients should ever receive gPXE - } - } #TODO: warn when windows - } + } + if ($nrent and $nrent->{netboot} and $nrent->{netboot} eq 'pxe') { + if (-f "$tftpdir/undionly.kpxe") { + if ($doiscsi and $chainent and $chainent->{currstate} and ($chainent->{currstate} eq 'iscsiboot' or $chainent->{currstate} eq 'boot')) { + $lstatements = 'if exists gpxe.bus-id { filename = \"\"; } else if exists client-architecture { filename = \"undionly.kpxe\"; } '.$lstatements; + } else { + $lstatements = 'if exists gpxe.bus-id { filename = \"xcat/xnba/nodes/'.$node.'\"; } else if exists client-architecture { filename = \"undionly.kpxe\"; } '.$lstatements; #Only PXE compliant clients should ever receive gPXE + } + } #TODO: warn when windows } @@ -845,8 +847,18 @@ sub addnet { push @netent, " option domain-name-servers $nameservers;\n"; } - push @netent, " if option client-architecture = 00:00 { #x86\n"; - push @netent, " filename \"pxelinux.0\";\n"; + my $tmpmaskn = unpack("N", inet_aton($mask)); + my $maskbits = 32; + while (not ($tmpmaskn & 1)) { + $maskbits--; + $tmpmaskn=$tmpmaskn>>1; + } + + # $lstatements = 'if exists gpxe.bus-id { filename = \"\"; } else if exists client-architecture { filename = \"undionly.kpxe\"; } '.$lstatements; + push @netent, " if exists gpxe.bus-id { #x86, gPXE\n"; + push @netent, " filename = \"xcat/xnba/nets/".$net."_".$maskbits."\";\n"; + push @netent, " } else if option client-architecture = 00:00 { #x86\n"; + push @netent, " filename \"undionly.kpxe\";\n"; push @netent, " } else if option vendor-class-identifier = \"Etherboot-5.4\" { #x86\n"; push @netent, " filename \"pxelinux.0\";\n"; push @netent, diff --git a/xCAT-server/lib/xcat/plugins/mknb.pm b/xCAT-server/lib/xcat/plugins/mknb.pm index 599c9e788..2aa41e782 100644 --- a/xCAT-server/lib/xcat/plugins/mknb.pm +++ b/xCAT-server/lib/xcat/plugins/mknb.pm @@ -107,6 +107,7 @@ sub process_request { if ($arch =~ /x86/) { mkpath("$tftpdir/xcat/xnba/nets"); chmod(0755,"$tftpdir/xcat/xnba"); + chmod(0755,"$tftpdir/xcat/xnba/nets"); mkpath("$tftpdir/pxelinux.cfg"); chmod(0755,"$tftpdir/pxelinux.cfg"); if (! -r "$tftpdir/pxelinux.0") { @@ -134,7 +135,7 @@ sub process_request { $dopxe=0; if ($arch =~ /x86/) { #only do pxe if just x86 or x86_64 and no x86 if ($arch =~ /x86_64/) { - if (-r "$tftpdir/xcat/xnba/$_.net") { + if (-r "$tftpdir/xcat/xnba/nets/$net") { my $cfg; my @contents; open($cfg,"<","$tftpdir/xcat/xnba/nets/$net"); @@ -154,8 +155,8 @@ sub process_request { my $cfg; open($cfg,">","$tftpdir/xcat/xnba/nets/$net"); print $cfg "#!gpxe\n"; - print $cfg 'imgfetch -n kernel tftp://${next-server}/xcat/nbk.'."$arch quiet xcatd=".$normnets->{$_}.":$xcatdport $consolecmdline\n"; - print $cfg 'imgfetch -n nbfs tftp://${next-server}/xcat/nbfs.'."$arch.gz\n"; + print $cfg 'imgfetch -n kernel http://${next-server}/tftpboot/xcat/nbk.'."$arch quiet xcatd=".$normnets->{$_}.":$xcatdport $consolecmdline\n"; + print $cfg 'imgfetch -n nbfs http://${next-server}/tftpboot/xcat/nbfs.'."$arch.gz\n"; print $cfg "imgload kernel\n"; print $cfg "imgexec kernel\n"; close($cfg); diff --git a/xCAT-server/lib/xcat/plugins/pxe.pm b/xCAT-server/lib/xcat/plugins/pxe.pm index a6c259648..3586259b3 100644 --- a/xCAT-server/lib/xcat/plugins/pxe.pm +++ b/xCAT-server/lib/xcat/plugins/pxe.pm @@ -4,6 +4,7 @@ use Data::Dumper; use Sys::Syslog; use Socket; use File::Copy; +use File::Path; my $request; my $callback; @@ -39,7 +40,16 @@ sub check_dhcp { sub getstate { my $node = shift; if (check_dhcp($node)) { - if (-r $tftpdir . "/pxelinux.cfg/".$node) { + if (-r $tftpdir . "/xcat/xnba/nodes/".$node) { + my $fhand; + open ($fhand,$tftpdir . "/xcat/xnba/nodes/".$node); + my $headline = <$fhand>; + $headline = <$fhand>; #second line is the comment now... + close $fhand; + $headline =~ s/^#//; + chomp($headline); + return $headline; + } elsif (-r $tftpdir . "/pxelinux.cfg/".$node) { my $fhand; open ($fhand,$tftpdir . "/pxelinux.cfg/".$node); my $headline = <$fhand>; @@ -66,6 +76,10 @@ sub setstate { my %chainhash = %{shift()}; my %machash = %{shift()}; my $kern = $bphash{$node}->[0]; #$bptab->getNodeAttribs($node,['kernel','initrd','kcmdline']); + if ($kern->{addkcmdline}) { #Implement the kcmdline append here for + #most generic, least code duplication + $kern->{kcmdline} .= " ".$kern->{addkcmdline}; + } if ($kern->{kcmdline} =~ /!myipfn!/) { my $ipfn = xCAT::Utils->my_ip_facing($node); unless ($ipfn) { @@ -83,37 +97,63 @@ sub setstate { $kern->{kcmdline} =~ s/!myipfn!/$ipfn/; } my $pcfg; - open($pcfg,'>',$tftpdir."/pxelinux.cfg/".$node); + open($pcfg,'>',$tftpdir."/xcat/xnba/nodes/".$node); my $cref=$chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']); + print $pcfg "#!gpxe\n"; if ($cref->{currstate}) { print $pcfg "#".$cref->{currstate}."\n"; } - print $pcfg "DEFAULT xCAT\n"; - print $pcfg "LABEL xCAT\n"; if ($cref and $cref->{currstate} eq "boot") { - print $pcfg "LOCALBOOT 0\n"; + print $pcfg "exit\n"; close($pcfg); } elsif ($kern and $kern->{kernel}) { - if ($kern->{kernel} =~ /!/) { - my $hypervisor; - my $kernel; - ($kernel,$hypervisor) = split /!/,$kern->{kernel}; - print $pcfg " KERNEL mboot.c32\n"; - print $pcfg " APPEND $hypervisor --- $kernel ".$kern->{kcmdline}." --- ".$kern->{initrd}."\n"; + if ($kern->{kernel} =~ /!/) { #TODO: deprecate this, do stateless Xen like stateless ESXi + my $hypervisor; + my $kernel; + ($kernel,$hypervisor) = split /!/,$kern->{kernel}; + print $pcfg " set 209:string xcat/xnba/nodes/$node.pxelinux\n"; + print $pcfg " set 210:string http://".'${next-server}'."/tftpboot/\n"; + print $pcfg " imgfetch -n pxelinux.0 http://".'${next-server}'."/tftpboot/pxelinux.0\n"; + print $pcfg " imgload pxelinux.0\n"; + print $pcfg " imgexec pxelinux.0\n"; + close($pcfg); + open($pcfg,'>',$tftpdir."/xcat/xnba/nodes/".$node.".pxelinux"); + print $pcfg "DEFAULT xCAT\nLABEL xCAT\n KERNEL mboot.c32\n"; + print $pcfg " APPEND $hypervisor --- $kernel ".$kern->{kcmdline}." --- ".$kern->{initrd}."\n"; } else { - #It's time to set pxelinux for this node to boot the kernel.. - print $pcfg " KERNEL ".$kern->{kernel}."\n"; - if ($kern->{initrd} or $kern->{kcmdline}) { - print $pcfg " APPEND "; - } - if ($kern and $kern->{initrd}) { - print $pcfg "initrd=".$kern->{initrd}." "; - } - if ($kern and $kern->{kcmdline}) { - print $pcfg $kern->{kcmdline}."\n"; - } else { - print $pcfg "\n"; - } + if ($kern->{kernel} =~ /\.c32\z/) { #gPXE comboot support seems insufficient, chain pxelinux instead + print $pcfg " set 209:string xcat/xnba/nodes/$node.pxelinux\n"; + print $pcfg " set 210:string http://".'${next-server}'."/tftpboot/\n"; + print $pcfg " imgfetch -n pxelinux.0 http://".'${next-server}'."/tftpboot/pxelinux.0\n"; + print $pcfg " imgload pxelinux.0\n"; + print $pcfg " imgexec pxelinux.0\n"; + close($pcfg); + open($pcfg,'>',$tftpdir."/xcat/xnba/nodes/".$node.".pxelinux"); + #It's time to set pxelinux for this node to boot the kernel.. + print $pcfg "DEFAULT xCAT\nLABEL xCAT\n"; + print $pcfg " KERNEL ".$kern->{kernel}."\n"; + if ($kern->{initrd} or $kern->{kcmdline}) { + print $pcfg " APPEND "; + } + if ($kern and $kern->{initrd}) { + print $pcfg "initrd=".$kern->{initrd}." "; + } + if ($kern and $kern->{kcmdline}) { + print $pcfg $kern->{kcmdline}."\n"; + } else { + print $pcfg "\n"; + } + } else { #other than comboot/multiboot, we won't have need of pxelinux + print $pcfg "imgfetch -n kernel http://".'${next-server}/tftpboot/'.$kern->{kernel}."\n"; + print $pcfg "imgload kernel\n"; + if ($kern->{kcmdline}) { + print $pcfg "imgargs kernel ".$kern->{kcmdline}."\n"; + } + if ($kern->{initrd}) { + print $pcfg "imgfetch http://".'${next-server}'."/tftpboot/".$kern->{initrd}."\n"; + } + print $pcfg "imgexec kernel\n"; + } } close($pcfg); my $inetn = inet_aton($node); @@ -324,9 +364,10 @@ sub process_request { my $bptab = xCAT::Table->new('bootparams',-create=>1); my $chaintab = xCAT::Table->new('chain'); my $mactab = xCAT::Table->new('mac'); #to get all the hostnames - my %bphash = %{$bptab->getNodesAttribs(\@nodes,[qw(kernel initrd kcmdline)])}; + my %bphash = %{$bptab->getNodesAttribs(\@nodes,[qw(kernel initrd kcmdline addkcmdline)])}; my %chainhash = %{$chaintab->getNodesAttribs(\@nodes,[qw(currstate)])}; my %machash = %{$mactab->getNodesAttribs(\@nodes,[qw(mac)])}; + mkpath($tftpdir."/xcat/xnba/nodes/"); foreach (@nodes) { my %response; $response{node}->[0]->{name}->[0]=$_;