X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=scripts%2Fvserver.functions;h=47eca33336bca44b3036b8a96674d5679d98b90b;hb=f5dbe45b60edf550f856188fa9e837a34d43a2e6;hp=7a9b6a8cf43305935ac53953f6fb5ec6ef6bf531;hpb=fcebe8bc0f98feaa9c859b659de37febe4eb8ebf;p=util-vserver.git diff --git a/scripts/vserver.functions b/scripts/vserver.functions index 7a9b6a8..47eca33 100644 --- a/scripts/vserver.functions +++ b/scripts/vserver.functions @@ -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=() @@ -72,6 +73,22 @@ else SILENT_OPT='--silent' fi +function _readFileToArray +{ + local _rfta_f="$1" + local _rfta_a="$2" + local _rfta_p="$3" + local _rfta_v + + test -e "$_rfta_f" || return 0 + while read _rfta_v; do + case x"$_rfta_v" in + (x|x\#*) ;; + (*) eval "$_rfta_a=( \"\${$_rfta_a[@]}\" $_rfta_p \"$_rfta_v\" )";; + esac + done <"$_rfta_f" +} + function _generateChbindOptions { local vdir="$1" @@ -92,18 +109,22 @@ function _generateChbindOptions CHBIND_OPTS=( "${CHBIND_OPTS[@]}" --ip "$i" ) done + _readFileToArray "$vdir"/nflags CHBIND_OPTS --flag + _readFileToArray "$vdir"/ncapabilities CHBIND_OPTS --ncap + _HAVE_CHBIND_OPTIONS=1 } function _generateNiceCommand { local vdir=$1 - local nice + local nice=0 + local current_nice=`$_NICE` - test -r "$vdir/nice" || return 0; - read nice <"$vdir"/nice + test -r "$vdir/nice" && read nice <"$vdir"/nice - NICE_CMD=( $_NICE -$nice ) + let nice=$nice-$current_nice || : + NICE_CMD=( $_NICE -n $nice ) } @@ -137,31 +158,15 @@ function _generatePersonalityOptions function _generateCCapabilityOptions { local vdir=$1 - local cap - local f="$vdir"/ccapabilities - - test -e "$f" || return 0 - while read cap; do - case x"$cap" in - (x|x\#*) ;; - (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --ccap "$cap" );; - esac - done <"$f" + + _readFileToArray "$vdir"/ccapabilities OPTS_VATTRIBUTE --ccap } function _generateBCapabilityOptions { local vdir=$1 - local cap - local f="$vdir"/bcapabilities - - test -e "$f" || return 0 - while read cap; do - case x"$cap" in - (x|x\#*) ;; - (*) OPTS_VATTRIBUTE=( "${OPTS_VATTRIBUTE[@]}" --bcap "$cap" );; - esac - done <"$f" + + _readFileToArray "$vdir"/bcapabilities OPTS_VATTRIBUTE --bcap } function _generateCapabilityOptions @@ -245,18 +250,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) @@ -292,7 +301,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";; @@ -383,6 +412,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 @@ -526,7 +560,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 @@ -688,6 +726,54 @@ function generateOptions fi } +function addtoCPUSET +{ + local vdir=$1 + local cpuset + local f="$vdir"/cpuset + local i + local configured=0 + + test -d "$f" || return 0 + test -e "$f"/name || return 0 + + read cpuset < "$f"/name + test -e "$f"/nocreate || { + 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" || { + configured=1 + break + } + fi + done + } + + echo $$ >/dev/cpuset/"$cpuset"/tasks || configured=1 + if [ "$configured" -ne 0 ]; then + warning $"\ +WARNING: Failed to create or CPUSET \"$cpuset\" does not exist! Not using it!" >&2 + rmdir /dev/cpuset/"$cpuset" 2>/dev/null || : + return 0 + fi +} + +function removeCPUSET +{ + local vdir=$1 + local cpuset + local f="$vdir"/cpuset + + test -d "$f" || return 0 + test -e "$f"/name || return 0 + + read cpuset < "$f"/name + test -e "$f"/nocreate || { + rmdir /dev/cpuset/"$cpuset" 2>/dev/null || : + } +} + function _mountVserverInternal { local fstab="$1" @@ -741,13 +827,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" "/" } @@ -1099,3 +1185,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 +} +