rc.config 6.11 KB
Newer Older
1
2
#!/usr/bin/perl -w
#
3
# Copyright (c) 2004-2016 University of Utah and the Flux Group.
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#
use English;
use Getopt::Std;

#
# This is the entrypoint to running the config scripts. It would be nice
# to just stick these in a directory and run them all, but order matters
# and I hate naming things so that the order comes up the way I want it!
# Anyway, this script fires off the rc scripts in the proper order.
#
# All of the scripts accept a -j argument since in some cases we run these
# on behalf of a vnode, and the script needs to tell the tmcc library the
# vnodeid for when it talks to tmcd. Otherwise, libtmcc knows when it is
# running *inside* a vnode and sets things up properly for talking to tmcd.
#
sub usage()
{
    print "Usage: " .
	scriptname() . " [-j vnodeid] boot|shutdown|reconfig|reset\n";
    exit(1);
}
44
my $optlist = "j:dM";
45
46
47
48
my %options = ();
my $action  = "boot";
my $debug   = 0;
my $vnodeid;
49
my $updatemasterpasswdfiles = 0;
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

# 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;

# Protos.
sub doboot();
sub doshutdown();
sub doreconfig();
sub docleanup();

# Parse command line.
if (! getopts($optlist, \%options)) {
    usage();
}
if (defined($options{'j'})) {
    $vnodeid = $options{'j'};
    libsetup_setvnodeid($vnodeid);
}
if (defined($options{'d'})) {
    $debug++;
}
88
89
90
if (defined($options{'M'})) {
    $updatemasterpasswdfiles = 1;
}
91
92
93
94
95
96
97
98
99
100
# Allow default above.
if (@ARGV) {
    $action = $ARGV[0];
}

#
# The master list of scripts. Add in the right order! To speed things up
# specify a shorter set for the MFS.
#
my @bootscripts;
101
102
my %bootscript_args = ( 'rc.accounts' => $updatemasterpasswdfiles ?
			                 '-M' : '' );
103
104

if (MFS()) {
105
    @bootscripts = ("rc.misc", "rc.localize", "rc.mounts", "rc.accounts", 
Mike Hibler's avatar
Mike Hibler committed
106
107
		    "rc.hostnames", "rc.keys", "rc.tarfiles", "rc.rpms",
		    "rc.tpmsetup");
108
}
109
elsif (FAKEJAILED()) {
110
111
    @bootscripts = ("rc.misc", "rc.keys", "rc.route", "rc.tunnels",
		    "rc.ifconfig", "rc.progagent");
112
}
113
elsif (WINDOWS()) {
Mike Hibler's avatar
Mike Hibler committed
114
    @bootscripts = ("rc.misc", "rc.localize", "rc.keys", "rc.mounts",
115
		    "rc.accounts", "rc.topomap", 
116
		    "rc.route", "rc.ifconfig",
Russ Fish's avatar
Russ Fish committed
117
		    "rc.hostnames", "rc.lmhosts", "rc.syncserver", 
Russ Fish's avatar
Russ Fish committed
118
119
		    # rc.progagent is run by a separate service named ProgAgent.
		    # It's started by EmulabStartup after rc.bootsetup runs.
120
		    "rc.tarfiles", "rc.rpms");
121
122
} elsif (STORAGEHOST()) {
    @bootscripts = ("rc.misc","rc.localize","rc.keys");
123
}
124
125
126
127
128
129
130
elsif (INDOCKERVM()) {
    @bootscripts = ("rc.misc", "rc.localize", "rc.keys",
		    "rc.blobs", "rc.topomap", "rc.accounts",
		    "rc.route", "rc.tunnels",
		    "rc.trace", "rc.syncserver", "rc.trafgen",
		    "rc.tarfiles", "rc.rpms", "rc.progagent", "rc.linkagent"
		    );
David Johnson's avatar
David Johnson committed
131
}
132
else {
133
    @bootscripts = ("rc.firewall", "rc.tpmsetup",
134
135
136
137
138
139
140
		    "rc.misc", "rc.localize", "rc.keys",
		    #
		    # local blockstore setup should happen before rc.mounts,
		    # rc.blobs and rc.trace.
		    #
		    "rc.storagelocal",
		    "rc.mounts", "rc.blobs", "rc.topomap", "rc.accounts",
141
		    "rc.route", "rc.tunnels", "rc.ifconfig", "rc.delays",
142
143
		    "rc.hostnames",
		    #
144
145
146
		    # remote blockstore setup should be after rc.ifconfig
		    # and rc.hostnames. rc.storage handles its own mounts,
		    # so it is okay that it is called after rc.mounts.
147
		    #
148
		    "rc.storageremote", 
149
		    "rc.trace", "rc.syncserver", "rc.trafgen",
150
		    "rc.tarfiles", "rc.rpms", "rc.progagent", "rc.linkagent",
151
152
		    "rc.tiptunnels", "rc.motelog", "rc.simulator",
		    "rc.diskagent", "rc.nodecheck"
153
		    );
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
}

# Execute the action.
SWITCH: for ($action) {
    /^boot$/i && do {
	doboot();
	last SWITCH;
    };
    /^shutdown$/i && do {
	doshutdown();
	last SWITCH;
    };
    /^reconfig$/i && do {
	doreconfig();
	last SWITCH;
    };
    /^reset$/i && do {
	docleanup();
	last SWITCH;
    };
    fatal("Invalid action: $action");
}
exit(0);

sub doaction($@)
{
    my ($what, @scripts) = @_;
    
    #
    # Run all the scripts. We run them all, not worrying about individual
    # failure. Right thing to do? Maybe stop on failure?
    #
    my $optarg = (defined($vnodeid) ? "-j $vnodeid" : "");

188
    #
189
    # Grab our rc manifest so we can enable/disable/replace this script and
190
191
192
    # run (or not) its hooks.
    #
    my %manifest = ();
193
    getrcmanifest(\%manifest);
194

195
    foreach my $script (@scripts) {
196
197
198
199
200
201
	my $bargs = '';
	if (exists($bootscript_args{$script})
	    && defined($bootscript_args{$script})) {
	    $bargs = $bootscript_args{$script};
	}

202
203
204
205
	# No need to install all this cruft on the MFS or other small envs.
	next
	    if (!-x "$BINDIR/rc/$script");

206
	runbootscript(\%manifest,"$BINDIR/rc",$script,$what,"$optarg $bargs $what");
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    }
}

#
# Boot Action.
#
sub doboot()
{
    doaction("boot", @bootscripts);
}

#
# Shutdown Action.
#
sub doshutdown()
{
    doaction("shutdown", reverse(@bootscripts));
}

#
# Node Reconfig Action (without rebooting).
#
sub doreconfig()
{
    doshutdown();
    #
    # Must tell tmcc to reload its cache!
    # 
    tmccgetconfig();
    return doboot();
}

#
# Node cleanup action (node is reset to completely clean state).
#
sub docleanup()
{
244
    doaction("reset", reverse(@bootscripts));
245
}