]> git.pld-linux.org Git - packages/VMware-server.git/blob - VMware-server.init
- massive change ( validate errors warrings from desktop-file-validate)
[packages/VMware-server.git] / VMware-server.init
1 #!/bin/sh
2
3 #
4 # Copyright 1998 VMware, Inc.  All rights reserved.
5 #
6
7 # vmnet:        Manages the services needed to run VMware networking
8 #
9 # description:  Manages the services needed to run VMware networking
10 #
11 # chkconfig:    235 90 8
12 #
13 # probe:        true
14 # hide:         true
15
16 subsys=vmnet
17 driver=vmmon
18 vnet=vmnet
19 bridge=vmnet-bridge
20 dhcpd=vmnet-dhcpd
21 netifup=vmnet-netifup
22 natd=vmnet-natd
23 ping=vmware-ping
24 smbd=vmware-smbd
25 nmbd=vmware-nmbd
26
27 # Source config files
28 vmware_etc_dir=/etc/vmware
29 vmnet_cfg="$vmware_etc_dir"/vmnet.conf
30 VM_BINDIR=/usr/bin
31
32 for f in $vmnet_cfg; do
33         if [ -r $f ]; then
34                 . $f
35         else    
36                 echo "FATAL: Unable to read $f"
37                 exit 1
38         fi
39 done    
40
41 # System wide functions
42 . /etc/rc.d/init.d/functions
43
44 # Create /dev/vmnetXX device
45 vmware_create_vmnet() {
46     local vHubNr="$1" # IN
47     local vDevice="/dev/vmnet$vHubNr"
48
49     if [ ! -e "$vDevice" ]; then
50         mknod -m 600 "$vDevice" c 119 "$vHubNr"
51     fi
52 }
53                   
54 #
55 # Create a temporary directory
56 #
57
58 # They are a lot of small utility programs to create temporary files in a
59 # secure way, but none of them is standard. So I wrote this --hpreg
60 make_tmp_dir() {
61         local dirname="$1" # OUT
62         local prefix="$2"  # IN
63         local tmp
64         local serial
65         local loop
66
67         tmp="${TMPDIR:-/tmp}"
68         # Don't overwrite existing user data
69         # -> Create a directory with a name that didn't exist before
70         #
71         # This may never succeed (if we are racing with a malicious process), but at
72         # least it is secure
73         serial=0
74         loop='yes'
75         while [ "$loop" = 'yes' ]; do
76                 # Check the validity of the temporary directory. We do this in the loop
77                 # because it can change over time
78                 if [ ! -d "$tmp" ]; then
79                         echo 'Error: "'"$tmp"'" is not a directory.'
80                         echo
81                         exit 1
82                 fi
83                 if [ ! -w "$tmp" -o ! -x "$tmp" ]; then
84                         echo 'Error: "'"$tmp"'" should be writable and executable.'
85                         echo
86                         exit 1
87                 fi
88                 # Be secure
89                 # -> Don't give write access to other users (so that they can not use this
90                 # directory to launch a symlink attack)
91                 if mkdir -m 0755 "$tmp"'/'"$prefix$serial" >/dev/null 2>&1; then
92                         loop='no'
93                 else
94                         serial=`expr "$serial" + 1`
95                         if [ "`expr "$serial" % 200`" = '0' ]; then
96                                 echo 'Warning: The "'"$tmp"'" directory may be under attack.'
97                                 echo
98                         fi
99                 fi
100         done
101         eval "$dirname"'="$tmp"'"'"'/'"'"'"$prefix$serial"'
102 }
103
104 #
105 # Utilities
106 #
107
108 # Compute the subnet address associated to a couple IP/netmask
109 ipv4_subnet() {
110         local ip="$1"
111         local netmask="$2"
112
113         # Split quad-dotted addresses into bytes
114         # There is no double quote around the back-quoted expression on purpose
115         # There is no double quote around $ip and $netmask on purpose
116         set -- `IFS='.'; echo $ip $netmask`
117         echo $(($1 & $5)).$(($2 & $6)).$(($3 & $7)).$(($4 & $8))
118 }
119
120 # Compute the broadcast address associated to a couple IP/netmask
121 ipv4_broadcast() {
122         local ip="$1"
123         local netmask="$2"
124
125         # Split quad-dotted addresses into bytes
126         # There is no double quote around the back-quoted expression on purpose
127         # There is no double quote around $ip and $netmask on purpose
128         set -- `IFS='.'; echo $ip $netmask`
129         echo $(($1 | (255 - $5))).$(($2 | (255 - $6))).$(($3 | (255 - $7))).$(($4 | (255 - $8)))
130 }
131
132 # Count the number of running virtual machines by looking at the number of references
133 # to the $driver module.
134 countVMs() {
135         # Beware of module dependancies here. An exact match is important
136         /sbin/lsmod | awk 'BEGIN {n = 0;} {if ($1 == "'"$driver"'") n = $3;} END {print n;}'
137 }
138
139 # Check if there is an IP route for a given subnet via a given interface
140 # Return true if there is _NO_ such route
141 noRoutePresent() {
142         local subnet="$1" # IN
143         local intf="$2"   # IN
144
145         # Beware, there may be several identical routes
146         [ "`/sbin/route -n | grep '^'"$subnet"'.*'"$intf"'$'`" = '' ]
147 }
148
149
150 # Macro definitions
151 #
152 # Note:
153 #  . Each daemon must be started from its own directory to avoid busy devices
154 #  . Each PID file doesn't need to be added to the installer database, because
155 #    it is going to be automatically removed when it becomes stale (after a
156 #    reboot). It must go directly under /var/run, or some distributions
157 #    (RedHat 6.0) won't clean it
158 #
159
160 # Terminate a process synchronously
161 vmware_synchrone_kill() {
162         local pid="$1"    # IN
163         local signal="$2" # IN
164         local second
165
166         kill -"$signal" "$pid"
167         # Wait a bit to see if the dirty job has really been done
168         for second in 0 1 2 3 4 5 6 7 8 9 10; do
169                 if [ ! -d /proc/"$pid" ]; then
170                         # Success
171                         return 0
172                 fi
173                 sleep 1
174         done
175         # Timeout
176         return 1
177 }
178
179 # Kill the process associated to a pidfile
180 vmware_stop_pidfile() {
181         local pidfile="$1" # IN
182         local pid
183
184         pid=`cat "$pidfile" 2>/dev/null`
185         if [ "$pid" = '' ]; then
186                 # The file probably does not exist or is empty. Success
187                 return 0
188         fi
189         # Keep only the first number we find, because some Samba pid files are really
190         # trashy: they end with NUL characters
191         # There is no double quote around $pid on purpose
192         set -- $pid
193         pid="$1"
194         # First try a nice SIGTERM
195         if vmware_synchrone_kill "$pid" 15; then
196                 return 0
197         fi
198         # Then send a strong SIGKILL
199         if vmware_synchrone_kill "$pid" 9; then
200                 return 0
201         fi
202         return 1
203 }
204
205 # Start the host-only network user service
206 vmware_start_hostonly() {
207         local vHubNr="$1"    # IN
208         local vHostIf="$2"   # IN
209         local ifIp="$3"      # IN
210         local ifMask="$4"    # IN
211         local run_dhcpd="$5" # IN
212         local run_samba="$6" # IN
213         local ifNet
214
215         # Do a cursory check to see if the host-only network
216         # configuration is still ok.  We do this so that mobile
217         # hosts don't get setup at install time and then moved to
218         # a new locale where the host-only network config is no
219         # longer valid.
220         #
221         # NB: This really needs to be done at power-on time when
222         #     VM is configured to use host-only networking so that
223         #     we aren't fooled by dynamic changes in the network.
224         #
225         # XXX ping takes 10 seconds to timeout if nobody answers
226         #     that slows boot too much so we do this bit in the
227         #     background.
228         if "$VM_BINDIR"/"$ping" -q "$ifIp"; then
229                 echo 'Host-only networking disabled because '"$ifIp"
230                 echo 'appears to be a real, physical, existing address.'
231                 echo 'Please modify your host-only network configuration.'
232                 exit 1
233         fi
234         cd "$VM_BINDIR" && "$VM_BINDIR"/"$netifup" \
235           -d /var/run/"$netifup"-"$vHostIf".pid /dev/vmnet"$vHubNr" "$vHostIf"
236         [ "$?" -eq 0 ] || exit 1
237         # Configure the virtual host ethernet interface and define the private IP
238         # network
239         #
240         # . We provide the broadcast address explicitly because versions of ifconfig
241         #   prior to 1.39 (1999-03-18) seem to miscompute it
242         # . 2.0.x kernels don't install a route when the interface is marked up, but
243         #   2.2.x kernel do. Since we want to see any errors from route we don't
244         #   just discard messages from route, but instead check if the route got
245         #   installed before manually adding one.
246         ifNet=`ipv4_subnet "$ifIp" "$ifMask"`
247         if ifconfig "$vHostIf" inet "$ifIp" netmask "$ifMask" \
248           broadcast "`ipv4_broadcast "$ifIp" "$ifMask"`" up \
249           && noRoutePresent "$ifNet" "$vHostIf"; then
250                 route add -net "$ifNet" netmask "$ifMask" "$vHostIf"
251         fi
252         if [ "$run_dhcpd" = 'yes' ]; then
253                 # Start a DHCP server on a private IP network
254                 # The daemon already logs its output in the system log, so we can safely
255                 # trash it
256                 cd "$VM_BINDIR" && "$VM_BINDIR"/"$dhcpd" \
257                   -cf "$vmware_etc_dir"/"$vHostIf"/dhcpd/dhcpd.conf \
258                   -lf "$vmware_etc_dir"/"$vHostIf"/dhcpd/dhcpd.leases \
259                   -pf /var/run/"$dhcpd"-"$vHostIf".pid "$vHostIf" >/dev/null 2>&1 || exit 1
260         fi
261         if [ "$run_samba" = 'yes' ]; then
262                 # Start a SMB name server on a private IP network
263                 # Disable logging to avoid the uncontrolled creation of unmanaged files
264                 cd "$VM_BINDIR" && "$VM_BINDIR"/"$nmbd" -D -l /dev/null \
265                   -s "$vmware_etc_dir"/"$vHostIf"/smb/smb.conf \
266                   -f /var/run/"$nmbd"-"$vHostIf".pid || exit 1
267                 # Start a SMB share server on a private IP network
268                 # Disable logging to avoid the uncontrolled creation of unmanaged files
269                 cd "$VM_BINDIR" && "$VM_BINDIR"/"$smbd" -D -l /dev/null \
270                   -s "$vmware_etc_dir"/"$vHostIf"/smb/smb.conf \
271                   -f /var/run/"$smbd"-"$vHostIf".pid || exit 1
272         fi
273 }
274
275 # Stop the host-only network user service
276 vmware_stop_hostonly() {
277         local vHostIf="$1"   # IN
278         local ifIp="$2"      # IN
279         local ifMask="$3"    # IN
280         local ifNet
281
282         # Terminate the private network
283         ifNet=`ipv4_subnet "$ifIp" "$ifMask"`
284         noRoutePresent "$ifNet" "$vHostIf" || route del -net "$ifNet" netmask "$ifMask" || exit 1
285         # To test if the interface exists, we can not just look at the exitcode
286         # because old versions of ifconfig don't exit with 1 when invoked with a
287         # non-existing interface
288         if [ "`ifconfig "$vHostIf" 2>/dev/null`" != '' ]; then
289                 ifconfig "$vHostIf" down || exit 1
290         fi
291         vmware_stop_pidfile /var/run/"$netifup"-"$vHostIf".pid || exit 1
292 }
293
294 # See how we were called.
295 case "$1" in
296   start)
297         if [ -f /var/lock/subsys/"$subsys" ]; then
298                 msg_already_running "VMware Workstation networking"
299         fi      
300         # Try to load parport_pc. Failure is allowed as it does not exist
301         # on kernels 2.0
302         /sbin/modprobe parport_pc >/dev/null 2>&1
303         msg_starting 'Virtual machine monitor'
304         busy
305         /sbin/modprobe $driver
306         [ "$?" -eq "0" ] && ok || fail
307         if [ "$VM_NETWORKING" = 'yes' ]; then
308                 msg_starting 'Virtual ethernet'
309                 busy
310                 /sbin/modprobe $vnet
311                 [ "$?" -eq 0 ] && ok || fail
312                 vHubNr=0
313                 while [ $vHubNr -lt 9 ]; do
314                         eval 'interface="$VNET_'"$vHubNr"'_INTERFACE"'
315                         eval 'hostaddr="$VNET_'"$vHubNr"'_HOSTONLY_HOSTADDR"'
316                         eval 'netmask="$VNET_'"$vHubNr"'_HOSTONLY_NETMASK"'
317                         if [ -n "$interface" ]; then
318                                 vmware_create_vmnet "$vHubNr"
319                                 # Connect a physical host ethernet interface to a virtual ethernet hub
320                                 msg_starting 'Bridged networking on /dev/vmnet'"$vHubNr"
321                                 busy
322                                 cd "$VM_BINDIR" && "$VM_BINDIR"/"$bridge" \
323                                   -d /var/run/"$bridge"-"$vHubNr".pid /dev/vmnet"$vHubNr" "$interface"
324                                 [ "$?" -eq 0 ] && ok || fail
325                         elif [ -n "$hostaddr" -a -n "$netmask" ]; then
326                                 vmware_create_vmnet "$vHubNr"
327                                 eval 'samba="$VNET_'"$vHubNr"'_SAMBA"'
328                                 msg_starting 'Host-only networking on /dev/vmnet'"$vHubNr"
329                                 busy
330                                 vmware_start_hostonly "$vHubNr" 'vmnet'"$vHubNr" "$hostaddr" \
331                                   "$netmask" 'yes' "$samba"
332                                 [ "$?" -eq 0 ] && ok || fail
333                                 eval 'nat="$VNET_'"$vHubNr"'_NAT"'
334                                 if [ "$nat" = 'yes' ]; then
335                                         # Start the NAT network user service
336                                         msg_starting 'NAT networking on /dev/vmnet'"$vHubNr"
337                                         busy
338                                         cd "$VM_BINDIR" && "$VM_BINDIR"/"$natd" \
339                                           -d /var/run/"$natd"-"$vHubNr".pid \
340                                           -m /var/run/"$natd"-"$vHubNr".mac \
341                                           -c "$vmware_etc_dir"/vmnet"$vHubNr"/nat/nat.conf >/dev/null 2>&1
342                                         [ "$?" -eq 0 ] && ok || fail
343                                 fi
344                         fi
345                         vHubNr=$(($vHubNr + 1))
346                 done
347         fi
348         touch /var/lock/subsys/"$subsys"
349         ;;
350
351   stop)
352         if [ "`countVMs`" -gt 0 ]; then
353                 echo 'At least one instance of VMware Workstation is still running.'
354                 echo 'Please stop all running instances of VMware Workstation first.'
355                 echo
356         fi
357         if [ ! -f /var/lock/subsys/"$subsys" ]; then
358                 msg_not_running "VMware Workstation networking"
359         fi      
360         # Try to unload parport_pc. Failure is allowed as it does not exist
361         # on kernels 2.0, and some other process could be using it.
362         /sbin/modprobe -r parport_pc >/dev/null 2>&1
363         if [ "$VM_NETWORKING" = "yes" ]; then
364                 # NB: must kill off processes using vmnet before
365                 #     unloading module
366                 vHubNr=0
367                 while [ $vHubNr -lt 9 ]; do
368                         eval 'interface="$VNET_'"$vHubNr"'_INTERFACE"'
369                         eval 'hostaddr="$VNET_'"$vHubNr"'_HOSTONLY_HOSTADDR"'
370                         eval 'netmask="$VNET_'"$vHubNr"'_HOSTONLY_NETMASK"'
371                         if [ -n "$interface" ]; then
372                                 # Disconnect a physical host ethernet interface from a virtual ethernet hub
373                                 msg_stopping "Bridged networking on /dev/vmnet$vHubNr"
374                                 busy
375                                 vmware_stop_pidfile /var/run/"$bridge"-"$vHubNr".pid
376                                 [ "$?" -eq 0 ] && ok || fail
377                         elif [ -n "$hostaddr" -a -n "$netmask" ]; then
378                                 # Stop a DHCP server on a private IP network
379                                 msg_stopping "DHCP server on /dev/vmnet$vHubNr"
380                                 busy
381                                 vmware_stop_pidfile /var/run/"$dhcpd"-"vmnet$vHubNr".pid
382                                 [ "$?" -eq 0 ] && ok || fail
383                                 eval 'samba="$VNET_'"$vHubNr"'_SAMBA"'
384                                 if [ "$samba" = "yes" ]; then
385                                         # Stop a SMB share server on a private IP network
386                                         msg_stopping 'SMB share server on /dev/vmnet'"$vHubNr"
387                                         busy
388                                         vmware_stop_pidfile /var/run/"$smbd"-'vmnet'"$vHubNr".pid
389                                         [ "$?" -eq 0 ] && ok || fail
390                                         # Stop a SMB name server on a private IP network
391                                         msg_stopping 'SMB name server on /dev/vmnet'"$vHubNr"
392                                         busy
393                                         vmware_stop_pidfile /var/run/"$nmbd"-'vmnet'"$vHubNr".pid
394                                         [ "$?" -eq 0 ] && ok || fail
395                                 fi
396                                 eval 'nat="$VNET_'"$vHubNr"'_NAT"'
397                                 if [ "$nat" = "yes" ]; then
398                                         # Stop the NAT network user service
399                                         msg_stopping 'NAT networking on /dev/vmnet'"$vHubNr"
400                                         busy
401                                         vmware_stop_pidfile /var/run/"$natd"-"$vHubNr".pid
402                                         [ "$?" -eq 0 ] && ok || fail
403                                 fi
404                                 msg_stopping 'Host-only networking on /dev/vmnet'"$vHubNr"
405                                 busy
406                                 vmware_stop_hostonly 'vmnet'"$vHubNr" "$hostaddr" "$netmask"
407                                 [ "$?" -eq 0 ] && ok || fail
408
409                         fi
410                         vHubNr=$(($vHubNr + 1))
411                 done
412                 msg_stopping 'Virtual machine monitor'
413                 busy
414                 if /sbin/lsmod | grep -q ^"$driver"; then
415                         /sbin/rmmod "$driver"
416                 fi
417                 [ "$?" -eq "0" ] && ok || fail
418                 msg_stopping 'Virtual ethernet'
419                 busy
420                 if /sbin/lsmod | grep -q ^"$vnet"; then
421                         /sbin/rmmod "$vnet"
422                 fi
423                 [ "$?" -eq "0" ] && ok || fail
424         fi
425         rm -f /var/lock/subsys/"$subsys"
426         ;;
427   status)
428         if [ "`countVMs`" -gt 0 ]; then
429                 echo 'At least one instance of VMware Workstation is still running.'
430                 echo
431         fi
432         if [ "$VM_NETWORKING" = "yes" ]; then
433                 status "$bridge"
434                 status "$dhcpd"
435                 status "$netifup"
436         fi
437         if [ "$VM_NETWORKING" = "yes" ]; then
438                 echo -n "Module $vnet "
439                 /sbin/modprobe "$vnet" >/dev/null 2>&1 && echo installed || echo "not installed"
440         fi
441         ;;
442   restart)
443         "$0" stop && "$0" start
444         ;;
445   *)
446         echo "Usage: `basename "$0"` {start|stop|status|restart}"
447         exit 3
448 esac
449
450 exit 0
This page took 0.059345 seconds and 3 git commands to generate.