Commit d8f8f9b4 authored by Leigh Stoller's avatar Leigh Stoller

A set of changes to run "prepare" on a node just prior to an image

being taken.

The basic strategy is to have node_reboot (when -p option supplied)
invoke a special command on the node that will cause the shutdown
procedure to run prepare as it goes single user, but before the
network is turned off and the machine rebooted. The output of the
prepare run is capture and send back via the tmcd BOOTLOG command and
stored in the DB, so that create_image can dump that to the logfile
(so that the person taking the image can know for certain that the
prepare ran and finished okay).

On linux this is pretty easy to arrange since reboot is actually
shutdown and shutdown runs the K scripts in /etc/rc.d/rc6.d, and at
the end the node is basically single user mode. I just added a new
script to run prepare and send back the output.

On FreeBSD this is a lot harder since there are no decent hooks.
Instead, I had to hack up init (see tmcd/freebsd/init/{4,5,6}) with
some simple code that looks for a command to run instead of going to a
single user shell. The command (script) runs prepare, sends the output
back to tmcd, and then does a real reboot.

Okay, so how to get -p passed to node_reboot? I hacked up the
libadminmfs code slightly to do that, with new 'prepare' argument
option. This may not be the best approach; might have to do this as a
real state transition if problems develop. I will wait and see.

