home *** CD-ROM | disk | FTP | other *** search
/ Chip: Linux Special / CorelLinux_CHIP.iso / VMware / installer / services.sh < prev   
Encoding:
Linux/UNIX/POSIX Shell Script  |  1999-11-10  |  15.2 KB  |  553 lines

  1. #!/bin/sh
  2. #
  3. # Copyright (C) 1998-99, VMware, Inc.  All Rights Reserved.
  4. #
  5. # This script manages the services needed to run VMware
  6.  
  7. # Basic support for IRIX style chkconfig
  8. # chkconfig: 3 90 08
  9. # description: Manages the services needed to run VMware
  10.  
  11. vmware_etc_dir=/etc/vmware
  12.  
  13. #
  14. # Make the old installer aware of the new installer.sh mechanism.
  15. # Kludge time :)
  16. #
  17.  
  18. if [ "$1" = "stop" ]; then
  19.     pid=$$
  20.     ppid=`grep "^PPid:" /proc/"$pid"/status | cut -f 2`
  21.     parent_name=`grep "^Name:" /proc/"$ppid"/status | cut -f 2`
  22.     if [ "$parent_name" = "install.pl" ]; then
  23.     # The old installer called this script
  24.     vmware_installer="$vmware_etc_dir"/installer.sh
  25.         if [ -x "$vmware_installer" ]; then
  26.         echo 'A previous installation of VMware has been detected.'
  27.         echo
  28.  
  29.         kind=`"$vmware_installer" kind`
  30.         echo 'The previous installation was made by the '"$kind"' installer,'
  31.         echo 'which is more recent than this installer.'
  32.         echo 'This means that your are trying to downgrade or remove VMware.'
  33.         echo -n 'Do you really want to do this? (yes/no) [n] '
  34.         read answer
  35.             echo
  36.         case "$answer" in
  37.         y|Y|yes|Yes|YES)
  38.             vmware_db_bkp="$vmware_etc_dir"/db.tar.gz
  39.             "$vmware_installer" convertdb old "$vmware_db_bkp"
  40.             "$vmware_installer" uninstall
  41.             tar -C / -xzopf "$vmware_db_bkp"
  42.             rm -f "$vmware_db_bkp"
  43.             
  44.             exit 0
  45.             ;;
  46.             
  47.         *)
  48.             # Prevent the display of the old installer's error message
  49.             kill "$ppid"
  50.             exit 1
  51.             ;;
  52.         esac
  53.         else
  54.         echo 'Error: Unable to find the previous installer object '"$vmware_installer"'.'
  55.         echo
  56.  
  57.         # Exit with 0 otherwise the user will never be able to re-install
  58.             exit 0
  59.     fi
  60.     fi
  61. fi
  62.  
  63. #
  64. # From now on, this is a normal startup script. I swear.
  65. #
  66.  
  67. vmware_checkvm="$vmware_etc_dir"/checkvm
  68. if [ -x "$vmware_checkvm" ]; then
  69.     # The toolbox is installed
  70.     if "$vmware_checkvm" >/dev/null 2>&1; then
  71.     # We are in a VM. Do nothing.
  72.         exit 1
  73.     fi
  74. fi
  75.  
  76. # Since this script is installed, our database should be installed too and
  77. # should contain the basic information
  78. vmware_db="$vmware_etc_dir"/locations
  79. if [ ! -r "$vmware_db" ]; then
  80.     echo 'Warning: Unable to find VMware'"'"'s database '"$vmware_db"'.'
  81.     echo        
  82.     
  83.     exit 1
  84. fi
  85.  
  86. # Load an answer from the database
  87. db_load_answer() {
  88.     id="$1"
  89.  
  90.     grep '^remove_answer '"$id"'$\|^answer '"$id"' ' "$vmware_db" | tail -1 | sed -n 's/^answer '"$id"' //p'
  91. }
  92.  
  93. # Add a file to the database
  94. db_add_file() {
  95.     file="$1"
  96.  
  97.     echo 'file '"$file" >> "$vmware_db"
  98. }
  99.  
  100. # Clear the configuration flag
  101. clear_config_flag() {
  102.     confflag="$1"
  103.  
  104.     touch "$confflag"
  105.     chmod 644 "$confflag"
  106.     db_add_file "$confflag"
  107. }
  108.  
  109. vmware_init_dir=`db_load_answer 'INITDIR'`
  110. # This defines echo_success() and echo_failure() on RedHat
  111. # This defines obsolete daemon() and killproc() on some distributions
  112. if [ -r "$vmware_init_dir"/init.d/functions ]; then
  113.     . "$vmware_init_dir"/init.d/functions
  114. fi
  115.  
  116. # This defines $rc_done and $rc_failed on S.u.S.E.
  117. if [ -f /etc/rc.config ]; then
  118.      # Don't quite feel like including the entire file.
  119.      # There could be conflicts.
  120.      rc_done="\033[71G\033[32mdone\033[m"
  121.      rc_failed="\033[71G\033[31m\033[1mfailed\033[m"
  122. else
  123.      rc_done="\033[71G done"
  124.      rc_failed="\033[71Gfailed"
  125. fi
  126.  
  127. subsys=vmware
  128. driver=vmmon
  129. ppuser=vmppuser
  130. vnet=vmnet
  131. bridge=vmnet-bridge
  132. dhcpd=vmnet-dhcpd
  133. vmnet0=${vnet}0
  134. vmnet1=${vnet}1
  135. ping=vmware-ping
  136.  
  137. #
  138. # Utilities
  139. #
  140.  
  141. # Initialize some variables with values from the database
  142. variables_init() {
  143.     vmware_bin_dir=`db_load_answer 'BINDIR'`
  144.     vmware_networking=`db_load_answer 'NETWORKING'`
  145.     vmware_bridgeif=`db_load_answer 'VNET_INTERFACE'`
  146.     vmnetHostOnlyAddress=`db_load_answer 'VNET_HOSTONLY_HOSTADDR'`
  147.     vmnetHostOnlyNetmask=`db_load_answer 'VNET_HOSTONLY_NETMASK'`
  148. }
  149.  
  150. #
  151. # Count the number of running virtual machines
  152. # by looking at the number of references to the
  153. # $driver module.
  154. #
  155. countVMs() {
  156.     # The ^ matters because our modules can depend on other kernel modules
  157.     echo `/sbin/lsmod | \
  158.        awk 'BEGIN { n = 0; } /^'"$driver"'/ { n = $3; } END { print n; }'`
  159. }
  160.  
  161. #
  162. # Check if a route to a network via a specific interface
  163. # is installed.  Return true if it is _NOT_ present.
  164. #
  165. noRoutePresent() {
  166.     test X`/sbin/route -n | awk '/'"$1"'.*'"$2"'/ { print "yes"; }'` != Xyes
  167. }
  168.  
  169. #
  170. # Check if the Class C network is reachable by pinging
  171. # the host at <addr> (the address we'll be assign to
  172. # ourself.  This is used to check/verify a host-only
  173. # config before enabling the interface and starting DHCPD
  174. #
  175. # NB: If you don't want to do this test, just substitute
  176. #     false for it.
  177. #
  178. lookForHostOnlyNetwork() {
  179.     "$vmware_bin_dir"/"$ping" "$1"
  180. }
  181.  
  182. #
  183. # XXX This assumes a Class C address; should use the netmask
  184. # XXX to calculate the network number but that's too painful
  185. # XXX in the shell.
  186. #
  187. ipv4Network() {
  188.     echo "$1" | sed 's/[.][0-9]*$//'
  189. }
  190.  
  191. vmware_failed() {
  192.    if `type -type echo_failure >/dev/null`; then
  193.       echo_failure
  194.    else
  195.       echo -ne "$rc_failed"
  196.    fi
  197. }
  198.  
  199. vmware_success() {
  200.    if `type -type echo_success >/dev/null`; then
  201.       echo_success
  202.    else
  203.       echo -ne "$rc_done"
  204.    fi
  205. }
  206.  
  207. # Execute a macro
  208. # Parameters:
  209. #  $1 = service name
  210. #  $2 = executed name
  211. # Works with bash, zsh
  212. vmware_exec() {
  213.    # Display the service name
  214.    echo -n '   '"$1"
  215.  
  216.    # execute the macro and trash its output
  217.    # On Caldera 2.2, SIGHUP is sent to all our children when this script exits
  218.    # I wanted to use shopt -u huponexit instead but their bash is too old
  219.    if (trap '' SIGHUP; "$2") >/dev/null 2>&1
  220.    then
  221.       vmware_success
  222.       echo
  223.       return 0
  224.    else
  225.       vmware_failed
  226.       echo
  227.       return 1
  228.    fi
  229. }
  230.  
  231. # Execute a macro in the background
  232. # Parameters:
  233. #  $1 = service name
  234. #  $2 = executed name
  235. # Works with bash, zsh
  236. vmware_bg_exec() {
  237.    # Display the service name
  238.    echo -n '   '"$1"' (background)'
  239.  
  240.    # execute the macro in the background and log its output
  241.    # On Caldera 2.2, SIGHUP is sent to all our children when this script exits
  242.    # I wanted to use shopt -u huponexit instead but their bash is too old
  243.    (trap '' SIGHUP; "$2") 2>&1 | logger -t 'VMware[init]' -p daemon.err &
  244.  
  245.    # Display the execution result
  246.    vmware_success
  247.    echo
  248.    return 0
  249. }
  250.  
  251. #
  252. # Macro definitions
  253. #
  254.  
  255. # Start the virtual machine monitor kernel service
  256. vmware_start_vmmon() {
  257.    /sbin/insmod -s -f "$driver" || exit 1
  258.  
  259.    exit 0
  260. }
  261.  
  262. # Stop the virtual machine monitor kernel service
  263. vmware_stop_vmmon() {
  264.    if (/sbin/lsmod | grep -- ^"$driver") >/dev/null 2>&1;
  265.    then
  266.       /sbin/rmmod "$driver" || exit 1
  267.    fi
  268.  
  269.    exit 0
  270. }
  271.  
  272. # Start the virtual machine parallel port kernel service
  273. vmware_start_vmppuser() {
  274.    if ! grep -q ' parport_release[^'$'\t'']*$' /proc/ksyms; then
  275.      # parport support is not built in the kernel
  276.      /sbin/modprobe parport || exit 1
  277.    fi
  278.    if ! grep -q ' parport_pc_[^'$'\t'']*$' /proc/ksyms; then
  279.      # parport_pc support is not built in the kernel
  280.      /sbin/modprobe parport_pc || exit 1
  281.    fi
  282.    /sbin/insmod -s -f "$ppuser" || exit 1
  283.  
  284.    exit 0
  285. }
  286.  
  287. # Stop the virtual machine parallel port kernel service
  288. vmware_stop_vmppuser() {
  289.    if (/sbin/lsmod | grep -- ^"$ppuser") >/dev/null 2>&1;
  290.    then
  291.       /sbin/rmmod "$ppuser" || exit 1
  292.    fi
  293.    # Try to unload the modules. Failure is allowed because some other process
  294.    # could be using them.
  295.    /sbin/modprobe -r parport_pc >/dev/null 2>&1
  296.    /sbin/modprobe -r parport >/dev/null 2>&1
  297.  
  298.    # Return the right exitcode even if the previous command failed
  299.    exit 0
  300. }
  301.  
  302. # Start the virtual ethernet kernel service
  303. vmware_start_vmnet() {
  304.    /sbin/insmod -s -f "$vnet" || exit 1
  305.  
  306.    exit 0
  307. }
  308.  
  309. # Stop the virtual ethernet kernel service
  310. vmware_stop_vmnet() {
  311.    if (/sbin/lsmod | grep -- ^"$vnet") >/dev/null 2>&1;
  312.    then
  313.       /sbin/rmmod "$vnet" || exit 1
  314.    fi
  315.  
  316.    exit 0
  317. }
  318.  
  319. # Start the network bridge user service
  320. vmware_start_bridge() {
  321.    # Run the daemon in its own directory (to avoid busy devices)
  322.    cd "$vmware_bin_dir" && "$vmware_bin_dir"/"$bridge" -d /dev/"$vmnet0" "$vmware_bridgeif" || exit 1
  323.  
  324.    exit 0
  325. }
  326.  
  327. # Stop the network bridge user service
  328. vmware_stop_bridge() {
  329.    if `which start-stop-daemon >/dev/null`; then
  330.       start-stop-daemon --stop --user 0 --oknodo --exec "$vmware_bin_dir"/"$bridge" || exit 1
  331.    elif `type -type killproc >/dev/null`; then
  332.       # Suppress unwanted output
  333.       killproc "$vmware_bin_dir"/"$bridge" >/dev/null 2>&1 || exit 1
  334.    else
  335.       echo Unable to stop "$vmware_bin_dir"/"$bridge"
  336.       exit 1
  337.    fi
  338.  
  339.    exit 0
  340. }
  341.  
  342. # Start the host-only network user service
  343. vmware_start_hostonly() {
  344.    #
  345.    # Do a cursory check to see if the host-only network
  346.    # configuration is still ok.  We do this so that mobile
  347.    # hosts don't get setup at install time and then moved to
  348.    # a new locale where the host-only network config is no
  349.    # longer valid.
  350.    #
  351.    # NB: This really needs to be done at power-on time when
  352.    #     VM is configured to use host-only networking so that
  353.    #     we aren't fooled by dynamic changes in the network.
  354.    #
  355.    # XXX ping takes 10 seconds to timeout if noone answers;
  356.    #      that slows boot too much so we do this bit in the
  357.    #      background.
  358.    #
  359.    if lookForHostOnlyNetwork "$vmnetHostOnlyAddress"; then
  360.       echo "Host-only networking disabled because $vmnetHostOnlyAddress"
  361.       echo "appears to be a real, physical, existing address."
  362.       echo "Check your host-only network configuration."
  363.       exit 1
  364.    else
  365.       # Configure the virtual interface and define the private IP network
  366.       # 2.0.x does not install a route when the interface is
  367.       # marked up, but 2.2.x does.  Since we want to see any
  368.       # errors from route we don't just discard messages from
  369.       # route, but instead check if the route got installed
  370.       # before manually adding one.
  371.       netnum=`ipv4Network "$vmnetHostOnlyAddress" "$vmnetHostOnlyNetmask"`
  372.       if ifconfig "$vmnet1" inet "$vmnetHostOnlyAddress" \
  373.                             netmask "$vmnetHostOnlyNetmask" up \
  374.          && noRoutePresent "$netnum" "$vmnet1"; then
  375.          route add -net "$netnum".0 netmask "$vmnetHostOnlyNetmask" "$vmnet1"
  376.       fi
  377.  
  378.       # Set up a dhcp server on the private IP network
  379.       #
  380.       # NB: The dhcp logs its output, we can safely trash it
  381.       #
  382.       # Run the daemon in its own directory (to avoid busy devices)
  383.       cd "$vmware_bin_dir" && "$vmware_bin_dir"/"$dhcpd" \
  384.             -cf "$vmware_etc_dir"/"$vmnet1".conf \
  385.             -lf "$vmware_etc_dir"/"$vmnet1".leases \
  386.             -pf /var/run/"$vmnet1".pid \
  387.             "$vmnet1" >/dev/null 2>&1
  388.    fi
  389.  
  390.    exit 0
  391. }
  392.  
  393. # Stop the host-only network user service
  394. vmware_stop_hostonly() {
  395.    # Stop the dhcp server
  396.    if `which start-stop-daemon >/dev/null`; then
  397.       start-stop-daemon --stop --user 0 --oknodo --exec "$vmware_bin_dir"/"$dhcpd" || exit 1
  398.    elif `type -type killproc >/dev/null`; then
  399.       # Suppress unwanted output
  400.       killproc "$vmware_bin_dir"/"$dhcpd" >/dev/null 2>&1 || exit 1
  401.    else
  402.       echo Unable to stop "$vmware_bin_dir"/"$dhcpd"
  403.       exit 1
  404.    fi
  405.  
  406.    # Terminate the private network
  407.    netnum=`ipv4Network "$vmnetHostOnlyAddress" "$vmnetHostOnlyNetmask"` || exit 1
  408.    noRoutePresent "$netnum" "$vmnet1" || \
  409.       route del -net "$netnum".0 netmask "$vmnetHostOnlyNetmask" || exit 1
  410.    # To test if the interface exists, we can not just look at the exitcode
  411.    # because old versions of ifconfig don't exit with 1 when invoked with a
  412.    # non-existing interface
  413.    present=`ifconfig "$vmnet1" 2>/dev/null`
  414.    if [ "$present" != "" ]; then
  415.       ifconfig "$vmnet1" down || exit 1
  416.    fi
  417.  
  418.    exit 0
  419. }
  420.  
  421. # See how we were called.
  422. case "$1" in
  423.   start)
  424.         if [ -e "$vmware_etc_dir"/not_configured ]; then
  425.        echo 'VMware is installed, but it has not been (correctly) configured'
  426.            echo 'for the running kernel. To (re-)configure it, invoke the'
  427.            echo 'following command: '"$vmware_bin_dir"'/vmware-config.pl.'
  428.            echo
  429.  
  430.            exit 1
  431.         fi
  432.  
  433.     # VMware is configured. Fetch useful information from the database
  434.         variables_init
  435.  
  436.     echo "Starting VMware services:"
  437.         exitcode='0'
  438.  
  439.     vmware_exec 'Virtual machine monitor' vmware_start_vmmon
  440.         exitcode=`expr "$exitcode" + "$?"`
  441.  
  442.         # The module is not installed on kernels 2.0.x
  443.         if [ -r /lib/modules/preferred/misc/"$ppuser".o -o -r /lib/modules/`uname -r`/misc/"$ppuser".o ]; then
  444.        vmware_exec 'Virtual bidirectional parallel port' vmware_start_vmppuser
  445.            exitcode=`expr "$exitcode" + "$?"`
  446.         fi
  447.  
  448.     if [ "$vmware_networking" = "yes" ]; then
  449.         vmware_exec 'Virtual ethernet' vmware_start_vmnet
  450.         exitcode=`expr "$exitcode" + "$?"`
  451.  
  452.         vmware_exec 'Bridged networking' vmware_start_bridge
  453.         exitcode=`expr "$exitcode" + "$?"`
  454.  
  455.         if [ -n "$vmnetHostOnlyAddress" -a -n "$vmnetHostOnlyNetmask" ]; then
  456.                 vmware_bg_exec 'Host-only networking' vmware_start_hostonly
  457.                 exitcode=`expr "$exitcode" + "$?"`
  458.         fi
  459.     fi
  460.  
  461.         if [ "$exitcode" -gt 0 ]; then
  462.        clear_config_flag "$vmware_etc_dir"/not_configured
  463.            exit 1
  464.         fi
  465.  
  466.     [ -d /var/lock/subsys ] || mkdir -p /var/lock/subsys
  467.     touch /var/lock/subsys/"$subsys"
  468.     ;;
  469.  
  470.   stop)
  471.         variables_init
  472.  
  473.     # look for running vm's
  474.     nvms="`countVMs`"
  475.     if [ "$nvms" -gt 0 ]; then
  476.         if [ "$nvms" -gt 1 ]; then
  477.             echo "There are $nvms VMs still running.  Please shut them down first."
  478.         else
  479.             echo "There is one VM still running.  Please shut it down first."
  480.         fi
  481.         exit 1;
  482.     fi
  483.  
  484.     echo "Stopping VMware services:"
  485.         exitcode='0'
  486.  
  487.     vmware_exec 'Virtual machine monitor' vmware_stop_vmmon
  488.         exitcode=`expr "$exitcode" + "$?"`
  489.  
  490.         # The module is not installed on kernels 2.0.x
  491.         if [ -r /lib/modules/preferred/misc/"$ppuser".o -o -r /lib/modules/`uname -r`/misc/"$ppuser".o ]; then
  492.            vmware_exec 'Virtual bidirectional parallel port' vmware_stop_vmppuser
  493.            exitcode=`expr "$exitcode" + "$?"`
  494.         fi
  495.  
  496.     if [ "$vmware_networking" = "yes" ]; then
  497.         # NB: must kill off processes using vmnet before
  498.         #     unloading module
  499.  
  500.             vmware_exec 'Bridged networking' vmware_stop_bridge
  501.             exitcode=`expr "$exitcode" + "$?"`
  502.  
  503.             if [ -n "$vmnetHostOnlyAddress" -a -n "$vmnetHostOnlyNetmask" ]; then
  504.             vmware_exec 'Host-only networking' vmware_stop_hostonly
  505.             exitcode=`expr "$exitcode" + "$?"`
  506.             fi
  507.  
  508.         vmware_exec 'Virtual ethernet' vmware_stop_vmnet
  509.             exitcode=`expr "$exitcode" + "$?"`
  510.         fi
  511.  
  512.         if [ "$exitcode" -gt 0 ]; then
  513.            exit 1
  514.         fi
  515.  
  516.     rm -f /var/lock/subsys/"$subsys"
  517.     ;;
  518.  
  519.   status)
  520.     # look for running vm's
  521.     nvms="`countVMs`"
  522.     if [ "$nvms" -gt 0 ]; then
  523.         echo "There are $nvms virtual machines running"
  524.     else
  525.         echo "There are no virtual machines running"
  526.     fi
  527.  
  528.     if [ "$vmware_networking" = "yes" ]; then
  529.             status "$bridge"
  530.             status "$dhcpd"
  531.         fi
  532.  
  533.     echo -n "Module $driver "
  534.     /sbin/modprobe "$driver" >/dev/null 2>&1 && echo installed || echo "not installed"
  535.     echo -n "Module $ppuser "
  536.     /sbin/modprobe "$ppuser" >/dev/null 2>&1 && echo installed || echo "not installed"
  537.     if [ "$vmware_networking" = "yes" ]; then
  538.             echo -n "Module $vnet "
  539.             /sbin/modprobe "$vnet" >/dev/null 2>&1 && echo installed || echo "not installed"
  540.         fi
  541.     ;;
  542.  
  543.   restart)
  544.     "$0" stop && "$0" start
  545.     ;;
  546.  
  547.   *)
  548.     echo "Usage: `basename "$0"` {start|stop|status|restart}"
  549.     exit 1
  550. esac
  551.  
  552. exit 0
  553.