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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide 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 joko 1.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 joko 1.2 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 joko 1.1 #print "\n\n";
213    
214     my $cmd_screen = "$screen -m -d -S $vhost_name ";
215    
216 joko 1.2 # was: $cmd_screen $cmd_prefix $linux \\
217    
218 joko 1.1 my $start_cmd = "
219 joko 1.2 $cmd_screen $cmd_prefix \\
220     $vhost->{'kernel'} \\
221 joko 1.1 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 joko 1.2 ubd2=$vhost_path/datafs/$vhost->{'datafs'} \\
228     ubd3=$vhost_path/datafs/$vhost->{'datafs2'}"; # > $vhost_path/boot.msg &";
229 joko 1.1
230     # ubd2=$vhost_path/datafs/$vhost->{'datafs'} >> /dev/null"; # > $vhost_path/boot.msg";
231    
232 joko 1.2 #print $start_cmd; exit;
233    
234 joko 1.1 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 joko 1.2 Your linux called "$vhost_name" is running as "$owner".
242 joko 1.1 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