/[cvs]/nfo/perl/scripts/umltools/UML/Control.pm
ViewVC logotype

Contents of /nfo/perl/scripts/umltools/UML/Control.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations)
Mon Sep 20 22:11:17 2004 UTC (19 years, 7 months ago) by joko
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +14 -3 lines
+ changing ownership of uml directory
+ kernel name now configurable; used via $vhost->{'kernel'}
+ third partition via: ubd3=$vhost_path/datafs/$vhost->{'datafs2'}

1 package UML::Control;
2
3 use strict;
4 use warnings;
5
6 use UML::Config;
7 use UML::Utils;
8 use Data::Dumper;
9
10 # setup configuration
11 my $DEBUG_STEP = $UML::Config::DEBUG_STEP;
12 my $username_runas = $ENV{USER};
13 my $cmd_prefix = "";
14 if ($username_runas ne "service") {
15 # $cmd_prefix = "$sudo -u service";
16 }
17
18 END { print "\n"; }
19
20 my $lockdir = '/home/service/var/lock';
21
22 sub lock {
23 my $vhost_name = shift;
24 my $cmd = "> $lockdir/uml_$vhost_name.lock";
25 system($cmd);
26 }
27
28 sub unlock {
29 my $vhost_name = shift;
30 my $cmd = "$rm $lockdir/uml_$vhost_name.lock";
31 print "\n", "unlocking via \"$cmd\"", "\n";
32 system($cmd);
33 }
34
35 sub is_locked {
36 my $vhost_name = shift;
37 return (-e "$lockdir/uml_$vhost_name.lock");
38 }
39
40 sub ensureSafeAction {
41 my $vhost_name = shift;
42
43 if (!vhost_exists($vhost_name)) {
44 die("vhost \"$vhost_name\" does not exists, exit.");
45 }
46
47 if (is_locked($vhost_name)) {
48 die("\"$vhost_name\" is locked, unlock via \"rm $lockdir/uml_$vhost_name.lock\"!!!");
49 }
50 }
51
52 sub isDown {
53 my $vhost_name = shift;
54 my $rootfs = UML::Config::get_host_rootfs($vhost_name);
55 my $cmd = "$fuser $rootfs";
56 my $res = `$cmd`;
57 if ($res) {
58 return 0;
59 } else {
60 return 1;
61 }
62 }
63
64 sub waitForShutdown {
65 my $vhost_name = shift;
66 print "waiting for shutdown of \"$vhost_name\" ";
67 while (!isDown($vhost_name)) {
68 print ".";
69 sleep 3;
70 }
71 print "\n";
72 }
73
74
75 sub prepare {
76
77 my $vhost_name = shift;
78
79 # ensureSafeAction($vhost_name);
80 # lock($vhost_name);
81
82 my $userid = get_sys_userid();
83 #print "id: $userid", "\n";
84 if ($userid != 0) {
85 die(__PACKAGE__ . "::prepare can only be executed by root!");
86 }
87
88 my $vhost = get_host_cfg($vhost_name);
89 #print Dumper($vhost); exit;
90
91 my $vhost_path = get_host_basepath($vhost_name);
92 my $device_bridge = $vhost->{'bridge'}{'device'};
93
94 my $host_device = $vhost->{main}{'device'};
95 my $hostip = $vhost->{'main'}{'ip'};
96 my $netmask = $vhost->{'main'}{'netmask'};
97 my $broadcast = $vhost->{'main'}{'broadcast'};
98 my $ip = $vhost->{'net'}{'ip'};
99
100 my $cmd;
101
102
103 # network-bridge
104
105 my $owner_netbridge;
106 $owner_netbridge = $vhost->{'bridge'}{'owner'};
107 # use the identity of the user running this script
108 $owner_netbridge ||= "";
109
110
111 # # creating tap-devices with tunctl, if necessary
112 # $device_bridge =~ m/tap(\d+)/;
113 # my $tapnum = $1;
114 # while (get_tapnumber() lt $tapnum) {
115 # print "creating TAP", "\n";
116 # inc_tapnumber();
117 # }
118
119
120
121
122
123 # networking
124
125 $cmd = "$mount -o remount,rw /proc";
126 askCmd("", $cmd, "remounting /proc-filesystem read-write");
127
128 $cmd = "echo 1 > /proc/sys/net/ipv4/ip_forward";
129 askCmd("", $cmd, "enabling proxy-arp for \"$device_bridge\"");
130
131 $cmd = "$route del -host $ip dev $device_bridge gw $ip";
132 askCmd("", $cmd, "deleting route to \"$ip\" via \"$device_bridge\"");
133
134 #$cmd = "$ifconfig $device_bridge $hostip netmask $netmask broadcast $broadcast down";
135 $cmd = "$ifconfig $device_bridge $hostip netmask $netmask down";
136 askCmd("", $cmd, "shutting down device \"$device_bridge\"");
137
138
139 # initialize tap-device with tunctl
140 # determine user-id of device-owner
141 my $bridgeid = get_sys_userid($owner_netbridge);
142 # delete tap-device
143 $cmd = "$tunctl -d $device_bridge";
144 askCmd("", $cmd, "removing tap-device $device_bridge");
145 # create tap-device
146 $cmd = "$tunctl -t $device_bridge -u $bridgeid";
147 askCmd("", $cmd, "creating tap-device $device_bridge for owner $bridgeid");
148
149
150 $cmd = "$ifconfig $device_bridge $hostip netmask $netmask up";
151 askCmd("", $cmd, "setting up device \"$device_bridge\"");
152
153 $cmd = "$route add -host $ip dev $device_bridge gw $ip";
154 askCmd("", $cmd, "adding route to \"$ip\" via \"$device_bridge\"");
155
156 $cmd = "echo 1 > /proc/sys/net/ipv4/conf/$device_bridge/proxy_arp";
157 askCmd("", $cmd, "enabling proxy-arp for \"$device_bridge\"");
158
159 $cmd = "$arp -Ds $ip $host_device pub";
160 askCmd("", $cmd, "adding arp-entry for \"$ip\"");
161
162 $cmd = "$mount -o remount,r /proc";
163 askCmd("", $cmd, "remounting /proc-filesystem read-only");
164
165 $cmd = "$chmod 666 /dev/net/tun";
166 askCmd("", $cmd, "setting proper file-permissions on device");
167
168 $cmd = "/home/service/bin/iptables/iptables.accounting_tap $ip $device_bridge";
169 askCmd("", $cmd, "accounting-rules for \"$ip\"");
170
171 }
172
173 sub start {
174
175 my $vhost_name = shift;
176
177 my $vhost_t = get_host_cfg($vhost_name);
178 # print Dumper($vhost_t); exit;
179
180 # any other operations pending?
181 ensureSafeAction($vhost_name);
182
183 # don't try to start host if it seems to be up and running
184 if (!isDown($vhost_name)) {
185 print "$vhost_name is already running.", "\n";
186 return;
187 }
188
189 # get host config
190 my $vhost = get_host_cfg($vhost_name);
191
192 my $vhost_path = get_host_basepath($vhost_name);
193 my $device_bridge = $vhost->{'bridge'}{'device'};
194 my $ip = $vhost->{'net'}{'ip'};
195 my $host_device = $vhost->{main}{'device'};
196
197 my $owner;
198 $owner = get_sys_username();
199
200 # TODO: do an owner-check/change
201 # if ($owner != $owner_should_be) { ... }
202
203 #lock($vhost_name);
204
205 my $cmd;
206
207 my $umlowner = $vhost->{main}{'owner'};
208 $cmd = "$chown -R $umlowner.$umlowner $vhost_path";
209 askCmd("do it", $cmd, "changing ownership of uml directory");
210 #exit;
211
212 #print "\n\n";
213
214 my $cmd_screen = "$screen -m -d -S $vhost_name ";
215
216 # was: $cmd_screen $cmd_prefix $linux \\
217
218 my $start_cmd = "
219 $cmd_screen $cmd_prefix \\
220 $vhost->{'kernel'} \\
221 mem=$vhost->{'mem'} \\
222 umid=$vhost->{'umid'} \\
223 uml_dir=$vhost_path/var \\
224 $host_device=tuntap,$device_bridge \\
225 ubd0=$vhost_path/rootfs/$vhost->{'rootfs'} \\
226 ubd1=$vhost_path/$vhost->{'swapfs'} \\
227 ubd2=$vhost_path/datafs/$vhost->{'datafs'} \\
228 ubd3=$vhost_path/datafs/$vhost->{'datafs2'}"; # > $vhost_path/boot.msg &";
229
230 # ubd2=$vhost_path/datafs/$vhost->{'datafs'} >> /dev/null"; # > $vhost_path/boot.msg";
231
232 #print $start_cmd; exit;
233
234 askCmd("do it", $start_cmd, "starting \"$vhost_name\" on \"$ip\"");
235 unlock($vhost_name);
236
237 print "\n";
238
239 print <<EOM;
240 Please note:
241 Your linux called "$vhost_name" is running as "$owner".
242 Since "screen" is used here, there are some issues you should know about:
243 You can't use the normal "su" to switch to this user from a root shell,
244 because the Terminal of this shell would still be owned by root.
245 (see http://groups.yahoo.com/group/gnu-screen/message/237)
246 This can simply be resolved by "chown"ing the tty-device to the
247 wanna-be user before doing a "su".
248 The program "sue" (included in this distribution) does exactly this.
249
250 Howto use your running linux:
251 - login via ssh to the specified ip-address or
252 - use "sue" and "screen" to switch to a running linux on the host system
253 #> sue <username>
254 #> screen -r <linuxname>
255 example:
256 #> sue service
257 #> screen -r quepasa
258
259 Detach from this screen by pressing: CTRL-A, CTRL-D
260
261 EOM
262
263 }
264
265
266 sub kill {
267
268 my $vhost_name = shift;
269
270 my $vhost = get_host_cfg($vhost_name);
271 my %vhost = %{$vhost};
272 my $vhost_path = get_host_basepath($vhost_name);
273
274 my $pid_main;
275
276 my $pidfile = "$vhost_path/var/$vhost_name/pid";
277 if (open FH, $pidfile) {
278 $pid_main = <FH>;
279 close FH;
280 chomp($pid_main);
281 }
282
283 my $cmd;
284
285 my $mconsole_file = "$vhost_path/var/$vhost_name/mconsole";
286 if (-e $mconsole_file) {
287 $cmd = "$uml_mconsole $mconsole_file halt";
288 #askCmd("do it", $cmd);
289 }
290
291 my @signals = (qw( TERM KILL ));
292
293 foreach my $signal (@signals) {
294
295 my $signame = 'SIG' . $signal;
296
297 # send signal to main process
298 if ($pid_main) {
299 print "sending main process the $signal signal", "\n";
300 #$cmd = "$kill -9 $pid_main";
301 $cmd = "$kill -s $signame $pid_main";
302 askCmd("do it", $cmd);
303 sleep 3;
304 }
305
306 # get list of processes
307 $cmd = "$ps ax";
308 my $procs = `$cmd`;
309 my @procs = split("\n", $procs);
310
311 # filter out child processes
312 my $regex = '\(' . $vhost_name . '\)';
313 @procs = grep(/$regex/, @procs);
314
315 next if (!@procs);
316 print "sending child processes the $signal signal", "\n";
317
318 # send signal to each process
319 foreach my $procline (@procs) {
320 $procline = substr($procline, 0, 80);
321 chomp($procline);
322 $procline =~ m/^[|\s]*(\w+)/;
323 my $pid = $1;
324 next if (!$pid);
325
326 if ($DEBUG_STEP) {
327 print $procline, "\n";
328 }
329 #$cmd = "$kill -9 $pid";
330 $cmd = "$kill -s $signal $pid";
331 askCmd("do it", $cmd);
332 }
333
334 # wait a bit
335 sleep 3;
336
337 }
338
339 }
340
341 sub stop {
342 my $vhost_name = shift;
343 stop_ssh($vhost_name);
344 }
345
346 sub stop_ssh {
347
348 my $vhost_name = shift;
349
350 my $vhost = get_host_cfg($vhost_name);
351 # print Dumper($vhost); exit;
352
353 my %vhost = %{$vhost};
354 my $vhost_path = get_host_basepath($vhost_name);
355
356 my $cmd;
357
358 ensureSafeAction($vhost_name);
359 lock($vhost_name);
360
361 # -----------------------------
362 # is: (via ssh-command) ;)
363 # done:
364 # - proper sync
365 # - proper shutdown
366 # todo:
367 # - abstract bd-account
368 # - automate setup of bd-account
369 my $ip = $vhost{'net'}{'ip'};
370 #my $remotecmd = "$sync && $poweroff";
371 #my $remotecmd = "$sync && $shutdown -h now";
372 my $remotecmd = "$sync && $halt";
373
374 print "Trying to reach $vhost_name via ssh to send shutdown command", "\n";
375 $cmd = "$cmd_prefix $ssh bd\@$ip \"$remotecmd\"";
376 askCmd("do it", $cmd);
377
378 unlock($vhost_name);
379
380 }
381
382 sub restart {
383
384 my $vhost_name = shift;
385 ensureSafeAction($vhost_name);
386
387 stop($vhost_name);
388 waitForShutdown($vhost_name);
389 start($vhost_name);
390
391 return;
392
393 lock($vhost_name);
394
395 my $vhost = get_host_cfg($vhost_name);
396 my %vhost = %{$vhost};
397 my $vhost_path = get_host_basepath($vhost_name);
398
399 my $cmd;
400 $cmd = "/usr/bin/uml_mconsole $vhost_path/var/$vhost_name/mconsole reboot";
401 askCmd("do it", $cmd);
402
403 unlock($vhost_name);
404
405 }
406
407 sub get_tapnumber {
408
409 my $infile = '/proc/net/dev';
410
411 open(FH, "<$infile");
412 my @lines = <FH>;
413 close(FH);
414
415 my $tapnumber = -1;
416 foreach (@lines) {
417 if (m/tap(\d+):/) {
418 my $tmp_tapnumber = $1;
419 if ($tmp_tapnumber gt $tapnumber) {
420 $tapnumber = $tmp_tapnumber;
421 }
422 }
423 }
424
425 return $tapnumber;
426
427 }
428
429 sub inc_tapnumber {
430 my $cmd;
431 $cmd = "/usr/bin/tunctl";
432 askCmd("do it", $cmd);
433 }
434
435 1;

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed