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