Commit 7cfa7aa6 authored by David Johnson's avatar David Johnson

libosload rewrite and HP Procurve switch support.

libosload_new contains the new libosload.  It provides the same
API as the original libosload, but the functionality has been
split out into well-defined methods that can be overridden by
per-node type subclasses in small chunks.  This is all protected
by the NewOsload feature.

libosload_switch.pm.in and libossetup_switch.pm.in contain the HP
switch support, which requires the new libosload and new
libossetup.  libossetup_switch doesn't do anything too radical, but
it does support running a node it is "lighting up" through multiple
operations -- i.e., first a RELOAD, then a RECONFIG.  This was
necessary because switches require a config to be pushed to them
(well, they do in the way I elected to support them), and they
cannot fetch configuration in the normal Emulab way via tmcd.

Eventually, that multi-op support will be factored out into
libossetup more generically so that other node types which require
push-based configuration can leverage it.

libosload_switch contains the HP switch loading code.  It's built
around expect-like interaction on the serial console.  It supports
xmodem and tftp uploads, but tries to only flash the switch lazily.
Thus, if the switch is already loaded with an image and a user
(or the reload daemon, or anybody) reloads it with the same image,
it won't actually get reloaded.  You can now force this reload
with os_load.

libosload_switch also contains reconfig code (i.e., to wipe
switch configs and recreate based on which experiment it is in).
libossetup_switch directly invokes this instead of going through
libosload, since configuring is not really part of loading.  It
is just convenient since configuration also happens over the
serial console, and all the osload code for the switch can be
reused.

