#! /usr/lib/util-vserver/sigexec /bin/bash # Copyright (C) 2004 Enrico Scholz # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ## Usage: vshelper : ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars} test -e "$UTIL_VSERVER_VARS" || { echo $"Can not find util-vserver installation (the file '$UTIL_VSERVER_VARS' would be expected); aborting..." >&2 exit 1 } . "$UTIL_VSERVER_VARS" . "$_LIB_FUNCTIONS" function showHelp { echo $"\ Usage: vshelper * Report bugs to <$PACKAGE_BUGREPORT>." exit 0 } function showVersion { echo $"\ vshelper $PACKAGE_VERSION -- userspace reboot helper This program is part of $PACKAGE_STRING Copyright (C) 2004 Enrico Scholz This program is free software; you may redistribute it under the terms of the GNU General Public License. This program has absolutely no warranty." exit 0 } function doInternalMethod { local method=$1 case "$method" in (restart) case "$ACTION" in (restart) logging $"Restarting vserver '$VSERVER'" local sync_dir vshelper.initStopSync sync_dir spawn $_VSERVER --defaulttty "$VSERVER" restart & disown %% vshelper.waitForStopSync "$sync_dir" ;; (halt|poweroff) logging $"Stopping vserver '$VSERVER'" local sync_dir vshelper.initStopSync sync_dir spawn $_VSERVER --defaulttty "$VSERVER" stop & disown %% vshelper.waitForStopSync "$sync_dir" spawn killContext "$XID" ;; (swsusp) ## TODO: any senseful action here? Perhaps shutdown scheduler for it? exit 0 ;; (restart2) ;; (shutdown) logging $"Cleaning up after vserver '$VSERVER'" spawn $_VSERVER --defaulttty "$VSERVER" stop ;; (*) warning $"Unknown action '$ACTION' for vserver '$VSERVER'" exit 1 esac ;; (async) spawn killContext "$XID" ;; (sync) local f=${METHOD_ARGS[0]} test -n "$f" || panic $"Insufficent arguments for method '$method' and vserver '$VSERVER'" test -p "$f" || panic $"File '$f' which is required for synchronisation of vserver '$VSERVER' is not a pipe" spawn killContext "$XID" echo "$ACTION" >"$f" ;; (*) local script findObject -x script "$__CONFDIR"/.defaults/apps/vshelper-methods/"$method" "$__PKGLIBDIR"/vshelper-methods/"$method" '' test -n '$script' || { warning $"No handler for internal method '$method' found" exit 1 } export VSERVER execute "$script" "${ARGS[@]}" esac } function doDefaultMethod { local handler vshelper.getHandler handler "$VSERVER" "$ACTION" || { warning $"No handler configured for action '$ACTION' on vserver '$VSERVER'" exit 1 } case "$handler" in (/*) execute "$handler" "${ARGS[@]}";; (:*) doInternalMethod "${handler##:}" "$@";; esac } #=========== test "$1" != '--version' || showVersion test "$1" != '--help' || showHelp if ! tty -s; then findObject -e _VS_LOGFILE "$__CONFDIR"/.defaults/apps/vshelper/logfile /dev/null findObject -e _VS_ERRFILE "$__CONFDIR"/.defaults/apps/vshelper/logfile /dev/null exec >$_VS_LOGFILE exec 2>>$_VS_ERRFILE fi logging "$(date): vshelper $*" test "$#" -ge 2 || panic $"vshelper called with missing arguments; try '--help' for more information" vshelper.isEnabled || exit 0 ! vshelper.isDebug || set -x set -eu if $_VSERVER_INFO - FEATURE vshelper0; then declare -r XID=$1 declare -r ACTION=$2 elif $_VSERVER_INFO - FEATURE vshelper; then declare -r ACTION=$1 declare -r XID=$2 else panic $"vshelper functionality not supported by kernel" fi findObject -x delegate "$__CONFDIR"/.defaults/apps/vshelper-delegate/"$ACTION" "$__PKGLIBDIR"/vshelper-delegate/"$ACTION" '' test -e "$delegate" && exec -a "$ACTION" "$delegate" "$@" this_xid=$($_VSERVER_INFO - XID) pxid= responsible_xid=$XID while true; do pxid=$($_VSERVER_INFO "$responsible_xid" PXID) || break test "$pxid" -ne "$this_xid" || break responsible_xid=$pxid done vserver_id=$($_VSERVER_INFO "$responsible_xid" ID) || test "$ACTION" = "shutdown" || panic $"No responsible vserver found for xid '$responsible_xid' ($XID); aborting..." test "$XID" = "$responsible_xid" || { logging "Giving 'vshelper' task for '$XID' to parent vserver '$vserver_id' ($responsible_xid)" execute $_VSERVER "$vserver_id" exec $_VSHELPER "$@" } #=========== ARGS=( "$@" ) declare -a state getFileArray state "$__VSHELPERSTATEDIR/$XID" && test ${#state[@]} -ge 2 || { logging "'vshelper' not configured for xid '$XID'" exit 0 } declare -r VSERVER=${state[0]} cfg_xid=$($_VSERVER_INFO "${state[0]}" CONTEXT false) || panic $"Configured vserver '$VSERVER' does not seem to run; aborting..." test "$cfg_xid" = "$XID" || panic $"Configured ($cfg_xid) and actual ($XID) xid for vserver '$VSERVER' are mismatching; aborting..." cur_xid=$($_VSERVER_INFO "$VSERVER" CONTEXT false) || panic $"Vserver '$VSERVER' with '$XID' does not seem to run; strange..." test "$cur_xid" = "$XID" || panic $"Expected ($XID) and actual ($cur_xid) xid for vserver '$VSERVER' are mismatching; strange..." method=${state[1]} if test "${#state[@]}" -gt 2; then unset state[0] state[1] declare -ra METHOD_ARGS=( "${state[@]}" ) else declare -ra METHOD_ARGS=() fi case "$method" in (default) doDefaultMethod "$@";; (sync|async) doInternalMethod "$method" "$@";; (*) panic $"Unknown method '$method' used by vserver '$VSERVER'";; esac