Don't set _IS_FAKEINIT on rescue, let the caller decide with --rescue-init.
[util-vserver.git] / scripts / vserver.functions
index c6fa4b5..592d3f1 100644 (file)
@@ -42,6 +42,7 @@ declare -a OPTS_VCONTEXT_MIGRATE=()
 declare -a OPTS_VCONTEXT_ENTER=()
 declare -a OPTS_VATTRIBUTE=( --flag fakeinit )
 declare -a OPTS_VSCHED=()
+declare -a OPTS_ENV=()
 
 declare -a STOPCMD_PREPARE=()
 
@@ -246,18 +247,22 @@ function _generateInitOptions
     CHCONTEXT_INIT_OPTS=()
 
 
-    getFileValue INITSTYLE      "$cfgdir"/style
+    test -n "$INITSTYLE" || \
+      getFileValue INITSTYLE    "$cfgdir"/style
     getFileValue RUNLEVEL_START "$cfgdir"/runlevel
     getFileValue RUNLEVEL_START "$cfgdir"/runlevel.start
     getFileValue RUNLEVEL_STOP  "$cfgdir"/runlevel.stop
     getFileArray INITKILL_SEQ  "$cfgdir"/killseq || :
 
+    findFile _gio_env          "$cfgdir"/environment \
+       "$__CONFDIR"/.defaults/apps/init/environment \
+       "$__PKGLIBDEFAULTDIR"/environment
+    getFileArray OPTS_ENV      "$_gio_env" || :
+
     case x"$INITSTYLE" in
        (xrescue)
            INITCMD_START=( "${INITCMD_RESCUE[@]}" )
            INITCMD_STOP=( /sbin/killall5 )
-           _IS_FAKEINIT=1
-           _NEED_VSHELPER_SYNC=
            ;;
            
        (xsysv)
@@ -293,7 +298,27 @@ function _generateInitOptions
            ;;
 
        (xgentoo)
-           panic "init-style '$INITSTYLE' is no longer supported; please use plain instead; aborting";;
+           test -n "$RUNLEVEL_START" || RUNLEVEL_START="default"
+
+           INITCMD_START=( /lib/rcscripts/sh/init-vserver.sh "$RUNLEVEL_START" )
+           INITCMD_STOP=( /sbin/rc shutdown )
+           INITCMD_PREPARE=( $_FAKE_RUNLEVEL 3 /var/run/utmp )
+
+           pushd "$vdir"/vdir &>/dev/null
+           basever=$($_CHROOT_SH cat /etc/gentoo-release | $_AWK '{print $5}')
+           popd &>/dev/null
+
+           basemaj=${basever/.*}
+           basemin=${basever#*.}
+           basemin=${basemin/.*}
+
+           test "$basemaj" -lt 1 -o "$basemin" -lt 13 && \
+           panic "\
+Using init-style 'gentoo' requires >=baselayout-1.13 inside the vserver!
+
+Your vserver ($(basename "$vdir")) seems to have baselayout-$basever,
+please use 'plain' init-style instead!"
+           ;;
 
        (x) ;;
        (*) panic "Unknown init-style '$INITSTYLE'; aborting";;
@@ -384,6 +409,11 @@ function _generateChcontextOptions
 function _generateScheduleOptions
 {
     local vdir=$1
+    if test -d "$vdir"/sched; then
+      OPTS_VSCHED=( --dir "$vdir"/sched --missingok )
+      return 0
+    fi
+
     local f="$vdir"/schedule
     test -e "$f" || return 0
 
@@ -527,7 +557,11 @@ function _processSingleInterface
                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 || {
+           test -e "$iface/vlandev" \
+                -o \( -e "$iface/../vlandev" -a ! -e "$iface/novlandev" \) \
+                -o \( -e "$__CONFDIR/.defaults/interfaces/vlandev" \
+                      -a ! -e "$iface/novlandev" \
+                      -a ! -e "$iface/../novlandev" \) && {
                _addInterfaceCmd VCONFIG $vlan_info
            }
        fi
@@ -705,7 +739,7 @@ function addtoCPUSET
        test -d /dev/cpuset/"$cpuset" || mkdir /dev/cpuset/"$cpuset" || configured=1
        for i in cpus mems cpu_exclusive mem_exclusive virtualized; do
            if test -e "$f"/"$i"; then
-               cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" 2>/dev/null || {
+               cat "$f"/"$i" >/dev/cpuset/"$cpuset"/"$i" || {
                    configured=1
                    break
                }
@@ -790,13 +824,13 @@ function mountVserver
 
     test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$cfgdir"
 
-    test -z "$NAMESPACE_CLEANUP" || isAvoidNamespace "$cfgdir" || \
-       $_VNAMESPACE --cleanup
-
     _mountVserverInternal "$cfgdir"/fstab
     _mountVserverInternal "$cfgdir"/fstab.local
     _mountVserverInternal "$cfgdir"/fstab.remote $_CHBIND "${CHBIND_OPTS[@]}"
 
+    isNamespaceCleanup "$cfgdir" && \
+        _namespaceCleanup "$cfgdir"
+
     isAvoidNamespace "$cfgdir" || \
        $_SECURE_MOUNT --rbind -n "$vdir" "/"
 }
@@ -1148,3 +1182,42 @@ function saveDiskLimits
        _saveSingleDiskLimit "$vdir" "$dlimit"
     done
 }
+
+function _namespaceCleanup
+{
+    local vdir="$1"
+    local root=$($_VSERVER_INFO "$1" VDIR 1)
+    local -a list
+    local -a skip
+    local tmp
+
+    getFileArray skip "$vdir"/namespace-cleanup-skip \
+       "$__CONFDIR"/.defaults/namespace-cleanup-skip || :
+
+    # these are things that have to be accessible post-cleanup
+    for tmp in "$root" "$__SBINDIR" "$__PKGLIBDIR" "$vdir" \
+       "$__PKGSTATEDIR" "${skip[@]}"; do
+       while test -n "$tmp"; do
+           list=( "${list[@]}" "$tmp" )
+           tmp="${tmp%/*}"
+       done
+    done
+
+    local -a list_umount
+    while read dev path opts; do
+       test -n "$path" || continue
+       for i in "$root" /dev /proc; do
+           test "${path#$i}" != "$path" && continue 2
+       done
+       for i in "${list[@]}" /; do
+           test "$path" = "$i" && continue 2
+       done
+       # unmount them in reverse order so mounts further down the tree get unmounted first
+       list_umount=( "$path" "${list_umount[@]}" )
+    done < /proc/mounts
+    # separate loop to avoid races while reading /proc/mounts
+    for i in "${list_umount[@]}"; do
+       $_UMOUNT -l -n "$i"
+    done
+}
+