From bb9f3935378f3150998aac71da2d70d91f47a4e0 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Fri, 11 Jul 2008 19:02:39 +0000 Subject: [PATCH] -Further nodeset 'netboot' improvements. moncfgmaster is the bulk of time now. moncfgmaster speedups are the next logical step. At scale setNodesAttribs call would be the one following that. Without moncfgmaster, the nodeset for 541 servers is now 15 seconds (mostly due to lack of setNodesAttribs) git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@1868 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/lib/xcat/plugins/anaconda.pm | 27 +++++++----- xCAT-server/lib/xcat/plugins/destiny.pm | 54 +++++++++++++++--------- xCAT-server/lib/xcat/plugins/pxe.pm | 30 ++++++++----- 3 files changed, 70 insertions(+), 41 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/anaconda.pm b/xCAT-server/lib/xcat/plugins/anaconda.pm index d8410bdd8..2bd36095d 100644 --- a/xCAT-server/lib/xcat/plugins/anaconda.pm +++ b/xCAT-server/lib/xcat/plugins/anaconda.pm @@ -80,14 +80,15 @@ sub preprocess_request my %localnodehash; my %dispatchhash; my $nrtab = xCAT::Table->new('noderes'); + my $nrents = $nrtab->getNodesAttribs($req->{node},[qw(tftpserver servicenode)]); foreach my $node (@{$req->{node}}) { my $nodeserver; - my $tent = $nrtab->getNodeAttribs($node, ['tftpserver']); + my $tent = $nrents->{$node}->[0]; #$nrtab->getNodeAttribs($node, ['tftpserver']); if ($tent) { $nodeserver = $tent->{tftpserver} } unless ($tent and $tent->{tftpserver}) { - $tent = $nrtab->getNodeAttribs($node, ['servicenode']); + $tent = $nrents->{$node}->[0]; #$nrtab->getNodeAttribs($node, ['servicenode']); if ($tent) { $nodeserver = $tent->{servicenode} } } if ($nodeserver) @@ -161,6 +162,13 @@ sub mknetboot } my %donetftp=(); my %oents = %{$ostab->getNodesAttribs(\@nodes,[qw(os arch profile)])}; + my $restab = xCAT::Table->new('noderes'); + my $bptab = xCAT::Table->new('bootparams',-create=>1); + my $hmtab = xCAT::Table->new('nodehm'); + my $reshash = $restab->getNodesAttribs(\@nodes, ['primarynic','tftpserver','xcatmaster']); + my $hmhash = + $hmtab->getNodesAttribs(\@nodes, + ['serialport', 'serialspeed', 'serialflow']); foreach $node (@nodes) { my $ent = $oents{$node}->[0]; #ostab->getNodeAttribs($node, ['os', 'arch', 'profile']); @@ -249,26 +257,23 @@ sub mknetboot ); next; } - my $restab = xCAT::Table->new('noderes'); - my $bptab = xCAT::Table->new('bootparams',-create=>1); - my $hmtab = xCAT::Table->new('nodehm'); - my $ent = $restab->getNodeAttribs($node, ['primarynic']); - my $sent = - $hmtab->getNodeAttribs($node, - ['serialport', 'serialspeed', 'serialflow']); + my $ent = $reshash->{$node}->[0];#$restab->getNodeAttribs($node, ['primarynic']); + my $sent = $hmhash->{$node}->[0]; +# $hmtab->getNodeAttribs($node, +# ['serialport', 'serialspeed', 'serialflow']); # determine image server, if tftpserver use it, else use xcatmaster # else use site.Master, last resort use self my $imgsrv; my $ient; - $ient = $restab->getNodeAttribs($node, ['tftpserver']); + $ient = $reshash->{$node}->[0]; #$restab->getNodeAttribs($node, ['tftpserver']); if ($ient and $ient->{tftpserver}) { $imgsrv = $ient->{tftpserver}; } else { - $ient = $restab->getNodeAttribs($node, ['xcatmaster']); + $ient = $reshash->{node}->[0]; #$restab->getNodeAttribs($node, ['xcatmaster']); if ($ient and $ient->{xcatmaster}) { $imgsrv = $ient->{xcatmaster}; diff --git a/xCAT-server/lib/xcat/plugins/destiny.pm b/xCAT-server/lib/xcat/plugins/destiny.pm index e10fb0bbc..8c845d295 100644 --- a/xCAT-server/lib/xcat/plugins/destiny.pm +++ b/xCAT-server/lib/xcat/plugins/destiny.pm @@ -11,6 +11,15 @@ my $callback; my $subreq; my $errored = 0; +#DESTINY SCOPED GLOBALS +my $chaintab; +my $iscsitab; +my $bptab; +my $typetab; +my $restab; +my $sitetab; +my $hmtab; + sub handled_commands { return { setdestiny => "destiny", @@ -48,7 +57,7 @@ sub relay_response { sub setdestiny { my $req=shift; - my $chaintab = xCAT::Table->new('chain',-create=>1); + $chaintab = xCAT::Table->new('chain',-create=>1); my @nodes=@{$req->{node}}; my $state = $req->{arg}->[0]; my %nstates; @@ -59,9 +68,10 @@ sub setdestiny { unless ($iscsitab) { $callback->({error=>"Unable to open iscsi table to get iscsiboot parameters",errorcode=>[1]}); } - my $bptab = xCAT::Table->new('bootparams'); + my $bptab = xCAT::Table->new('bootparams',-create=>1); + my $ients = $iscsitab->getNodesAttribs($req->{node},[qw(kernel kcmdline initrd)]); foreach (@{$req->{node}}) { - my $ient = $iscsitab->getNodeAttribs($_,[qw(kernel kcmdline initrd)]); + my $ient = $ients->{$_}->[0]; #$iscsitab->getNodeAttribs($_,[qw(kernel kcmdline initrd)]); unless ($ient and $ient->{kernel}) { $callback->({error=>"$_: No iscsi boot data available",errorcode=>[1]}); next; @@ -78,9 +88,10 @@ sub setdestiny { node=>$req->{node}}, \&relay_response); if ($errored) { return; } my $nodetype = xCAT::Table->new('nodetype'); + my $ntents = $nodetype->getNodesAttribs($req->{node},[qw(os arch profile)]); foreach (@{$req->{node}}) { $nstates{$_} = $state; #local copy of state variable for mod - my $ntent = $nodetype->getNodeAttribs($_,[qw(os arch profile)]); + my $ntent = $ntents->{$_}->[0]; #$nodetype->getNodeAttribs($_,[qw(os arch profile)]); if ($ntent and $ntent->{os}) { $nstates{$_} .= " ".$ntent->{os}; } else { $errored =1; $callback->({error=>"nodetype.os not defined for $_"}); } @@ -94,21 +105,24 @@ sub setdestiny { unless ($state =~ /^netboot/) { $chaintab->setNodeAttribs($_,{currchain=>"boot"}); }; } } elsif ($state eq "shell" or $state eq "standby" or $state =~ /^runcmd/ or $state =~ /^runimage/) { - my $noderes=xCAT::Table->new('noderes',-create=>1); + $restab=xCAT::Table->new('noderes',-create=>1); my $bootparms=xCAT::Table->new('bootparams',-create=>1); my $nodetype = xCAT::Table->new('nodetype'); my $sitetab = xCAT::Table->new('site'); my $nodehm = xCAT::Table->new('nodehm'); + my $hments = $nodehm->getNodesAttribs(\@nodes,['serialport','serialspeed','serialflow']); (my $portent) = $sitetab->getAttribs({key=>'xcatdport'},'value'); (my $mastent) = $sitetab->getAttribs({key=>'master'},'value'); + my $enthash = $nodetype->getNodesAttribs(\@nodes,[qw(arch)]); + my $resents = $restab->getNodeAttribs(\@nodes,[qw(xcatmaster)]); foreach (@nodes) { - my $ent = $nodetype->getNodeAttribs($_,[qw(arch)]); + my $ent = $enthash->{$_}->[0]; #$nodetype->getNodeAttribs($_,[qw(arch)]); unless ($ent and $ent->{arch}) { $callback->({error=>["No archictecture defined in nodetype table for $_"],errorcode=>[1]}); return; } my $arch = $ent->{arch}; - my $ent = $noderes->getNodeAttribs($_,[qw(xcatmaster)]); + my $ent = $resents->{$_}->[0]; #$restab->getNodeAttribs($_,[qw(xcatmaster)]); my $master; my $kcmdline = "quiet "; if ($mastent and $mastent->{value}) { @@ -117,7 +131,7 @@ sub setdestiny { if ($ent and $ent->{xcatmaster}) { $master = $ent->{xcatmaster}; } - $ent = $nodehm->getNodeAttribs($_,['serialport','serialspeed','serialflow']); + $ent = $hments->{$_}->[0]; #$nodehm->getNodeAttribs($_,['serialport','serialspeed','serialflow']); if ($ent and defined($ent->{serialport})) { $kcmdline .= "console=ttyS".$ent->{serialport}; #$ent = $nodehm->getNodeAttribs($_,['serialspeed']); @@ -145,7 +159,6 @@ sub setdestiny { initrd => "xcat/nbfs.$arch.gz", kcmdline => $kcmdline."xcatd=$master:$xcatdport"}); } - $nodetype->close; } elsif (!($state eq "boot")) { $callback->({error=>["Unknown state $state requested"],errorcode=>[1]}); return; @@ -190,16 +203,16 @@ sub nextdestiny { } my $node; + $chaintab = xCAT::Table->new('chain'); + my $chainents = $chaintab->getNodesAttribs(\@nodes,[qw(currstate currchain chain)]); foreach $node (@nodes) { - my $chaintab = xCAT::Table->new('chain'); unless($chaintab) { syslog("local1|err","ERROR: $node requested destiny update, no chain table"); return; #nothing to do... } - my $ref = $chaintab->getNodeAttribs($node,[qw(currstate currchain chain)]); + my $ref = $chainents->{$node}->[0]; #$chaintab->getNodeAttribs($node,[qw(currstate currchain chain)]); unless ($ref->{chain} or $ref->{currchain}) { syslog ("local1|err","ERROR: node requested destiny update, no path in chain.currchain"); - $chaintab->close; return; #Can't possibly do anything intelligent.. } unless ($ref->{currchain}) { #If no current chain, copy the default @@ -213,7 +226,6 @@ sub nextdestiny { $ref->{currchain} = $ref->{currstate}; } $chaintab->setNodeAttribs($node,$ref); #$ref is in a state to commit back to db - $chaintab->close; my %requ; $requ{node}=[$node]; $requ{arg}=[$ref->{currstate}]; @@ -249,13 +261,20 @@ sub getdestiny { @nodes=($node); } my $node; + $restab = xCAT::Table->new('noderes'); + my $chainents = $chaintab->getNodesAttribs(\@nodes,[qw(currstate chain)]); + my $nrents = $restab->getNodesAttribs(\@nodes,[qw(tftpserver xcatmaster)]); + $bptab = xCAT::Table->new('bootparams',-create=>1); + my $bpents = $bptab->getNodesAttribs(\@nodes,[qw(kernel initrd kcmdline xcatmaster)]); + my $sitetab= xCAT::Table->new('site'); + (my $sent) = $sitetab->getAttribs({key=>'master'},'value'); foreach $node (@nodes) { my $chaintab = xCAT::Table->new('chain'); unless ($chaintab) { #Without destiny, have the node wait with ssh hopefully open at least $callback->({node=>[{name=>[$node],data=>['standby'],destiny=>[ 'standby' ]}]}); return; } - my $ref = $chaintab->getNodeAttribs($node,[qw(currstate chain)]); + my $ref = $chainents->{$node}->[0]; #$chaintab->getNodeAttribs($node,[qw(currstate chain)]); unless ($ref) { $callback->({node=>[{name=>[$node],data=>['standby'],destiny=>[ 'standby' ]}]}); return; @@ -265,15 +284,12 @@ sub getdestiny { $ref->{currstate} = shift @chain; $chaintab->setNodeAttribs($node,{currstate=>$ref->{currstate}}); } - my $noderestab = xCAT::Table->new('noderes',-create=>1); #In case client decides to download images, get data out to it my %response; $response{name}=[$node]; $response{data}=[$ref->{currstate}]; $response{destiny}=[$ref->{currstate}]; - my $sitetab= xCAT::Table->new('site'); - my $nrent = $noderestab->getNodeAttribs($node,[qw(tftpserver xcatmaster)]); - my $bpent = $noderestab->getNodeAttribs($node,[qw(kernel initrd kcmdline xcatmaster)]); - (my $sent) = $sitetab->getAttribs({key=>'master'},'value'); + my $nrent = $nrents->{$node}->[0]; #$noderestab->getNodeAttribs($node,[qw(tftpserver xcatmaster)]); + my $bpent = $bpents->{$node}->[0]; #$bptab->getNodeAttribs($node,[qw(kernel initrd kcmdline xcatmaster)]); if (defined $bpent->{kernel}) { $response{kernel}=$bpent->{kernel}; } diff --git a/xCAT-server/lib/xcat/plugins/pxe.pm b/xCAT-server/lib/xcat/plugins/pxe.pm index d2381ba17..c86a9cfeb 100644 --- a/xCAT-server/lib/xcat/plugins/pxe.pm +++ b/xCAT-server/lib/xcat/plugins/pxe.pm @@ -62,20 +62,19 @@ sub setstate { =cut my $node = shift; - my $bptab = xCAT::Table->new('bootparams',-create=>1); - my $kern = $bptab->getNodeAttribs($node,['kernel','initrd','kcmdline']); + my %bphash = %{shift()}; + my %chainhash = %{shift()}; + my %machash = %{shift()}; + my $kern = $bphash{$node}->[0]; #$bptab->getNodeAttribs($node,['kernel','initrd','kcmdline']); my $pcfg; open($pcfg,'>',$tftpdir."/pxelinux.cfg/".$node); - my $chaintab = xCAT::Table->new('chain'); - my $cref=$chaintab->getNodeAttribs($node,['currstate']); + my $cref=$chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']); if ($cref->{currstate}) { print $pcfg "#".$cref->{currstate}."\n"; } print $pcfg "DEFAULT xCAT\n"; print $pcfg "LABEL xCAT\n"; - $chaintab = xCAT::Table->new('chain'); - my $stref = $chaintab->getNodeAttribs($node,['currstate']); - if ($stref and $stref->{currstate} eq "boot") { + if ($cref and $cref->{currstate} eq "boot") { print $pcfg "LOCALBOOT 0\n"; close($pcfg); } elsif ($kern and $kern->{kernel}) { @@ -104,6 +103,10 @@ sub setstate { } my $mactab = xCAT::Table->new('mac'); #to get all the hostnames my %ipaddrs; + unless (inet_aton($node)) { + syslog("local1|err","xCAT unable to resolve IP in pxe plugin"); + return; + } my $ip = inet_ntoa(inet_aton($node));; unless ($ip) { syslog("local1|err","xCAT unable to resolve IP in pxe plugin"); @@ -111,7 +114,7 @@ sub setstate { } $ipaddrs{$ip} = 1; if ($mactab) { - my $ment = $mactab->getNodeAttribs($node,['mac']); + my $ment = $machash{$node}->[0]; #$mactab->getNodeAttribs($node,['mac']); if ($ment and $ment->{mac}) { my @macs = split(/\|/,$ment->{mac}); foreach (@macs) { @@ -274,16 +277,21 @@ sub process_request { arg=>[$args[0]]},\&pass_along); } if ($errored) { return; } + #Time to actually configure the nodes, first extract database data with the scalable calls + 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 %chainhash = %{$chaintab->getNodesAttribs(\@nodes,[qw(currstate)])}; + my %machash = %{$mactab->getNodesAttribs(\@nodes,[qw(mac)])}; foreach (@nodes) { my %response; $response{node}->[0]->{name}->[0]=$_; if ($args[0] eq 'stat') { $response{node}->[0]->{data}->[0]= getstate($_); $callback->(\%response); - } elsif ($args[0] eq 'enact') { - setstate($_); } elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate - setstate($_); + setstate($_,\%bphash,\%chainhash,\%machash); } }