Commit 858145b2 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents 0527e3ee 84ddb1d4
......@@ -80,7 +80,6 @@ boss-install: $(addprefix $(INSTALL_BINDIR)/, $(BIN_SCRIPTS)) \
$(addprefix $(INSTALL_DIR)/opsdir/lib/, $(USERLIBS))
post-install:
chown root $(INSTALL_SBINDIR)/subboss_dhcpd_makeconf
chown root $(INSTALL_SBINDIR)/genelists
chmod u+s $(INSTALL_SBINDIR)/genelists
chown root $(INSTALL_SBINDIR)/dhcpd_makeconf
......
......@@ -592,6 +592,46 @@ sub IsReserved($)
return 1;
}
sub GetSubboss($$)
{
my ($self, $service, $subboss_id) = @_;
return 0
if (! ref($self));
my $ref;
if (defined $self->{"SUBBOSSES"}) {
my $ref = $self->{"SUBBOSSES"}->{$service};
}
if (!defined $ref) {
my $nodeid = $self->node_id();
my $query_result =
DBQueryWarn("select * from subbosses " .
"where node_id='$nodeid' and " .
"service = '$service'");
return 0
if (!$query_result);
return 0
if (!$query_result->numrows);
if (!defined($self->{"SUBBOSSES"})) {
$self->{"SUBBOSSES"} = {};
}
$ref = $self->{"SUBBOSSES"}->{$service} =
$query_result->fetchrow_hashref();
}
$$subboss_id = $ref->{'subboss_id'};
return 0;
}
#
# Flush the reserve info so it reloads.
#
......
......@@ -664,27 +664,33 @@ sub MapNodes($$)
}
$node = $pnode;
}
my $interface = Interface->LookupByIface($node,$iface);
if (!defined($interface)) {
print STDERR "Could not map iface for $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
}
if (!defined($MAC)) {
print STDERR "No mac (or vmac) for $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
}
if (! ($MAC =~ /^[\w]*$/)) {
print STDERR "Bad mac '$MAC' for $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
}
if ($interface->Update({"mac" => "$MAC"})) {
print STDERR "Could not update $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
#
# If the interface is the loopback, then we do not need
# to do this.
#
if ($iface ne "lo0" && $iface ne "loopback") {
my $interface = Interface->LookupByIface($node,$iface);
if (!defined($interface)) {
print STDERR "Could not map iface for $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
}
if (!defined($MAC)) {
print STDERR "No mac (or vmac) for $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
}
if (! ($MAC =~ /^[\w]*$/)) {
print STDERR "Bad mac '$MAC' for $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
}
if ($interface->Update({"mac" => "$MAC"})) {
print STDERR "Could not update $node,$iface\n";
print STDERR "$manifest_string\n";
return -1;
}
}
if (defined($VMAC)) {
my $vinterface =
......
......@@ -43,7 +43,7 @@ SBIN_STUFF = resetvlans console_setup.proxy sched_reload named_setup \
elabinelab snmpit.proxy panic node_attributes \
nfstrace plabinelab smbpasswd_setup smbpasswd_setup.proxy \
rmproj snmpit.proxynew snmpit.proxyv2 pool_daemon \
checknodes_daemon
checknodes_daemon subboss_frisbeelauncher_wrapper
ifeq ($(ISMAINSITE),1)
SBIN_STUFF += repos_daemon
endif
......@@ -95,7 +95,7 @@ SETUID_BIN_SCRIPTS = node_reboot eventsys_control tarfiles_setup savelogs \
SETUID_SBIN_SCRIPTS = mkproj rmgroup mkgroup frisbeelauncher frisbeeimage \
rmuser idleswap named_setup exports_setup \
sfskey_update setgroups newnode_reboot vnode_setup \
elabinelab nfstrace rmproj
elabinelab nfstrace rmproj subboss_frisbeelauncher_wrapper
SETUID_LIBX_SCRIPTS = console_setup spewlogfile
ifeq ($(SYSTEM),FreeBSD)
......@@ -231,6 +231,8 @@ endif
chmod u+s $(INSTALL_SBINDIR)/mkgroup
chown root $(INSTALL_SBINDIR)/frisbeelauncher
chmod u+s $(INSTALL_SBINDIR)/frisbeelauncher
chown root $(INSTALL_SBINDIR)/subboss_frisbeelauncher_wrapper
chmod u+s $(INSTALL_SBINDIR)/subboss_frisbeelauncher_wrapper
chown root $(INSTALL_SBINDIR)/frisbeeimage
chmod u+s $(INSTALL_SBINDIR)/frisbeeimage
chown root $(INSTALL_SBINDIR)/rmuser
......
......@@ -45,6 +45,7 @@ my $PROJROOT = "@PROJROOT_DIR@";
my $MAXRETRIES = 1;
my $FRISBEELAUNCHER = "$TB/sbin/frisbeelauncher";
my $SUBBOSS_FRISBEELAUNCHER = "$TB/sbin/subboss_frisbeelauncher_wrapper";
my $osselect = "$TB/bin/os_select";
my $TBUISP = "$TB/bin/tbuisp";
......@@ -452,6 +453,7 @@ sub osload ($$) {
my $class = $nodeobject->class();
my $isremote = $nodeobject->isremotenode();
my $isvirtnode = $nodeobject->isvirtnode();
my $subboss;
my $reload_mode;
my $reload_func;
my $reboot_required;
......@@ -465,6 +467,7 @@ sub osload ($$) {
$reload_mode = "Frisbee";
$reload_func = \&SetupReloadFrisbee;
$reboot_required = !$noreboot; # Reboot unless $noreboot flag set
$nodeobject->GetSubboss('frisbee', \$subboss);
if (defined($nodeflags{$node})
&& defined($nodeflags{$node}{'noreboot'})) {
......@@ -506,6 +509,7 @@ sub osload ($$) {
'zerofree' => $zerofree,
'prepare' => $prepare,
'maxwait' => $maxwait,
'subboss' => $subboss,
'isremote' => $isremote,
'isvirtnode' => $isvirtnode
};
......@@ -981,6 +985,7 @@ sub SetupReloadFrisbee($)
my $zerofree = $reload_info->{'zerofree'};
my $prepare = $reload_info->{'prepare'};
my $isvirtnode = $reload_info->{'isvirtnode'};
my $subboss = $reload_info->{'subboss'};
my $osid = TBNodeDiskloadOSID($node);
#
......@@ -1016,6 +1021,25 @@ sub SetupReloadFrisbee($)
}
foreach my $imageid (@$imageids) {
if (defined $subboss) {
my $image = Image->Lookup($imageid);
my $filename = $image->filename();
my @image_stats = stat $filename;
my $query_result = DBQueryWarn("select sync from subboss_images where " .
"subboss_id = '$subboss' and imageid = '$imageid' and sync = 1");
if (!$query_result || !$query_result->numrows) {
system("$SUBBOSS_FRISBEELAUNCHER " . ($debug ? "-d ": "") .
"$subboss " . "$imageid " . "\"$filename\" " .
stat[7] . ' ' . stat[9]);
if ($?) {
tberror "Subboss Frisbee Launcher ($imageid on $subboss) failed!";
return -1;
}
return 0;
}
}
system("$FRISBEELAUNCHER " . ($debug ? "-d ": "") . "$imageid");
if ($?) {
tberror "Frisbee Launcher ($imageid) failed!";
......
......@@ -3368,6 +3368,7 @@ sub ReadRspecSolution($$)
if (scalar(@ifacerefs) == 2) {
my ($ifaceA,$ifaceB) = @ifacerefs;
my $trivial = 0;
my $virtA = $ifaceA->{'virtual_interface_id'};
my $virtB = $ifaceB->{'virtual_interface_id'};
......@@ -3377,10 +3378,15 @@ sub ReadRspecSolution($$)
my $nodeB = $self->solution()->{'V2P'}->{$vnodeB};
my $portA = $ifacemap{$vnodeA}->{$virtA};
my $portB = $ifacemap{$vnodeB}->{$virtB};
my $vlink = "linksimple/$virtual_id/$virtA,$virtB";
if ($portA eq "loopback" || $portB eq "loopback") {
$nodeA = $nodeB = $portA = $portB = undef;
$trivial = 1;
$virtlan->_trivial_ok(1);
}
my $vlink = "linksimple/$virtual_id/$virtA,$virtB";
$self->AddLinkToSolution($vlink, 0, 0,
$self->AddLinkToSolution($vlink, $trivial, 0,
$nodeA, $portA, $nodeB, $portB);
}
else {
......
......@@ -24,7 +24,7 @@ my $debug = 1;
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $RPCSERVER = "@OUTERBOSS_NODENAME@";
my $RPCSERVER = "@BOSSNODE@";
my $RPCPORT = "@OUTERBOSS_XMLRPCPORT@";
my $RPCCERT = "@OUTERBOSS_SSLCERTNAME@";
......
......@@ -12,6 +12,8 @@ use Sys::Syslog;
use English;
use Socket;
use Errno qw(EADDRINUSE);
use File::Basename;
use File::Path;
#
# This also kills a running frisbee.
......@@ -34,7 +36,7 @@ my $MY_IP;
my $BASEADDR = "@FRISEBEEMCASTADDR@";
my $BASEPORT = "@FRISEBEEMCASTPORT@";
my $RPCSERVER = "@OUTERBOSS_NODENAME@";
my $RPCSERVER = "@BOSSNODE@";
my $RPCPORT = "@OUTERBOSS_XMLRPCPORT@";
my $RPCCERT = "@SUBBOSS_SSLCERTNAME@";
......@@ -65,12 +67,13 @@ sub ClearPid();
sub ClearAddress();
sub Fatal($);
sub debug($);
sub GetImageInfo($$);
sub GetLoadAddress($$);
# Defines
my $FRISBEED = "$TB/sbin/frisbeed";
my $LOGFILE = "$TB/log/frisbeelauncher";
my $FRISBEEIMAGE= "$TB/sbin/frisbeeimage";
my $IMAGE_CACHE = "$TB/image_cache";
my $child_pid = 0;
my $dlfilename = 0;
......@@ -123,6 +126,7 @@ usage()
#
# XXX hack: use map + regex to get around taint check
my ($imageid, $filename, $size, $mtime) = map { /(.*)/; $1 } @ARGV;
$filename = "$IMAGE_CACHE/$filename";
#
# Get node ID via tmcc
......@@ -154,6 +158,13 @@ my $naddress;
my $address;
my $pid;
$naddress = GetLoadAddress($subbossid, $imageid);
if (defined $naddress) {
# Try to discover if some other process is handling this address
$address = $$naddress{"address"};
$pid = $$naddress{"frisbee_pid"};
}
if (!$killmode) {
#
# Pick an address to use before locking the DB. Die if unsucessful,
......@@ -161,11 +172,6 @@ if (!$killmode) {
# already a laucher active, we will wind up wasting this address,
# but hey, we can make more!
#
$naddress = PickAddress($subbossid, $imageid);
# Try to discover if some other process is handling this address
$address = $$naddress{"address"};
$pid = $$naddress{"frisbee_pid"};
#
......@@ -174,6 +180,8 @@ if (!$killmode) {
if ($pid && $address) {
debug("A server ($address) is already running for image $imageid\n");
exit(0);
} else {
$address = PickAddress($subbossid, $imageid);
}
if (-e $filename) {
......@@ -200,6 +208,10 @@ if (!$killmode) {
SetPid($PID);
$EUID = $UID;
$dlfilename = $filename;
my $image_dir = dirname($filename);
if (! -d $image_dir && !mkpath($image_dir)) {
Fatal("Unable to create path \"$image_dir\"\n");
}
system($FRISBEEIMAGE, $imageid, $filename);
ClearPid();
ClearSyncFlag();
......@@ -211,9 +223,6 @@ if (!$killmode) {
}
}
} else {
my $result = GetImageInfo($subbossid, $imageid);
my $address = $$result{"address"};
my $pid = $$result{"frisbee_pid"};
# Nothing running.
exit(0)
......@@ -240,9 +249,9 @@ if (!$killmode) {
#
sleep(1);
# XXX add call to get address and pid
$result = GetImageInfo($imageid, $subbossid);
$address = $$result{"address"};
$pid = $$result{"frisbee_pid"};
$naddress = GetLoadAddress($imageid, $subbossid);
$address = $$naddress{"address"};
$pid = $$naddress{"frisbee_pid"};
# Okay, situation resolved itself; other frisbeelauncher bailed.
exit(0)
......@@ -430,7 +439,7 @@ sub debug($)
sub PickAddress($$)
{
my ($subbossid, $imageid) = @_;
my $rval = libxmlrpc::CallMethod("subboss", "alloc_load_address",
my $rval = libxmlrpc::CallMethod("subboss", "allocate_load_address",
{"imageid" => "$imageid", "subboss_id" => $subbossid});
if (not defined $rval) {
......@@ -444,15 +453,15 @@ sub PickAddress($$)
# Get current load address and frisbeed pid for the specified imageid on the specified
# subbossid
#
sub GetImageInfo($$)
sub GetLoadAddress($$)
{
my ($subbossid, $imageid) = @_;
my $rval = libxmlrpc::CallMethod("subboss", "get_image_info",
my $rval = libxmlrpc::CallMethod("subboss", "get_load_address",
{"imageid" => $imageid, "subboss_id" => $subbossid});
if (not defined $rval) {
Fatal("$$: Failed to get mcast address from server!");
}
#if (not defined $rval) {
# Fatal("$$: Failed to get mcast address from server!");
#}
return $rval;
}
......@@ -465,7 +474,7 @@ sub ClearAddress()
{
debug("Clearing out registered load_address and pid\n");
my $rval = libxmlrpc::CallMethod("subboss", "dealloc_load_address",
my $rval = libxmlrpc::CallMethod("subboss", "clear_load_address",
{"imageid" => "$imageid", "subboss_id" => $subbossid});
if (not defined $rval) {
......@@ -482,7 +491,7 @@ sub ClearAddress()
sub SetPid($)
{
my ($pid) = @_;
my $rval = libxmlrpc::CallMethod("subboss", "set_pid",
my $rval = libxmlrpc::CallMethod("subboss", "set_frisbee_pid",
{"imageid" => "$imageid", "subboss_id" => $subbossid,
"frisbee_pid" => $pid});
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use Getopt::Std;
use POSIX 'setsid'; # For &daemonize
use POSIX ":sys_wait_h"; # For &WNOHANG
use Sys::Syslog;
use English;
use Socket;
use Errno qw(EADDRINUSE);
sub Fatal($);
#
# This also kills a running frisbee.
#
sub usage()
{
print "Usage: $0 [-d] [-k] <imageid>\n";
print "-k: Kill running frisbee.\n";
print "-d: Print debugging output.\n";
exit(1);
}
my $optlist = "dk";
my $debug = 0;
my $killmode = 0;
#
# Untaint the path
#
$ENV{'PATH'} = "/bin:/usr/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Change to root
$<=$>=0;
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"k"})) {
$killmode = 1;
}
usage()
if (@ARGV < 5);
# XXX HACK UGLY
# quick and dirty hack to get around taint checking
# This isn't really an issue anyway since we use the
# list form of system() which doesn't run the command
# via the shell (so no globbing or interpretation of
# metacharacters is done).
my ($subboss, $imageid, $path, $size, $mtime) = map { /(.*)/; $1 } @ARGV;
my @command = ('ssh', $subboss);
push @command, '-d' if ($debug);
push @command, '-k' if ($killmode);
push @command, ('/usr/testbed/sbin/subboss_frisbeelauncher', $imageid, $path, $size, $mtime);
system(@command);
if ($?) {
Fatal("Failed to launch frisbee on subboss $subboss");
}
sub Fatal($)
{
my ($msg) = @_;
die("*** $0:\n".
" $msg\n");
}
......@@ -36,6 +36,7 @@ sub doboot()
{
my $EXTRAFS = "/z";
my $TFTPBOOT_DIR = "$EXTRAFS/tftpboot";
my $IMAGES_DIR = "$EXTRAFS/image_cache";
my $stuffdir = "$EXTRAFS/tmp";
my $MFSTARBALL = "tftpboot-subboss.tar.gz";
......@@ -47,8 +48,9 @@ sub doboot()
system("/usr/local/etc/rc.d/tftpd-hpa.sh stop");
RecreateDir($EXTRAFS,1);
mysystem("$BINDIR/mkextrafs.pl -f $EXTRAFS");
mysystem("mkdir -p $TFTPBOOT_DIR $stuffdir");
mysystem("mkdir -p $TFTPBOOT_DIR $IMAGES_DIR $stuffdir");
mysystem("ln -sf $TFTPBOOT_DIR /tftpboot");
mysystem("ln -sf $IMAGES_DIR $TB/image_cache");
print "Copying over tftpboot tar file from web server and unpacking\n";
......
......@@ -26,4 +26,4 @@
* NB: See ron/libsetup.pm. That is version 4! I'll merge that in.
*/
#define DEFAULT_VERSION 2
#define CURRENT_VERSION 30
#define CURRENT_VERSION 31
......@@ -140,6 +140,8 @@ loadone() {
echo "Loading image #$NUM"
ADDRESS=`echo $LOADINFO | sed -e 's/.*ADDR=\([^[:space:]]*\).*/\1/'`
SERVER=`echo $LOADINFO | sed -e 's/.*SERVER=\([^[:space:]]*\).*/\1/'`
SERVER=${SERVER:-$BOSSIP}
PARTITION=`echo $LOADINFO | sed -e 's/.*PART=\([^[:space:]]*\).*/\1/'`
PARTITION=${PARTITION:-'0'}
PARTOS=`echo $LOADINFO | sed -e 's/.*PARTOS=\([^[:space:]]*\).*/\1/'`
......@@ -339,8 +341,8 @@ loadone() {
echo "Running /usr/local/bin/imageunzip -o -O -W 32 $ZFILL $imagefile /dev/${DISK}s${PARTITION}"
/usr/local/bin/imageunzip -o -O -W 32 $ZFILL $imagefile /dev/${DISK}s${PARTITION}
else
echo "Running $BINDIR/frisbee $LOADIP $MEMARGS $ZFILL $SLICE $MCASTIF $MCASTADDR /dev/$DISK at `date`"
$BINDIR/frisbee $LOADIP $MEMARGS $ZFILL $SLICE $MCASTIF $MCASTADDR /dev/$DISK
echo "Running $BINDIR/frisbee -S $SERVER $MEMARGS $ZFILL $SLICE $MCASTIF $MCASTADDR /dev/$DISK at `date`"
$BINDIR/frisbee -S $SERVER $MEMARGS $ZFILL $SLICE $MCASTIF $MCASTADDR /dev/$DISK
fi
fstat=$?
......@@ -395,9 +397,6 @@ STATUS=`$BINDIR/tmcc status`
BOSSIP=`echo $BOSSINFO | awk '{ print $2 }'`
# XXX should be part of loadinfo
LOADIP="-S $BOSSIP"
if [ -x /usr/sbin/ntpdate ]; then
/usr/sbin/ntpdate -b $BOSSIP >/dev/null 2>&1
fi
......
#/bin/sh -
#! /bin/sh
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
......
......@@ -25,6 +25,7 @@ sub usage()
my $optlist = "d";
my $debug = 1;
my $leaveme = 0;
my $running = 0;
my $cleaning = 0;
my $rebooting= 0;
my $vnodeid;
......@@ -147,12 +148,8 @@ if ($DOMAINNAME =~ /^[-\w]+\.(.*)$/) {
else {
die("Could not parse domain name!");
}
#
# Need the bossip, which was returned above
#
if ($BOSSIP !~ /^\d+\.\d+\.\d+\.\d+$/) {
die "Bad bossip '$BOSSIP' in $BOOTDIR/bossip!";
die "Bad bossip '$BOSSIP' from bossinfo!";
}
#
......@@ -287,6 +284,8 @@ if (! -e "$VNDIR/vnode.info") {
mysystem("mkdir -p /var/emulab/jails/$vnodeid");
}
else {
$rebooting = 1;
my $str = `cat $VNDIR/vnode.info`;
chomp($str);
($vmid, $vmtype) = ($str =~ /^(\d*) (\w*)$/);
......@@ -301,7 +300,6 @@ else {
if ($ret ne VNODE_STATUS_STOPPED()) {
MyFatal("vnode $vnodeid not stopped, not booting!");
}
$rebooting = 1;
}
my $cnet_mac = ipToMac($vnconfig{'CTRLIP'});
......@@ -446,6 +444,7 @@ TBDebugTimeStamp("finished $vmtype rootPostConfig()")
# This is for vnodesetup
mysystem("touch $VNDIR/running");
$running = 1;
#
# Install a signal handler to catch signals from vnodesetup.
......@@ -596,6 +595,13 @@ sub MyFatal($)
{
my ($msg) = @_;
#
# If rebooting but never got a chance to run, we do not want
# to kill off the container. Might lose user data.
#
$leaveme = 1
if ($rebooting && !$running);
Cleanup();
die("*** $0:\n".
" $msg\n");
......
......@@ -133,6 +133,7 @@ write_image()
local slice=$3
local zfill=$4
local ptype=$5
local server=$6
local port=""
local imagefile=""
local frisbee_opts="$FRISBEE_OPTS"
......@@ -207,7 +208,8 @@ write_image()
$BINDIR/tmcc state RELOADING
if [ $protocol = frisbee ]; then
$BINDIR/frisbee -m $address -p $port $frisbee_opts $disk
[ -n "$server" ] || server=$BOSSIP
$BINDIR/frisbee -m $address -p $port -S $server $frisbee_opts $disk
rc=$?
if [ $rc -ne 0 ]; then
......@@ -233,6 +235,7 @@ handle_loadinfo()
{
local LOADINFO="$@"
local ADDRESS=`get_value "$LOADINFO" ADDR`
local SERVER=`get_value "$LOADINFO" SERVER`
local PARTOS=`get_value "$LOADINFO" PARTOS`
local PARTITION=`get_value "$LOADINFO" PART`
PARTITION=${PARTITION:-'0'}
......@@ -305,7 +308,7 @@ handle_loadinfo()
zapsuperblocks /dev/$DISK
fi
write_image $ADDRESS /dev/$DISK $PARTITION $ZFILL $PTYPE
write_image $ADDRESS /dev/$DISK $PARTITION $ZFILL $PTYPE $SERVER