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