All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 07855cca authored by Leigh B. Stoller's avatar Leigh B. Stoller

This script was moved from the ron code into the common code since its

now used on local nodes. Possibly appropriate for linux too, since
this is mostly just a big wrapper for other scripts.
parent 83d6747e
......@@ -10,47 +10,49 @@ use English;
use Errno;
use POSIX qw(setsid);
# Drag in path stuff so we can find emulab stuff.
BEGIN { require "/etc/emulab/paths.pm"; import emulabpaths; }
#
# Setup a single virtual experiment.
#
sub usage()
{
print "Usage: vnodesetup [-k] <vnodeid>\n".
print "Usage: vnodesetup [-j [-s]] [-b | -k | -r] [-d] <vnodeid>\n".
"Use the -k option to kill the virtual node.\n";
exit(1);
}
my $optlist = "k";
my $killit = 0;
my $optlist = "kbdjsr";
#
# XXX deal with left over setups.
# left over directories.
# kill vtun log files.
#
# Locals
my $killit = 0;
my $rebootit = 0;
my $debug = 0;
my $fromboot = 0;
my $dojail = 0;
my $interactive = 0;
my $cleaning = 0;
my $rebooting = 0;
my $leavejail = 0;
my $jailpid;
#
# Turn off line buffering on output
#
$| = 1;
#
# Untaint path
#
$ENV{'PATH'} = "/usr/local/etc/emulab:/bin:/sbin:/usr/bin:/usr/local/bin:" .
"/usr/local/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Load the OS independent support library. It will load the OS dependent
# library and initialize itself.
#
use lib "/usr/local/etc/emulab";
use libsetup;
#
# Forward declarations for prototype checking
#
sub killvnode();
sub rebootvnode();
sub cleanup();
#
# Must be root.
......@@ -85,6 +87,21 @@ if (! getopts($optlist, \%options)) {
if (defined($options{"k"})) {
$killit = 1;
}
if (defined($options{"r"})) {
$rebootit = 1;
}
if (defined($options{"b"})) {
$fromboot = 1;
}
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"j"})) {
$dojail = 1;
if (defined($options{"s"})) {
$interactive = 1;
}
}
if (@ARGV != 1) {
usage();
}
......@@ -100,9 +117,9 @@ else {
#
# Hacky. All this path stuff is hacky.
#
my $logname = "/tmp/tbvnode-${vnodeid}.debug";
my $pidfile = "/var/run/tbvnode-${vnodeid}.pid";
my $vnodedir = "/var/emulab/$vnodeid";
my $vnodedir = "/var/emulab/jails/$vnodeid";
my $logname = "$LOGDIR/tbvnode-${vnodeid}.log";
#
# If killing the virtual node, then kill the manager process. We use
......@@ -116,6 +133,13 @@ if ($killit) {
}
exit(killvnode());
}
if ($rebootit) {
if (! -e $pidfile) {
die("*** $0:\n".
" No pid for $vnodeid manager!\n");
}
exit(rebootvnode());
}
#
# If the pidfile still exists, then something went wrong with a
......@@ -135,7 +159,6 @@ if (-e $pidfile) {
# If there was no such process, kill the pid file and go on.
#
system("rm -f $pidfile");
system("rm -rf $vnodedir");
}
else {
die("*** $0:\n".
......@@ -144,10 +167,10 @@ if (-e $pidfile) {
}
#
# Okay, lets and continue on so that ssh from Emulab exits right away.
# Okay, lets continue on so that ssh from Emulab exits right away.
# It will figure out we are okay via the ISUP.
#
if (TBBackGround($logname)) {
if (!$debug && !$interactive && TBBackGround($logname)) {
#
# Parent exits normally
#
......@@ -176,39 +199,60 @@ close(PFILE);
#
my $pgrp = getpgrp(0);
sub handler () {
sub handler ($) {
my ($signame) = @_;
$SIG{USR1} = 'IGNORE';
$SIG{USR2} = 'IGNORE';
if ($signame eq 'USR2') {
reboot();
$SIG{USR1} = \&handler;
$SIG{USR2} = \&handler;
return;
}
$SIG{TERM} = 'IGNORE';
$SIG{INT} = 'IGNORE';
print "Exiting\n";
kill('TERM', -$pgrp);
sleep(15);
system("rm -rf $vnodedir");
system("rm -f $pidfile");
exit(0);
$SIG{INT} = 'IGNORE';
#
# If we catch a TERM, we want to leave the jail around since TERM
# means the node is rebooting. We want to restart it later when the
# node reboots.
#
if ($signame eq 'TERM') {
$leavejail = 1;
}
fatal("Caught a SIG${signame}! Killing the vnode ...");
}
$SIG{TERM} = \&handler;
$SIG{INT} = \&handler;
$SIG{USR1} = \&handler;
$SIG{USR2} = \&handler;
#
# Kill existing directory in case its still there.
#
if (-e $vnodedir) {
#
if (!$fromboot && -e $vnodedir) {
system("rm -rf $vnodedir");
}
mkdir($vnodedir, 0755) or
die("*** $0:\n".
" Could not mkdir $vnodedir: $!\n");
if (! -e $vnodedir) {
mkdir($vnodedir, 0755) or
die("*** $0:\n".
" Could not mkdir $vnodedir: $!\n");
}
#
# Inform the TMCD we are setting up. Use REBOOTED event for simplicity!
# Inform the TMCD we are setting up.
#
system("tmcc -n $vnodeid state REBOOTED");
system("tmcc -n $vnodeid state TBSETUP");
#
# Invoke remotevnodesetup routine in the setup library. This will talk
# to tmcd and create the rc files.
#
if (!defined(remotenodevnodesetup($vnodeid, $vnodedir))) {
my ($pid) = vnodesetup($vnodeid);
if (!defined($pid)) {
#
# Hmm, suddenly got free.
#
......@@ -222,33 +266,78 @@ if (!defined(remotenodevnodesetup($vnodeid, $vnodedir))) {
#
$UID = 0;
REBOOT:
#
# Okay, now startup the scripts.
#
if (-e TMTUNNELCONFIG) {
print "Starting Tunnels ...\n";
TBForkCmd(TMTUNNELCONFIG);
sleep(5);
}
sleep(5);
if (-e TMTRAFFICCONFIG) {
print "Starting Traffic Generators ...\n";
TBForkCmd(TMTRAFFICCONFIG);
if (!$dojail) {
if (-e TMTRAFFICCONFIG) {
print "Starting Traffic Generators ...\n";
TBForkCmd(TMTRAFFICCONFIG);
sleep(1);
}
}
sleep(1);
#
# Inform the TMCD we are ready.
# Create the jail.
#
system("tmcc -n $vnodeid state ISUP");
if ($dojail) {
$jailpid = fork();
if ($jailpid) {
#
# Parent waits for jail to fold on its own. If the jail is
# killed off though, will never return.
#
if (waitpid($jailpid, 0) < 0) {
#
# Means that already waited. Must be forcing a reboot.
#
if (!defined($jailpid) && $rebooting) {
$rebooting = 0;
system("tmcc -n $vnodeid state TBSETUP");
goto REBOOT;
}
}
undef($jailpid);
if ($debug || $interactive) {
if ($?) {
fatal("Jail startup exited with $?");
}
cleanup();
exit(0);
}
fatal("Jail exited unexpectedly!");
}
else {
my $option = ($interactive ? "-s" : "");
exec("mkjail.pl $option -p $pid $vnodeid");
die("*** $0:\n".
" Could not start the jail!\n");
}
}
else {
#
# Inform the TMCD we are ready.
#
system("tmcc -n $vnodeid state ISUP");
#
# Now we just sit and wait to be killed off by a signal sent to the
# process group. Everything should get killed.
#
while (1) {
sleep 5;
#
# Now we just sit and wait to be killed off by a signal sent to the
# process group. Everything should get killed.
#
while (1) {
sleep 5;
}
}
exit 0;
#
# Routine to kill a vnode manager by sending it a signal.
......@@ -264,8 +353,8 @@ sub killvnode() {
die("*** $0:\n".
" Bad data in pid: $mpid!\n");
}
if (kill('TERM', $mpid) == 0) {
print"*** Could not kill(TERM) process $mpid: $!\n";
if (kill('USR1', $mpid) == 0) {
print"*** Could not kill(USR1) process $mpid: $!\n";
return -1;
}
......@@ -283,4 +372,100 @@ sub killvnode() {
return 0;
}
exit 0;
#
# Routine to "reboot" a vnode by sending a signal to the manager process.
#
sub rebootvnode() {
my $mpid = `cat $pidfile`;
$mpid =~ s/\n//;
# untaint
if ($mpid =~ /^([-\@\w.]+)$/) {
$mpid = $1;
}
else {
die("*** $0:\n".
" Bad data in pid: $mpid!\n");
}
if (kill('USR2', $mpid) == 0) {
print"*** Could not kill(USR2) process $mpid: $!\n";
return -1;
}
return 0;
}
#
# Cleanup at exit.
#
sub cleanup()
{
if ($cleaning) {
die("*** $0:\n".
" Oops, already cleaning!\n");
}
$cleaning = 1;
# Inform testbed that vnode going down.
system("tmcc -t 2 -n $vnodeid state SHUTDOWN");
#
# First force the jail to exit.
#
if (defined($jailpid)) {
if ($leavejail) {
kill('USR1', $jailpid);
}
else {
kill('HUP', $jailpid);
}
waitpid($jailpid, 0);
undef($jailpid);
}
$SIG{TERM} = 'IGNORE';
kill('TERM', -$pgrp);
print "Waiting 10 seconds for process group to die off ...\n";
sleep(10);
if (! $leavejail) {
system("rm -rf $vnodedir");
}
system("rm -f $pidfile");
}
#
# Reboot a vnode. Sort of odd, I know.
#
sub reboot()
{
$rebooting = 1;
# Inform testbed that vnode going down.
system("tmcc -t 2 -n $vnodeid state SHUTDOWN");
#
# First force the jail to exit, but leaving it intact.
#
if (defined($jailpid)) {
kill('USR1', $jailpid);
waitpid($jailpid, 0);
undef($jailpid);
}
$SIG{TERM} = 'IGNORE';
kill('TERM', -$pgrp);
print "Waiting 10 seconds for process group to die off ...\n";
sleep(10);
$SIG{TERM} = '\&handler';
}
#
# Print error and exit.
#
sub fatal($)
{
my ($msg) = @_;
cleanup();
die("*** $0:\n".
" $msg\n");
}
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