Also, of course, there are miscellaneous changes to support the
new libosload in os_load itself.
parent 649a30ac
......@@ -89,7 +89,8 @@ LIB_STUFF = libtbsetup.pm exitonwarn.pm libtestbed.pm snmpit_intel.pm \
libadminmfs.pm libtblog.pm libtblog_simple.pm libArchive.pm \
power_mail.pm power_whol.pm Template.pm power_rmcp.pm \
power_ilo.pm libvtop.pm libptop.pm libossetup.pm \
power_ipmi.pm
power_ipmi.pm libosload_new.pm libosload_switch.pm \
libossetup_switch.pm
# These scripts installed setuid, with sudo.
SETUID_BIN_SCRIPTS = node_reboot eventsys_control tarfiles_setup savelogs \
......
This diff is collapsed.
This diff is collapsed.
......@@ -28,6 +28,7 @@ use NodeType;
use libtblog;
use English;
use Data::Dumper;
use EmulabFeatures;
# Configure variables
my $TB = "@prefix@";
......@@ -73,6 +74,7 @@ sub New($$$@)
my $self = {};
$self->{'USER'} = $user;
$self->{'EXPT'} = $experiment;
$self->{'GROUP'} = (defined($experiment)) ? $experiment->GetGroup() : undef;
$self->{'HASH'} = {};
$self->{'NODES'} = {};
$self->{'PHYSNODES'} = {};
......@@ -99,6 +101,15 @@ sub New($$$@)
# XXX
$self->noretry(0);
$self->canceled(0);
if (EmulabFeatures->FeatureEnabled("NewOsload",$user,
$self->{'GROUP'},$experiment)) {
print STDERR "libossetup New NewOsload enabled\n";
require libosload_new;
# XXX -- @nodelist
$self->loadobj(libosload_new->New());
}
return $self;
}
# Break circular reference someplace to avoid exit errors.
......@@ -118,6 +129,7 @@ sub sharednodes($) { return $_[0]->{'SHAREDNODES'}; }
sub oplist($) { return $_[0]->{'OPLIST'}; }
sub user($) { return $_[0]->{'USER'}; }
sub experiment($) { return $_[0]->{'EXPT'}; }
sub group($) { return $_[0]->{'GROUP'}; }
sub IncrFailCount($) { $_[0]->{'FAILCOUNT'}++ }
sub failed($) { return $_[0]->{'FAILCOUNT'}; }
......@@ -529,8 +541,23 @@ sub LightUpNodes($@)
$reload_args{'nodelist'} = [ @list ];
$reload_args{'nodeflags'} = \%nodeflags;
my $pid = osload(\%reload_args, $reload_failures);
push(@children, [ $pid, \&osload_wait,
my $pid;
my $coderef;
if (EmulabFeatures->FeatureEnabled("NewOsload",$self->user(),
$self->group(),
$self->experiment())) {
($self->loadobj())->debug($self->debug());
$pid = ($self->loadobj())->osload(\%reload_args, $reload_failures);
$coderef = sub {
my $childpid = shift;
return ($self->loadobj())->osload_wait($childpid);
};
}
else {
$pid = osload(\%reload_args, $reload_failures);
$coderef = \&osload_wait;
}
push(@children, [ $pid, $coderef, ,
[ @list ], $reload_failures ]);
sleep(5);
}
......@@ -792,6 +819,10 @@ sub NewType($$)
if ($type eq "pcfedphys" || $type eq "pcfed") {
$type = "protogeni";
}
# elsif ($type eq 'hp5406') {
# print STDERR "changing type from $type to switch\n";
# $type = "switch";
# }
elsif (defined($typeinfo) && $typeinfo->issubnode()) {
$type = "subnode";
}
......@@ -800,12 +831,17 @@ sub NewType($$)
my $newtype = eval { $packname->New($self); };
# Not loaded?
if ($@) {
#print STDERR $@;
return undef;
print STDERR "module load failed: " . $@ . "\n";
eval "require libossetup_$type";
$newtype = eval { $packname->New($self); };
if ($@) {
print STDERR "module load failed: " . $@ . "\n";
return undef;
}
}
$self->{'TYPECACHE'}->{$type} = $newtype;
print STDERR "Created type object $type\n"
print STDERR "Created type object $type with parent $self\n"
if ($self->debug());
return $newtype;
......@@ -854,6 +890,8 @@ use English;
use Data::Dumper;
use overload ('""' => 'Stringify');
use vars qw($AUTOLOAD);
sub New($$$)
{
my ($class, $type, $parent) = @_;
......@@ -862,6 +900,7 @@ sub New($$$)
$self->{'TYPE'} = $type;
$self->{'NODES'} = {};
$self->{'PARENT'} = $parent;
print STDERR "just set parent in $self to $parent\n";
$self->{'FAILCOUNT'} = 0;
$self->{'TODOLIST'} = {};
......@@ -877,6 +916,23 @@ sub todo($) { return $_[0]->{'TODOLIST'}; }
sub todolist($) { return values(%{ $_[0]->{'TODOLIST'} }); }
sub IncrFailCount($) { $_[0]->{'FAILCOUNT'}++ }
sub AUTOLOAD {
my $self = shift;
my $type = ref($self) or die("$self is not an object\n");
my $name = $AUTOLOAD;
$name =~ s/.*://; # strip fully-qualified portion
if (@_) {
return $self->{'HASH'}->{$name} = shift;
}
elsif (exists($self->{'HASH'}->{$name})) {
return $self->{'HASH'}->{$name};
}
print STDERR "$self: tried to access unknown slot $name\n";
return undef;
}
#
# Add a node to the list.
#
......@@ -894,6 +950,7 @@ sub AddNode($$)
# This sets the OS that should boot, as well as any reloads, reboots
# and reconfigs that are needed.
#
print STDERR "trying get parent in $self\n";
$self->parent()->SetOS($node);
return 0;
}
......@@ -1262,7 +1319,15 @@ sub AddNode($$)
$reload_args{'imageid'} = $image->imageid();
$reload_args{'nodelist'} = [ $node_id ];
osload(\%reload_args, $reload_failures);
if (EmulabFeatures->FeatureEnabled("NewOsload",$self->user(),
$self->group(),
$self->experiment())) {
($parent->loadobj())->debug($self->debug());
($parent->loadobj())->osload(\%reload_args, $reload_failures);
}
else {
osload(\%reload_args, $reload_failures)
}
# Reset this. Updated in Volunteers() below.
$node->_setupoperation($libossetup::NOSTATE);
......
This diff is collapsed.
......@@ -32,10 +32,12 @@ sub usage()
" style==0: do not zero (same as not using -z)\n".
" style==1: let frisbee do the zeroing\n".
" style==2: zero disk before running frisbee\n".
"Use -P to prepare the disk as if a whole disk image was loaded\n");
"Use -P to prepare the disk as if a whole disk image was loaded\n".
"Use -F to force the load if Emulab tries to optimize it away\n".
"Use -R to push a reconfig to the node after the reload\n");
exit(-1);
}
my $optlist = "swldi:e:p:m:rz:Pc";
my $optlist = "swldi:e:p:m:rz:PcRF";
my $waitmode = 1;
my $listonly = 0;
my $debug = 0;
......@@ -43,6 +45,8 @@ my $noreboot = 0;
my $zerofree = 0;
my $prepare = 0;
my $usecurrent= 0;
my $reconfig = 0;
my $force = 0;
my @nodes = ();
my $imagepid;
my $pid;
......@@ -62,6 +66,8 @@ use Experiment;
use Node;
use OSinfo;
use Image;
use EmulabFeatures;
use User;
# Be careful not to exit on transient error
$libdb::DBQUERY_MAXTRIES = 30;
......@@ -103,11 +109,16 @@ $prepare = 1
if (defined($options{"P"}));
$usecurrent = 1
if (defined($options{"c"}));
$reconfig = 1
if (defined($options{"R"}));
$force = 1
if (defined($options{"F"}));
#
# Figure out which nodes. Choice of nodes on command line, or all nodes in an
# experiment. To get all free nodes, must use sched_reload.
#
my $experiment;
if (defined($options{"e"})) {
usage()
if (@ARGV);
......@@ -118,7 +129,7 @@ if (defined($options{"e"})) {
$pid = $1;
$eid = $2;
my $experiment = Experiment->Lookup($pid, $eid);
$experiment = Experiment->Lookup($pid, $eid);
if (!defined($experiment)) {
die("*** $0:\n".
" No such experiment $pid/$eid!\n");
......@@ -322,6 +333,26 @@ $osloadargs{'imageids'} = [ @imageids ]
$osloadargs{'swapinfo'} = 1;
$osloadargs{'usecurrent'} = $usecurrent;
my $user = User->ThisUser();
if (EmulabFeatures->FeatureEnabled("NewOsload",$user,undef,$experiment)) {
require libosload_new;
my $loadobj = libosload_new->New();
$loadobj->debug($debug);
#
# XXX basically, tell devices that try not to reload (like switches)
# that they really need to do it -- if the user or reload daemon actually
# invokes this script, we *have* to reload!
#
$osloadargs{'force'} = $force;
#
# XXX basically, tell devices that might be reconfig'd via push from us
# (like switches) that a reconfig should follow the reload!
#
$osloadargs{'reconfig'} = $reconfig;
exit($loadobj->osload(\%osloadargs, \%failednodes));
}
exit(osload(\%osloadargs, \%failednodes));
# Print a listing of imageids.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment