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