Also, I changed www/loadimage.php3 to spew the output of the
create_image to the browser.
parent bb5baf2c
......@@ -2321,7 +2321,9 @@ outfiles="$outfiles Makeconf GNUmakefile \
tip/GNUmakefile tip/console \
tmcd/GNUmakefile tmcd/tmcd.restart \
tmcd/common/GNUmakefile tmcd/common/config/GNUmakefile \
tmcd/freebsd/GNUmakefile \
tmcd/freebsd/GNUmakefile tmcd/freebsd/init/GNUmakefile \
tmcd/freebsd/init/4/GNUmakefile tmcd/freebsd/init/5/GNUmakefile \
tmcd/freebsd/init/6/GNUmakefile \
tmcd/freebsd/supfile tmcd/freebsd/sethostname \
tmcd/linux/GNUmakefile tmcd/linux/supfile \
tmcd/linux/sethostname.dhclient \
......
......@@ -759,7 +759,9 @@ outfiles="$outfiles Makeconf GNUmakefile \
tip/GNUmakefile tip/console \
tmcd/GNUmakefile tmcd/tmcd.restart \
tmcd/common/GNUmakefile tmcd/common/config/GNUmakefile \
tmcd/freebsd/GNUmakefile \
tmcd/freebsd/GNUmakefile tmcd/freebsd/init/GNUmakefile \
tmcd/freebsd/init/4/GNUmakefile tmcd/freebsd/init/5/GNUmakefile \
tmcd/freebsd/init/6/GNUmakefile \
tmcd/freebsd/supfile tmcd/freebsd/sethostname \
tmcd/linux/GNUmakefile tmcd/linux/supfile \
tmcd/linux/sethostname.dhclient \
......
......@@ -67,6 +67,7 @@ my $sleepwait = 10;
# 'name' string identifying the caller for error messages
# 'on' 1 to enter MFS, 0 to exit
# 'reboot' 1 to reboot into MFS, -1 to "power on", 0 to do nothing
# 'prepare' 1 to run prepare on the way down
# 'wait' 1 to wait for all nodes to reach MFS before returning,
# 0 to return after reboot/power-on
#
......@@ -86,6 +87,7 @@ sub TBAdminMfsBoot($$@)
my $on = $args->{'on'};
my $reboot = $args->{'reboot'};
my $wait = $args->{'wait'};
my $prepare = $args->{'prepare'};
#
# Reboot or power on nodes...
......@@ -133,7 +135,9 @@ sub TBAdminMfsBoot($$@)
$i++;
}
if ($reboot > 0) {
if (system("$nodereboot $batch")) {
my $optarg = ($prepare ? "-p" : "");
if (system("$nodereboot $optarg $batch")) {
print STDERR "*** $me:\n".
" WARNING: Could not reboot some of: $batch!\n";
}
......@@ -339,6 +343,7 @@ sub TBAdminMfsSelect($$@)
# the function returns 0, we abort as we would with
# a timeout.
# 'timestamp' if timestamps after significant events are desired
# 'prepare' 1 if nodes should be rebooted with "prepare" flag
#
# Returns zero if all nodes successfully run the command.
# If the $failed ref is defined, it is an arrayref in which we return the
......@@ -362,6 +367,7 @@ sub TBAdminMfsRunCmd($$@)
my $pfunc = $args->{'pfunc'};
my $pinterval = $args->{'pinterval'};
my $pcookie = $args->{'pcookie'};
my $prepare = $args->{'prepare'};
# we always need a value
$timeout = $commandtimo
......@@ -410,6 +416,7 @@ sub TBAdminMfsRunCmd($$@)
$myargs{'name'} = $me;
$myargs{'on'} = 1;
$myargs{'reboot'} = $poweron ? -1 : 1;
$myargs{'prepare'} = $prepare;
$myargs{'wait'} = 1;
my @failed = ();
if (TBAdminMfsBoot(\%myargs, \@failed, @nodes)) {
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
# All rights reserved.
#
# node reboot library. Basically the backend to the node_reboot script, but
......@@ -119,6 +119,7 @@ sub nodereboot($$)
my $realmode = 1;
my $killmode = 0;
my $freemode = 0;
my $prepare = 0;
my $reconfig = 0;
my $asyncmode = 0;
my $pipemode = 0;
......@@ -130,6 +131,7 @@ sub nodereboot($$)
$realmode = $args->{'realmode'} if (exists($args->{'realmode'}));
$killmode = $args->{'killmode'} if (exists($args->{'killmode'}));
$freemode = $args->{'freemode'} if (exists($args->{'freemode'}));
$prepare = $args->{'prepare'} if (exists($args->{'prepare'}));
$reconfig = $args->{'reconfig'} if (exists($args->{'reconfig'}));
$asyncmode = $args->{'asyncmode'} if (exists($args->{'asyncmode'}));
......@@ -335,7 +337,7 @@ sub nodereboot($$)
#
foreach my $node ( @batch ) {
$pids{$node} = RebootNode($node, $reconfig,
$killmode, $rebootmode);
$killmode, $rebootmode, $prepare);
}
}
......@@ -476,7 +478,7 @@ sub nodereboot($$)
# that it can wait on all the children later.
#
sub RebootNode {
my ($pc, $reconfig, $killmode, $rebootmode) = @_;
my ($pc, $reconfig, $killmode, $rebootmode, $prepare) = @_;
my ($status, $syspid, $mypid, $didipod, $nodestate);
#
......@@ -563,7 +565,7 @@ sub RebootNode {
# See if the machine is pingable. If its not pingable, then we just
# power cycle the machine rather than wait for ssh to time out.
#
if (! DoesPing($pc)) {
if (! DoesPing($pc, 0)) {
info("$pc appears dead: power cycle");
tbnotice "$pc appears dead; will power cycle.";
......@@ -660,7 +662,7 @@ sub RebootNode {
if ($syspid) {
my $timedout = 0;
local $SIG{ALRM} = sub { kill("TERM", $syspid); $timedout = 1; };
alarm 20;
alarm 20;;
waitpid($syspid, 0);
alarm 0;
......@@ -693,7 +695,11 @@ sub RebootNode {
}
}
else {
exec("$ssh -host $pc /sbin/reboot");
my $cmd = "/sbin/reboot";
$cmd = "'/usr/local/etc/emulab/reboot_prepare || $cmd'"
if ($prepare);
exec("$ssh -host $pc $cmd");
exit(0);
}
......@@ -708,7 +714,7 @@ sub RebootNode {
# We wait a while for the node to stop responding to pings, and if it never
# goes silent, whack it with a bigger stick.
#
if (WaitTillDead($pc) == 0) {
if (WaitTillDead($pc, ($prepare ? 200 : 30)) == 0) {
my $state = TBDB_NODESTATE_SHUTDOWN;
TBSetNodeEventState($pc,$state);
exit(0);
......@@ -726,7 +732,7 @@ sub RebootNode {
$UID = 0;
system("$ipod $pc");
$UID = $oldUID;
if (WaitTillDead($pc) == 0) {
if (WaitTillDead($pc, 20) == 0) {
my $state = TBDB_NODESTATE_SHUTDOWN;
TBSetNodeEventState($pc,$state);
exit(0);
......@@ -808,7 +814,7 @@ sub PowerCycle {
# Wait until a machine stops returning ping packets.
#
sub WaitTillDead {
my ($pc) = @_;
my ($pc, $waittime) = @_;
print STDERR "reboot ($pc): Waiting to die off.\n" if $debug;
......@@ -817,8 +823,8 @@ sub WaitTillDead {
# packets are sent from all the pings, before it will exit. So,
# loop doing a bunch of shorter pings.
#
for (my $i = 0; $i < 30; $i++) {
if (! DoesPing($pc)) {
for (my $i = 0; $i < $waittime; $i++) {
if (! DoesPing($pc, $i)) {
print STDERR "reboot ($pc): Died off.\n" if $debug;
return 0;
}
......@@ -832,7 +838,7 @@ sub WaitTillDead {
# This routine is NOT allowed to do any DB queries!
#
sub DoesPing {
my ($pc) = @_;
my ($pc, $index) = @_;
my $status;
my $saveuid;
......@@ -847,7 +853,7 @@ sub DoesPing {
# but no packets are returned. Other non-zero error codes indicate
# other problems. Any non-zero return indicates "not pingable" to us.
#
print STDERR "reboot ($pc): $ping returned $status\n" if $debug;
print STDERR "reboot ($pc): $ping $index returned $status\n" if $debug;
if ($status) {
return 0;
}
......
......@@ -31,7 +31,7 @@ sub usage()
}
# The hidden -r option runs this in "realmode", ie don't send an event, but
# really do the work instead.
my $optlist = "dfe:wrkacb";
my $optlist = "dfe:wrkacbp";
my $debug = 0;
my $powercycle = 0;
my $waitmode = 0;
......@@ -39,6 +39,7 @@ my $realmode = 1; # XXX Temporary, until we make event sending the default.
my $killmode = 0;
my $reconfig = 0;
my $rebootmode = 0;
my $prepare = 0;
#
# Configure variables
......@@ -97,6 +98,9 @@ if (defined($options{"k"})) {
if (defined($options{"w"})) {
$waitmode = 1;
}
if (defined($options{"p"})) {
$prepare = 1;
}
if (defined($options{"r"})) {
$realmode = 1;
......@@ -241,6 +245,7 @@ $args{'waitmode'} = $waitmode;
$args{'realmode'} = $realmode;
$args{'killmode'} = $killmode;
$args{'reconfig'} = $reconfig;
$args{'prepare'} = $prepare;
$args{'nodelist'} = [ @nodes ];
exit(nodereboot(\%args, \%status));
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -70,6 +70,7 @@ common-script-install: dir-install
$(INSTALL) -m 755 $(SRCDIR)/libtmcc.pm $(BINDIR)/libtmcc.pm
$(INSTALL) -m 755 $(SRCDIR)/libtestbed.pm $(BINDIR)/libtestbed.pm
$(INSTALL) -m 755 $(SRCDIR)/tmcc.pl $(BINDIR)/tmcc
$(INSTALL) -m 755 $(SRCDIR)/logboot $(BINDIR)/logboot
$(INSTALL) -m 755 $(SRCDIR)/watchdog $(BINDIR)/watchdog
$(INSTALL) -m 755 $(SRCDIR)/ntpstart $(BINDIR)/ntpstart
$(INSTALL) -m 755 $(SRCDIR)/runstartup $(BINDIR)/runstartup
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use Getopt::Std;
sub usage()
{
print "Usage: " . scriptname() . " <logfile>\n";
exit(1);
}
my $optlist = "d";
my $debug = 0;
my $logfile;
# Turn off line buffering on output
$| = 1;
# Drag in path stuff so we can find emulab stuff.
BEGIN { require "/etc/emulab/paths.pm"; import emulabpaths; }
# Only root.
if ($EUID != 0) {
die("*** $0:\n".
" Must be root to run this script!\n");
}
#
# Load the OS independent support library. It will load the OS dependent
# library and initialize itself.
#
use libsetup;
use libtmcc;
use librc;
# Parse command line.
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{'d'})) {
$debug = 1;
}
usage()
if (! @ARGV);
$logfile = $ARGV[0];
if (! -e $logfile) {
die("*** $0:\n".
" $logfile does not exist or cannot be read!\n");
}
if (tmcc(TMCCCMD_BOOTLOG, "", undef, ("datafile" => $logfile)) < 0) {
die("*** $0:\n".
" Error sending TBFAILED to Emulab Control!\n");
}
exit(0);
......@@ -50,8 +50,8 @@ destdircheck:
false; \
fi
install client-install: common-install etc-install \
sup-install script-install bin-install jail-install
install client-install: common-install etc-install init-install \
sup-install script-install bin-install jail-install
@echo "Remember to install the PEM files if necessary"
mfs-install: destdircheck common-install etc-install \
......@@ -174,6 +174,7 @@ etc-install: dir-install sysetc-install
sysetc-install: dir-install
$(INSTALL) -m 755 $(SRCDIR)/rc.conf $(SYSETCDIR)/rc.conf
$(INSTALL) -m 755 $(SRCDIR)/prepare.sh $(SYSETCDIR)/emulab/prepare.sh
$(INSTALL) -m 755 $(SRCDIR)/sysctl.conf $(SYSETCDIR)/sysctl.conf
$(INSTALL) -m 755 $(SRCDIR)/dhclient-exit-hooks \
$(SYSETCDIR)/dhclient-exit-hooks
......@@ -185,6 +186,7 @@ sysetc-install: dir-install
script-install: dir-install $(SCRIPTS)
$(INSTALL) -m 755 $(SRCDIR)/prepare $(BINDIR)/prepare
$(INSTALL) -m 755 $(SRCDIR)/reboot_prepare $(BINDIR)/reboot_prepare
$(INSTALL) -m 755 $(SRCDIR)/ixpboot $(BINDIR)/ixpboot
$(INSTALL) -m 755 $(SRCDIR)/liblocsetup.pm $(BINDIR)/liblocsetup.pm
$(INSTALL) -m 755 $(SRCDIR)/rc.delayagent $(BINDIR)/rc/rc.delayagent
......@@ -228,6 +230,9 @@ jail-install: dir-install injail
$(INSTALL) -m 755 $(SRCDIR)/jail/mkjail.pl $(BINDIR)/mkjail.pl
$(INSTALL) -m 755 ./injail $(JAILDIR)/injail
init-install:
(cd init; $(MAKE) DESTDIR=$(DESTDIR) client-install)
# Invoked from ../ron
remote-install: jail-install
$(INSTALL) -m 755 $(SRCDIR)/rc.ipod $(BINDIR)/rc.ipod
......
#
# Insert Copyright Here.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
EVENTSYS = @EVENTSYS@
OBJDIR = ../../../..
SUBDIR = tmcd/freebsd/init/4
include $(OBJDIR)/Makeconf
all:
client: init
include $(TESTBED_SRCDIR)/GNUmakerules
CFLAGS += -DDEBUGSHELL -DSECURE -DLOGIN_CAP -DCOMPAT_SYSV_INIT -DTESTBED
init: init.c pathnames.h
$(CC) $(CFLAGS) -static -o init $< -lutil -lcrypt
install:
client-install: client
install -s -o root -g wheel -m 500 -fschg -b -B.bak init /sbin/init
clean:
rm -f *.o core init
......@@ -630,7 +630,62 @@ single_user()
* Start the single user session.
*/
setctty(_PATH_CONSOLE);
#ifdef TESTBED
#define TERMCMD "/bootcmd"
if (access(TERMCMD, F_OK) == 0) {
FILE *fp;
char cmd[256], *bp;
char *myargv[3];
/*
* Very simple; the file contains the path of a
* command to run. No arguments supported, sorry.
*/
if ((fp = fopen(TERMCMD, "r")) == NULL) {
/* Lets avoid loops! */
unlink(TERMCMD);
goto skip;
}
if (fgets(cmd, sizeof(cmd), fp) == NULL) {
fclose(fp);
/* Lets avoid loops! */
unlink(TERMCMD);
goto skip;
}
fclose(fp);
/* Lets avoid loops! */
unlink(TERMCMD);
if ((bp = rindex(cmd, '\n')))
*bp = '\0';
if (access(cmd, X_OK) != 0) {
emergency("%s does not exist!", cmd);
goto skip;
}
/* See comment below */
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
myargv[0] = "sh";
myargv[1] = cmd;
myargv[2] = 0;
execv(_PATH_BSHELL, myargv);
stall("can't exec %s for %s: %m", _PATH_BSHELL, cmd);
}
/*
* If something goes wrong, we want to sit in single user mode
* so that we might catch the error. Not sure, might have to
* do something fancier, like perhaps add a state transition
* for this/
*/
skip:
#endif
#ifdef SECURE
/*
* Check the root password.
......
......@@ -588,7 +588,62 @@ single_user(void)
* Start the single user session.
*/
setctty(_PATH_CONSOLE);
#ifdef TESTBED
#define TERMCMD "/bootcmd"
if (access(TERMCMD, F_OK) == 0) {
FILE *fp;
char cmd[256], *bp;
char *myargv[3];
/*
* Very simple; the file contains the path of a
* command to run. No arguments supported, sorry.
*/
if ((fp = fopen(TERMCMD, "r")) == NULL) {
/* Lets avoid loops! */
unlink(TERMCMD);
goto skip;
}
if (fgets(cmd, sizeof(cmd), fp) == NULL) {
fclose(fp);
/* Lets avoid loops! */
unlink(TERMCMD);
goto skip;
}
fclose(fp);
/* Lets avoid loops! */
unlink(TERMCMD);
if ((bp = rindex(cmd, '\n')))
*bp = '\0';
if (access(cmd, X_OK) != 0) {
emergency("%s does not exist!", cmd);
goto skip;
}
/* See comment below */
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
myargv[0] = "sh";
myargv[1] = cmd;
myargv[2] = 0;
execv(_PATH_BSHELL, myargv);
stall("can't exec %s for %s: %m", _PATH_BSHELL, cmd);
}
/*
* If something goes wrong, we want to sit in single user mode
* so that we might catch the error. Not sure, might have to
* do something fancier, like perhaps add a state transition
* for this/
*/
skip:
#endif
#ifdef SECURE
/*
* Check the root password.
......
#
# Insert Copyright Here.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
EVENTSYS = @EVENTSYS@
OBJDIR = ../../../..
SUBDIR = tmcd/freebsd/init/6
include $(OBJDIR)/Makeconf
all:
client: init
include $(TESTBED_SRCDIR)/GNUmakerules
CFLAGS += -DDEBUGSHELL -DSECURE -DLOGIN_CAP -DCOMPAT_SYSV_INIT -DTESTBED
init: init.c pathnames.h
$(CC) $(CFLAGS) -static -o init $< -lutil -lcrypt
install:
client-install: client
install -s -o root -g wheel -m 500 -fschg -b -B.bak init /sbin/init
clean:
rm -f *.o core init
......@@ -594,7 +594,64 @@ single_user(void)
* Start the single user session.
*/
setctty(_PATH_CONSOLE);
#ifdef TESTBED
#define TERMCMD "/bootcmd"
if (access(TERMCMD, F_OK) == 0) {
FILE *fp;
char cmd[256], *bp;
char *myargv[3];
/*
* Very simple; the file contains the path of a
* command to run. No arguments supported, sorry.
*/
if ((fp = fopen(TERMCMD, "r")) == NULL) {
/* Lets avoid loops! */
unlink(TERMCMD);
goto skip;
}
if (fgets(cmd, sizeof(cmd), fp) == NULL) {
fclose(fp);
/* Lets avoid loops! */
unlink(TERMCMD);
goto skip;
}
fclose(fp);
/* Lets avoid loops! */
unlink(TERMCMD);
if ((bp = rindex(cmd, '\n')))
*bp = '\0';
if (access(cmd, X_OK) != 0) {
emergency("%s does not exist!", cmd);
goto skip;
}
/* See comment below */
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
char name[] = "-sh";
myargv[0] = name;
myargv[1] = cmd;
myargv[2] = 0;
execv(_PATH_BSHELL, myargv);
stall("can't exec %s for %s: %m", _PATH_BSHELL, cmd);
}
/*
* If something goes wrong, we want to sit in single user mode
* so that we might catch the error. Not sure, might have to
* do something fancier, like perhaps add a state transition
* for this
*/
skip:
#endif
#ifdef SECURE
/*
* Check the root password.
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2006 University of Utah and the Flux Group.
# All rights reserved.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../../..
SUBDIR = tmcd/freebsd/init
include $(OBJDIR)/Makeconf
# To decide what directory
FBSDVERSION := $(shell uname -v | sed -e 's/FreeBSD \([0-9]\).*/FreeBSD\1/')
ifeq ($(FBSDVERSION),FreeBSD4)
SUBDIR = 4
endif
ifeq ($(FBSDVERSION),FreeBSD5)
SUBDIR = 5
endif
ifeq ($(FBSDVERSION),FreeBSD6)
SUBDIR = 6
endif
SUBDIRS = $(SUBDIR)
all:
include $(TESTBED_SRCDIR)/GNUmakerules
install:
client: client-subdirs
client-install: client client-install-subdirs
clean: clean-subdirs
distclean: distclean-subdirs
# How to recursively descend into subdirectories to make general
# targets such as `all'.
%.MAKE:
@$(MAKE) -C $(dir $@) $(basename $(notdir $@))
%-subdirs: $(addsuffix /%.MAKE,$(SUBDIRS)) ;
.PHONY: $(SUBDIRS)
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -226,5 +226,7 @@ if (-x "/usr/libexec/locate.updatedb") {
system("/usr/libexec/locate.updatedb");
}
# Leave this print statement here; create_image depends on it.
print "prepare ran successfully!\n";
exit 0;
#!/bin/sh
#
# Called from /sbin/init to do the prepare and reboot.
#
. /etc/emulab/paths.sh
HOME=/
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export HOME PATH
if ! mount -u -o rw /; then
echo 'Mounting root filesystem rw failed, prepare aborting'
exit 1
fi
/bin/rm -f /bootcmd
umount -a >/dev/null 2>&1
mount -a -t nonfs
case $? in
0)
;;
*)
echo 'Mounting /etc/fstab filesystems failed, startup aborted'
exit 1
;;
esac
$BINDIR/prepare 2>&1 | tee /prepare.log
$BINDIR/logboot /prepare.log
rm -f /prepare.log
echo "Rebooting for real ..."
sync
/sbin/reboot
#!/bin/sh
#
# Arrange for "prepare" to be run on the way down, and then shutdown.
#
. /etc/emulab/paths.sh
echo "$ETCDIR/prepare.sh" > /bootcmd
shutdown now "Rebooting with Prepare"
exit 0
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -100,6 +100,9 @@ sysetc-install: dir-install ifcfgs
-ln -sf $(RRCDIR)/init.d/testbed $(DEFRUNLVLDIR)/S96testbed
-ln -sf $(RRCDIR)/init.d/testbed $(RCDIR)/rc1.d/K12testbed
-ln -sf $(RRCDIR)/init.d/testbed $(RCDIR)/rc6.d/K12testbed
$(INSTALL) -m 755 $(SRCDIR)/tbprepare $(RCDIR)/init.d/tbprepare
-ln -sf $(RRCDIR)/init.d/tbprepare $(RCDIR)/rc1.d/K89tbprepare
-ln -sf $(RRCDIR)/init.d/tbprepare $(RCDIR)/rc6.d/K89tbprepare
$(INSTALL) -m 755 -o root -g wheel -d $(SYSETCDIR)/cron.pend
if [ -e $(SYSETCDIR)/cron.daily/slocate.cron ]; then \
mv -f $(SYSETCDIR)/cron.daily/slocate.cron \
......@@ -124,6 +127,7 @@ script-install: dir-install $(SCRIPTS)
$(INSTALL) -m 755 $(SRCDIR)/rc.ipod $(BINDIR)/rc/rc.ipod
$(INSTALL) -m 755 $(SRCDIR)/rc.kname $(BINDIR)/rc/rc.kname
$(INSTALL) -m 755 $(SRCDIR)/prepare $(BINDIR)/prepare
$(INSTALL) -m 755 $(SRCDIR)/reboot_prepare $(BINDIR)/reboot_prepare
$(INSTALL) -m 755 $(SRCDIR)/ixpboot $(BINDIR)/ixpboot
$(INSTALL) -m 755 $(SRCDIR)/rc.ixp $(BINDIR)/rc/rc.ixp
$(INSTALL) -m 755 ./sethostname.dhclient $(BINDIR)/sethostname.dhclient
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# Copyright (c) 2000-2006 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -249,5 +249,7 @@ foreach my $file (@SOCKETS) {
}
}
# Leave this print statement here; create_image depends on it.
print "prepare ran successfully!\n";
exit 0;
#!/bin/sh
#
# Arrange for "prepare" to be run on the way down.
#
touch /var/lock/subsys/tbprepare
/sbin/reboot
exit 0