From 4c7148e8ed5ca0bd9cf10530ccc9b47b0ca0befb Mon Sep 17 00:00:00 2001 From: Mark Gurevich Date: Fri, 24 Jun 2016 13:16:38 -0400 Subject: [PATCH] Nodeset offline for ppc64 --- .../references/man8/nodeset.8.rst | 8 +- perl-xCAT/xCAT/Usage.pm | 2 +- xCAT-client/pods/man8/nodeset.8.pod | 8 +- xCAT-server/lib/xcat/plugins/grub2.pm | 94 ++++++++++++------- xCAT-server/lib/xcat/plugins/petitboot.pm | 50 +++++----- 5 files changed, 89 insertions(+), 73 deletions(-) diff --git a/docs/source/guides/admin-guides/references/man8/nodeset.8.rst b/docs/source/guides/admin-guides/references/man8/nodeset.8.rst index d8c0be67f..23ec24e23 100644 --- a/docs/source/guides/admin-guides/references/man8/nodeset.8.rst +++ b/docs/source/guides/admin-guides/references/man8/nodeset.8.rst @@ -19,7 +19,7 @@ Name **************** -\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ | \ **iscsiboot**\ | \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ] +\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ | \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ] \ **nodeset**\ \ *noderange*\ \ **osimage**\ [=\ *imagename*\ ] [\ **-**\ **-noupdateinitrd**\ ] [\ **-**\ **-ignorekernelchk**\ ] @@ -50,7 +50,7 @@ Assume that /tftpboot is the root for tftpd (set in site(5)|site.5). \ **nodeset**\ only sets the next boot state, but does not reboot. -\ **nodeset**\ is called by rinstall and winstall and is also called by the +\ **nodeset**\ is called by \ **rinstall**\ and \ **winstall**\ and is also called by the installation process remotely to set the boot state back to "boot". A user can supply their own scripts to be run on the mn or on the service node (if a hierarchical cluster) for a node when the nodeset command is run. Such scripts are called \ **prescripts**\ . They should be copied to /install/prescripts dirctory. A table called \ *prescripts*\ is used to specify the scripts and their associated actions. The scripts to be run at the beginning of the nodeset command are stored in the 'begin' column of \ *prescripts*\ table. The scripts to be run at the end of the nodeset command are stored in the 'end' column of \ *prescripts*\ table. You can run 'tabdump -d prescripts' command for details. The following two environment variables will be passed to each script: NODES contains all the names of the nodes that need to run the script for and ACTION contains the current nodeset action. If \ *#xCAT setting:MAX_INSTANCE=number*\ is specified in the script, the script will get invoked for each node in parallel, but no more than \ *number*\ of instances will be invoked at at a time. If it is not specified, the script will be invoked once for all the nodes. @@ -82,8 +82,8 @@ A user can supply their own scripts to be run on the mn or on the service node ( \ **-**\ **-noupdateinitrd**\ - Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drviers to initrd. But, the geninitrd command - should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of nodeset command. + Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drivers to initrd. But, the \ **geninitrd**\ command + should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of \ **nodeset**\ command. diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index e4ce30329..89be4615e 100755 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -461,7 +461,7 @@ Options: "Usage: Common: nodeset [-h|--help|-v|--version] - nodeset [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=]|offline|shutdown|stat]", + nodeset [shell|boot|runcmd=bmcsetup|osimage[=]|offline|shutdown|stat]", "rmflexnode" => "Usage: rmflexnode [-h|--help|-v|--version] diff --git a/xCAT-client/pods/man8/nodeset.8.pod b/xCAT-client/pods/man8/nodeset.8.pod index 835b7de8a..bc8e2fb46 100644 --- a/xCAT-client/pods/man8/nodeset.8.pod +++ b/xCAT-client/pods/man8/nodeset.8.pod @@ -4,7 +4,7 @@ B - set the boot state for a noderange =head1 B -B I [B | B | B | B | B | B[=I] | B | B] +B I [B | B | B | B | B[=I] | B | B] B I B[=I] [B<--noupdateinitrd>] [B<--ignorekernelchk>] @@ -31,7 +31,7 @@ B for yaboot makes changes to /tftpboot/etc/{node hex ip} B only sets the next boot state, but does not reboot. -B is called by rinstall and winstall and is also called by the +B is called by B and B and is also called by the installation process remotely to set the boot state back to "boot". A user can supply their own scripts to be run on the mn or on the service node (if a hierarchical cluster) for a node when the nodeset command is run. Such scripts are called B. They should be copied to /install/prescripts dirctory. A table called I is used to specify the scripts and their associated actions. The scripts to be run at the beginning of the nodeset command are stored in the 'begin' column of I table. The scripts to be run at the end of the nodeset command are stored in the 'end' column of I table. You can run 'tabdump -d prescripts' command for details. The following two environment variables will be passed to each script: NODES contains all the names of the nodes that need to run the script for and ACTION contains the current nodeset action. If I<#xCAT setting:MAX_INSTANCE=number> is specified in the script, the script will get invoked for each node in parallel, but no more than I of instances will be invoked at at a time. If it is not specified, the script will be invoked once for all the nodes. @@ -55,8 +55,8 @@ Prepare server for installing a node using the specified os image. The os image =item B<--noupdateinitrd> -Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drviers to initrd. But, the geninitrd command -should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of nodeset command. +Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drivers to initrd. But, the B command +should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of B command. =item B<--ignorekernelchk> diff --git a/xCAT-server/lib/xcat/plugins/grub2.pm b/xCAT-server/lib/xcat/plugins/grub2.pm index 15267f0da..d476df491 100644 --- a/xCAT-server/lib/xcat/plugins/grub2.pm +++ b/xCAT-server/lib/xcat/plugins/grub2.pm @@ -23,7 +23,7 @@ my $globaltftpdir = xCAT::TableUtils->getTftpDir(); my %usage = ( -"nodeset" => "Usage: nodeset [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=]|offline|shutdown|stat]", +"nodeset" => "Usage: nodeset [shell|boot|runcmd=bmcsetup|osimage[=]|offline|shutdown|stat]", ); sub handled_commands { @@ -78,7 +78,8 @@ sub getstate { chomp($headline); return $headline; } else { - return "boot"; + # There is no boot configuration file, node must be offline + return "offline"; } } else { return "discover"; @@ -181,19 +182,21 @@ sub setstate { my $nodemac; my %client_nethash = xCAT::DBobjUtils->getNetwkInfo([$node]); - open($pcfg, '>', $tftpdir . "/boot/grub2/" . $node); my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']); - if ($cref->{currstate}) { + + # remove the old boot configuration file and create a new one, but only if not offline directive + unlink($tftpdir . "/boot/grub2/" . $node); + if ($cref and $cref->{currstate} ne "offline") { + open($pcfg, '>', $tftpdir . "/boot/grub2/" . $node); print $pcfg "#" . $cref->{currstate} . "\n"; + + if (($::XCATSITEVALS{xcatdebugmode} eq "1") or ($::XCATSITEVALS{xcatdebugmode} eq "2")) { + print $pcfg "set debug=all\n"; + } + + print $pcfg "set timeout=5\n"; } - - if (($::XCATSITEVALS{xcatdebugmode} eq "1") or ($::XCATSITEVALS{xcatdebugmode} eq "2")) { - print $pcfg "set debug=all\n"; - } - - print $pcfg "set timeout=5\n"; - $normalnodes{$node} = 1; #Assume a normal netboot (well, normal dhcp, #which is normally with a valid 'filename' field, #but the typical ppc case will be 'special' makedhcp @@ -247,32 +250,34 @@ sub setstate { return; } + # write entries to boot config file, but only if not offline directive + if ($cref and $cref->{currstate} ne "offline") { + print $pcfg "set default=\"xCAT OS Deployment\"\n"; + print $pcfg "menuentry \"xCAT OS Deployment\" {\n"; + print $pcfg " insmod http\n"; + print $pcfg " insmod tftp\n"; + print $pcfg " set root=$grub2protocol,$serverip\n"; + print $pcfg " echo Loading Install kernel ...\n"; - print $pcfg "set default=\"xCAT OS Deployment\"\n"; - print $pcfg "menuentry \"xCAT OS Deployment\" {\n"; - print $pcfg " insmod http\n"; - print $pcfg " insmod tftp\n"; - print $pcfg " set root=$grub2protocol,$serverip\n"; - print $pcfg " echo Loading Install kernel ...\n"; + my $protocolrootdir = ""; + if ($grub2protocol =~ /^http$/) + { + $protocolrootdir = $tftpdir; + } - my $protocolrootdir = ""; - if ($grub2protocol =~ /^http$/) - { - $protocolrootdir = $tftpdir; + if ($kern and $kern->{kcmdline}) { + print $pcfg " linux $protocolrootdir/$kern->{kernel} $kern->{kcmdline}\n"; + } else { + print $pcfg " linux $protocolrootdir/$kern->{kernel}\n"; + } + print $pcfg " echo Loading initial ramdisk ...\n"; + if ($kern and $kern->{initrd}) { + print $pcfg " initrd $protocolrootdir/$kern->{initrd}\n"; + } + + print $pcfg "}"; + close($pcfg); } - - if ($kern and $kern->{kcmdline}) { - print $pcfg " linux $protocolrootdir/$kern->{kernel} $kern->{kcmdline}\n"; - } else { - print $pcfg " linux $protocolrootdir/$kern->{kernel}\n"; - } - print $pcfg " echo Loading initial ramdisk ...\n"; - if ($kern and $kern->{initrd}) { - print $pcfg " initrd $protocolrootdir/$kern->{initrd}\n"; - } - - print $pcfg "}"; - close($pcfg); my $inetn = xCAT::NetworkUtils->getipaddr($node); unless ($inetn) { syslog("local1|err", "xCAT unable to resolve IP for $node in grub2 plugin"); @@ -312,8 +317,11 @@ sub setstate { foreach $ip (keys %ipaddrs) { my @ipa = split(/\./, $ip); my $pname = "grub.cfg-" . sprintf("%02x%02x%02x%02x", @ipa); + # remove the old boot configuration file and copy (link) a new one, but only if not offline directive unlink($tftpdir . "/boot/grub2/" . $pname); - link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname); + if ($cref and $cref->{currstate} ne "offline") { + link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname); + } } if ($macstring) { $nodemac = xCAT::Utils->parseMacTabEntry($macstring, $node); @@ -323,8 +331,11 @@ sub setstate { my $tmp = lc($nodemac); $tmp =~ s/(..):(..):(..):(..):(..):(..)/$1-$2-$3-$4-$5-$6/g; my $pname = "grub.cfg-01-" . $tmp; + # remove the old boot configuration file and copy (link) a new one, but only if not offline directive unlink($tftpdir . "/boot/grub2/" . $pname); - link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname); + if ($cref and $cref->{currstate} ne "offline") { + link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname); + } } return; } @@ -713,6 +724,17 @@ sub process_request { } } + if ($args[0] eq 'offline') { + # If nodeset directive was offline we need to remove the architecture file link and remove dhcp entries + foreach my $osimage (keys %osimagenodehash) { + foreach my $tmp_node (@{ $osimagenodehash{$osimage} }) { + unlink( "$tftpdir/boot/grub2/grub2-$tmp_node"); + $sub_req->({ command => ['makedhcp'],arg=>['-d'], + node => \@{ $osimagenodehash{$osimage} } }, $callback); + } + } + } + #now run the end part of the prescripts unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') $errored = 0; diff --git a/xCAT-server/lib/xcat/plugins/petitboot.pm b/xCAT-server/lib/xcat/plugins/petitboot.pm index 8e082dd95..9409e1caf 100644 --- a/xCAT-server/lib/xcat/plugins/petitboot.pm +++ b/xCAT-server/lib/xcat/plugins/petitboot.pm @@ -63,7 +63,8 @@ sub getstate { chomp($headline); return $headline; } else { - return "boot"; + # There is no boot configuration file, node must be offline + return "offline"; } } else { return "discover"; @@ -168,10 +169,13 @@ sub setstate { } my $nodemac; - open($pcfg,'>',$tftpdir."/petitboot/".$node); my $cref=$chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']); - if ($cref->{currstate}) { - print $pcfg "#".$cref->{currstate}."\n"; + + # remove the old boot configuration file and create a new one, but only if not offline directive + unlink($tftpdir . "/petitboot/" . $node); + if ($cref and $cref->{currstate} ne "offline") { + open($pcfg,'>',$tftpdir."/petitboot/".$node); + print $pcfg "#".$cref->{currstate}."\n"; } $normalnodes{$node}=1; #Assume a normal netboot (well, normal dhcp, #which is normally with a valid 'filename' field, @@ -188,8 +192,8 @@ sub setstate { # arg=>['-s','filename = \"xcat/nonexistant_file_to_intentionally_break_netboot_for_localboot_to_work\";']},$callback); #print $pcfg "bye\n"; close($pcfg); - } elsif ($kern and $kern->{kernel}) { - #It's time to set yaboot for this node to boot the kernel.. + } elsif ($kern and $kern->{kernel} and $cref and $cref->{currstate} ne "offline") { + #It's time to set yaboot for this node to boot the kernel, but only if not offline directive print $pcfg "default xCAT\n"; print $pcfg "label xCAT\n"; print $pcfg "\tkernel $kern->{kernel}\n"; @@ -218,8 +222,11 @@ sub setstate { my @ipa=split(/\./,$ip); my $pname = sprintf("%02x%02x%02x%02x",@ipa); $pname = uc($pname); + # remove the old boot configuration file and copy (link) a new one, but only if not offline directive unlink($tftpdir."/".$pname); - link($tftpdir."/petitboot/".$node,$tftpdir."/".$pname); + if ($cref and $cref->{currstate} ne "offline") { + link($tftpdir."/petitboot/".$node,$tftpdir."/".$pname); + } return; } @@ -535,6 +542,14 @@ sub process_request { } } } + + if ($args[0] eq 'offline') { + # If nodeset directive was offline we need to remove dhcp entries + foreach my $node (@normalnodeset) { + $sub_req->({ command => ['makedhcp'],arg=>['-d'], + node => [$node] }, $callback); + } + } #now run the end part of the prescripts unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') @@ -560,27 +575,6 @@ sub process_request { } } -sub getstate { - my $node = shift; - my $tftpdir = shift; - unless ($tftpdir) { $tftpdir = _slow_get_tftpdir($node); } - if (check_dhcp($node)) { - if (-r $tftpdir . "/petitboot/".$node) { - my $fhand; - open ($fhand,$tftpdir . "/petitboot/".$node); - my $headline = <$fhand>; - close $fhand; - $headline =~ s/^#//; - chomp($headline); - return $headline; - } else { - return "boot"; - } - } else { - return "discover"; - } -} - #---------------------------------------------------------------------------- =head3 getNodesetStates returns the nodeset state for the given nodes. The possible nodeset