X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fscripts%2Fvserver.functions;h=77e15ba06b3aee566a0d3c71ff032486fe17ffa1;hb=dfa40e043f50b3ed0f89cdec01d0655c94c1e12e;hp=cfa69f2726e90d85fce4e2e34c5f502ab1eefcc3;hpb=8ae89fda82d242ba3cf6b4faf4295f63d171c094;p=util-vserver.git diff --git a/util-vserver/scripts/vserver.functions b/util-vserver/scripts/vserver.functions index cfa69f2..77e15ba 100644 --- a/util-vserver/scripts/vserver.functions +++ b/util-vserver/scripts/vserver.functions @@ -28,6 +28,7 @@ declare -a CHCONTEXT_OPTS=() declare -a CAPCHROOT_OPTS=() declare -a INTERFACES=() +declare -a INITCMD_RESCUE=( /bin/sleep 900 ) declare -a INITCMD_START=() declare -a INITCMD_START_SYNC=() declare -a INITCMD_STOP=() @@ -38,6 +39,7 @@ declare -a ENTER_SHELL=() declare -a OPTS_VCONTEXT_CREATE=() declare -a OPTS_VCONTEXT_MIGRATE=() +declare -a OPTS_VCONTEXT_ENTER=() declare -a OPTS_VATTRIBUTE=( --flag fakeinit ) declare -a OPTS_VSCHED=() @@ -45,6 +47,7 @@ declare -a STOPCMD_PREPARE=() declare -a VSERVER_EXTRA_CMDS=() +INIT_RESCUE= VSHELPER_SYNC_TIMEOUT=30 USE_VNAMESPACE= INTERFACE_CMDS_IDX=0 @@ -100,6 +103,34 @@ function _generateNiceCommand NICE_CMD=( $_NICE -$nice ) } + +function _generatePersonalityOptions +{ + local vdir="$1" + local f="$vdir"/personality + local type flags + + test -s "$f" || return 0 + + { + local delim tmp + + read type + while read tmp; do + case x$tmp in + (x\#*|x) ;; + (*) flags=$flags$delim$tmp + delim=, + ;; + esac + done + } <"$f" + + OPTS_VCONTEXT_ENTER=( "${OPTS_VCONTEXT_ENTER[@]}" + --personality-type "$type" + ${flags:+--personality-flags "$flags"} ) +} + function _generateCCapabilityOptions { local vdir=$1 @@ -109,7 +140,7 @@ function _generateCCapabilityOptions test -e "$f" || return 0 while read cap; do case x"$cap" in - (x|x\#) ;; + (x|x\#*) ;; (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --ccap "$cap" );; esac done <"$f" @@ -124,7 +155,7 @@ function _generateBCapabilityOptions test -e "$f" || return 0 while read cap; do case x"$cap" in - (x|x\#) ;; + (x|x\#*) ;; (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --bcap "$cap" );; esac done <"$f" @@ -145,7 +176,7 @@ function _generateCapabilityOptions while read cap; do case x"$cap" in - (x|x\#) ;; + (x|x\#*) ;; (!CAP_SYSCHROOT) CAP_OPTS=( "${CAP_OPTS[@]}" --cap "$cap" ) CAPCHROOT_OPTS=( "${CAPCHROOT_OPTS[@]}" --nochroot ) @@ -218,6 +249,13 @@ function _generateInitOptions getFileArray INITKILL_SEQ "$cfgdir"/killseq || : case x"$INITSTYLE" in + (xrescue) + INITCMD_START=( "${INITCMD_RESCUE[@]}" ) + INITCMD_STOP=( /sbin/killall5 ) + _IS_FAKEINIT=1 + _NEED_VSHELPER_SYNC= + ;; + (xsysv) test -n "$RUNLEVEL_START" || RUNLEVEL_START=3 test -n "$RUNLEVEL_STOP" || RUNLEVEL_STOP=6 @@ -256,16 +294,16 @@ function _generateInitOptions ;; (x) ;; - (*) echo "Unknown init-style '$INITSTYLE'; aborting" >&2; - exit 1;; + (*) panic "Unknown init-style '$INITSTYLE'; aborting";; esac - getFileArray INITCMD_START "$cfgdir"/cmd.start || : - getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || : - getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || : - getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || : - getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || : - + if test x"$INITSTYLE" != xrescue; then + getFileArray INITCMD_START "$cfgdir"/cmd.start || : + getFileArray INITCMD_STOP "$cfgdir"/cmd.stop || : + getFileArray INITCMD_START_SYNC "$cfgdir"/cmd.start-sync || : + getFileArray INITCMD_STOP_SYNC "$cfgdir"/cmd.stop-sync || : + getFileArray INITCMD_PREPARE "$cfgdir"/cmd.prepare || : + fi test -n "$OPTION_FORCE_SYNC" -o -e "$cfgdir"/sync || { INITCMD_START_SYNC=() @@ -289,7 +327,7 @@ function _generateFlagOptions test ! -e "$vdir"/flags || \ while read flag; do case x"$flag" in - (x|x\#) ;; + (x|x\#*) ;; (xnamespace) ;; (xfakeinit) _IS_FAKEINIT=1 @@ -338,7 +376,7 @@ function _generateChcontextOptions OPTS_VCONTEXT_CREATE=( $SILENT_OPT \ ${ctx:+--xid "$ctx"} ) ## put '--secure' at front so that it can be overridden - OPTS_VATTRIBUTE=( --secure "${OPTS_VATTRIBUTE[@]}" ) + OPTS_VATTRIBUTE=( --secure --flag default "${OPTS_VATTRIBUTE[@]}" ) } function _generateScheduleOptions @@ -416,6 +454,29 @@ function _generateMac eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ]) } +function _getVLANInfo +{ + case "$1" in + (vlan????) + panic "\ +creation of VLAN_PLUS_VID devices is not supported; please create them +before starting the vserver and use the 'nodev' flag then" + echo "$1 vlan ${1##vlan} VLAN_PLUS_VID" + ;; + (vlan*) + panic "\ +creation of VLAN_PLUS_VID_NO_PAD devices is not supported; please +create them before starting the vserver and use the 'nodev' flag then" + echo "$1 vlan ${1##vlan} VLAN_PLUS_VID_N0_PAD" + ;; + (*.????) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID";; + (*.*) echo "$1 ${1%%.*} ${1##*.} DEV_PLUS_VID_NO_PAD";; + (*) return 1 + esac + + return 0 +} + ## Usage: _processSingleInterface function _processSingleInterface { @@ -458,19 +519,16 @@ function _processSingleInterface ## LEGACY ALERT test ! -e "$iface"/only_ip || break - case "$dev" in - (*.*) - test -d /proc/net/vlan || { - echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2 - return 1 - } - test -f /proc/net/vlan || { - _addInterfaceCmd VCONFIG ${dev/./ } - _addInterfaceCmd IP_ADDR 127.0.0.1/8 broadcast 127.255.255.255 dev "$dev" - _addInterfaceCmd IP_LINK "$dev" $up - } - ;; - esac + local vlan_info + if vlan_info=$(_getVLANInfo "$dev"); then + test -d /proc/net/vlan || { + echo -e $"VLAN device-name used, but vlan subsystem not enabled.\nTry to execute 'modprobe 8021q' before starting the vservers" >&2 + return 1 + } + test -f /proc/net/vlan -o -e "$iface"/novlandev || { + _addInterfaceCmd VCONFIG $vlan_info + } + fi if ! test -e "$iface"/indirect; then _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev" @@ -530,8 +588,9 @@ function enableInterfaces shift 2 $_MODPROBE ${name:+-o "$name"} "$mod" "$@" ;; - NAMEIF) $_NAMEIF "$@";; - VCONFIG) $_VCONFIG add "$@";; + NAMEIF) $_NAMEIF "$@";; + VCONFIG) $_VCONFIG set_name_type "$4" >/dev/null + $_VCONFIG add "$2" "$3" >/dev/null;; IP_ADDR) $_IP addr add "$@";; IP_ADDR_FLUSH) $_IP addr flush "$@";; IP_LINK) $_IP link set "$@";; @@ -566,7 +625,7 @@ function disableInterfaces IPTABLES) ;; ## TODO MODPROBE) $_RMMOD "${2:-$1}";; NAMEIF) ;; - VCONFIG) $_VCONFIG rem "$@";; + VCONFIG) $_VCONFIG rem "$2.$3" >/dev/null;; IP_ADDR) $_IP addr del "$@";; IP_ADDR_FLUSH) ;; IP_LINK) ;; ## Ignore the link-down command for now @@ -585,11 +644,11 @@ function prepareInit case "$INITSTYLE" in sysv) { find var/run ! -type d -print0; \ - find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_RM + find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm ;; plain) - $_CHROOT_RM .autofsck forcefsck 2>/dev/null || : - : | $_CHROOT_CAT fastboot 2>/dev/null || : + $_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || : + : | $_CHROOT_SH truncate fastboot 2>/dev/null || : ;; minit) ;; @@ -614,12 +673,13 @@ function prepareStop function generateOptions { - _generateInterfaceOptions "$1" + _generateInterfaceOptions "$1" test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1" - _generateNiceCommand "$1" - _generateInitOptions "$1" - _generateChcontextOptions "$1" - _generateScheduleOptions "$1" + _generateNiceCommand "$1" + _generateInitOptions "$1" + _generateChcontextOptions "$1" + _generateScheduleOptions "$1" + _generatePersonalityOptions "$1" if test -n "$_IS_FAKEINIT"; then CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit ) @@ -630,11 +690,17 @@ function generateOptions function _mountVserverInternal { local fstab="$1" + local xflag= + test -e "$fstab" || return 0 shift pushd "$vdir" >/dev/null - "$@" $_SECURE_MOUNT -a --chroot --fstab "$fstab" --rootfs no + # check whether / is mounted readonly or whether there is special + # magic regarding the mtab file; when etc/mtab can not be touched, + # add the '-n' flag to mount + test -w etc -o -w etc/mtab || xflag=-n + "$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no popd >/dev/null } @@ -643,10 +709,15 @@ function mountRootFS local cfgdir=$1 local vdir=$1/vdir local fstab="$cfgdir"/fstab + local xflag= test -e "$fstab" || return 0 pushd "$vdir" >/dev/null - $_SECURE_MOUNT -a --chroot --fstab "$fstab" --rootfs only -n + # check whether / is mounted readonly or whether there is special + # magic regarding the mtab file; when etc/mtab can not be touched, + # add the '-n' flag to mount + test -w etc -o -w etc/mtab || xflag=-n + $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs only -n popd >/dev/null } @@ -664,7 +735,7 @@ function mountVserver findObject -r mtab_src "$cfgdir"/apps/init/mtab "$__CONFDIR"/.defaults/init/mtab "$__PKGLIBDEFAULTDIR"/mtab /dev/null pushd "$vdir" >/dev/null - $_CHROOT_CAT /etc/mtab <"$mtab_src" + $_CHROOT_SH truncate /etc/mtab <"$mtab_src" popd >/dev/null test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir" @@ -720,22 +791,96 @@ function umountVserver test -n "$is_ok" } -## Usage: waitForSync +## Usage: waitForSync function initSync { local _is_meth=sync - test -n "$_NEED_VSHELPER_SYNC" || _is_meth=async + test -n "$_NEED_VSHELPER_SYNC" && \ + ! $_VSERVER_INFO - FEATURE vwait || _is_meth=async + + vshelper.initSync "$1" "$3" "$_is_meth" +} + +## Usage: initWait +function initWait +{ + if $_VSERVER_INFO - FEATURE vwait; then + local _is_tmpdir + _is_tmpdir=$($_MKTEMPDIR /tmp/vwaitstat.XXXXXX) + + ( + $_VWAIT --timeout "$VSHELPER_SYNC_TIMEOUT" \ + --status-fd 3 "$2" \ + >>$_is_tmpdir/out 2>$_is_tmpdir/err 3>$_is_tmpdir/fifo + rc=$? + + if test "$rc" -ne 0 -a "$rc" -ne 1; then + $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4 + killContext "$S_CONTEXT" 9 + fi + + exit $rc + ) 4>$_is_tmpdir/procs & + + echo "$!" >$_is_tmpdir/pid + eval "$3"=$_is_tmpdir + fi +function _waitForVWait +{ + wait "$3" || : - vshelper.initSync "$1" "$2" "$_is_meth" + declare -a status + declare -r procs=$(cat $4) + + getFileArray status "$2" + set -- ${status[0]} + + case "$1" in + (ERROR) warning $"\ +'vwait' exited with error '$2' which indicates that vserver could not +be stopped properly" + ;; + (FINISHED) ;; + (KILLED) warning $"\ +A timeout occured while waiting for the vserver to finish and it was +killed by sending a SIGKILL signal. Please investigate the reasons +and/or increase the timeout in apps/vshelper/sync-timeout." + ;; + + (TIMEOUT) warning $"\ +A timeout occured while waiting for the vserver to finish and it will +be killed by sending a SIGKILL signal. The following process list +might be useful for finding out the reason of this behavior: + +---------------------------------------------------------------------- +${procs:+$procs +}----------------------------------------------------------------------" + ;; + + (\?\?\?|*) warning $"\ +internal error: 'vwait' exited with an unexpected status '$1'; I will +try to continue but be prepared for unexpected events." + ;; + esac + + return 0 } -## Usage: waitForSync [] +## Usage: waitForSync [] [] function waitForSync { local cfgdir=$1 local fifo=$2 - - if test -n "$_NEED_VSHELPER_SYNC"; then + local vwait_statdir=$3 + local vwait_pid=$4 + + if test -d "$vwait_statdir"; then + _waitForVWait "$cfgdir" "$vwait_statdir/fifo" "$( <$vwait_statdir/pid )" "$vwait_statdir/procs" + elif test -n "$_NEED_VSHELPER_SYNC"; then $_VSHELPER_SYNC "$fifo" "$VSHELPER_SYNC_TIMEOUT" || \ warning $"\ A timeout or other error occured while waiting for the synchronization @@ -771,7 +916,9 @@ function execScriptlets local already_handled= for i in "$base/$flavor" "$base/$flavor.d"/*; do - test -f "$i" -a -r "$i" || continue + isRegularFile "$i" || continue + test -r "$i" || continue + already_handled=1 local start= test -x "$i" || start=_sourceWrap @@ -816,7 +963,7 @@ WARNING: The 'only_ip' flag for interface '$iface' is deprecated; use 'nodev' instead of" fi done - + find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';' vshelper.doSanityCheck