declare -a OPTS_VCONTEXT_CREATE=()
declare -a OPTS_VCONTEXT_MIGRATE=()
declare -a OPTS_VCONTEXT_ENTER=()
+OPT_VCONTEXT_CHROOT=--chroot
declare -a OPTS_VATTRIBUTE=( --flag fakeinit )
declare -a OPTS_VSCHED=()
declare -a OPTS_ENV=()
declare -a OPTS_VTAG_CREATE=()
declare -a OPTS_VTAG_ENTER=()
declare -a OPTS_VMEMCTRL=()
-declare -a OPTS_VSPACE=()
+declare -a OPTS_VSPACE=( --default )
+declare -a OPTS_VSPACE_SHARED=()
+declare -a VSPACE_SHARED_CMD=()
declare -a STOPCMD_PREPARE=()
SILENT_OPT=
+CGROUP_MNT=/dev/cgroup
+CGROUP_SUBSYS=all
+declare -a CGROUP_INHERIT=( cpuset.cpus cpuset.mems )
+
: ${VSERVER_NAME:=$(basename "$VSERVER_DIR")}
if test -e "$VSERVER_DIR"/noisy -o -n "$OPTION_VERBOSE"; then
local ionice_class=2
local ionice_priority=0
+ test -n "$_IONICE" || return 0
+
test -r "$vdir/ionice/class" && read ionice_class <"$vdir"/ionice/class
test -r "$vdir/ionice/priority" && read ionice_priority <"$vdir"/ionice/priority
panic "init-vserver.sh not found; aborting"
fi
- INITCMD_START=( env TERM=$TERM $RC_WRAP "$RUNLEVEL_START" )
+ OPTS_ENV=( "${OPTS_ENV[@]}" TERM=$TERM )
+ INITCMD_START=( $RC_WRAP "$RUNLEVEL_START" )
INITCMD_STOP=( env -i PATH=$RC_PATH TERM=$TERM RUNLEVEL=0 /sbin/rc shutdown )
INITCMD_PREPARE=( $_FAKE_RUNLEVEL 3 /var/run/utmp )
;;
+ (xarch)
+ test -n "$RUNLEVEL_START" || RUNLEVEL_START=3
+ INITCMD_START=( /etc/rc.multi )
+ INITCMD_STOP=( /etc/rc.shutdown )
+ INITCMD_PREPARE=( $_FAKE_RUNLEVEL "$RUNLEVEL_START" /var/run/utmp )
+ ;;
+
(x) ;;
(*) panic "Unknown init-style '$INITSTYLE'; aborting";;
esac
function _generateFlagOptions
{
local vdir=$1
+ local file
CHCONTEXT_FLAG_OPTS=()
- test ! -e "$vdir"/flags || \
+ findFile file "$vdir"/cflags "$vdir"/flags ""
+ test -z "$file" || \
while read flag; do
case x"$flag" in
(x|x\#*) ;;
--flag "$flag" )
;;
esac
- done <"$vdir"/flags
+ done <"$file"
isAvoidNamespace "$vdir" || {
USE_VNAMESPACE=1
CHCONTEXT_FLAG_OPTS=( "${CHCONTEXT_FLAG_OPTS[@]}" --flag namespace )
+ ! $_VSERVER_INFO - FEATURE PIVOT_ROOT || \
+ OPT_VCONTEXT_CHROOT=--pivot-root
}
}
{
local vdir="$1"
local d="$vdir"/spaces
+ local shared
- ( test ! -e "$d"/pid ) || \
- OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --pid )
+ if test -e "$d"/pid; then
+ getFileValue shared "$d"/pid
+ if test -z "$shared"; then
+ OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --pid )
+ else
+ OPTS_VSPACE_SHARED=( "${OPTS_VSPACE_SHARED[@]}" --pid )
+ VSPACE_SHARED_CMD=( "${VSPACE_SHARED_CMD[@]}" $_VSPACE --enter "$shared" --pid -- )
+ fi
+ fi
- test ! -e "$d"/net || {
- OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --net )
+ if test -e "$d"/net; then
+ getFileValue shared "$d"/net
# network context and namespace don't make much sense
_HAVE_CHBIND_OPTIONS=1
CHBIND_CMD=()
- }
+ if test -z "$shared"; then
+ OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --net )
+ else
+ OPTS_VSPACE_SHARED=( "${OPTS_VSPACE_SHARED[@]}" --net )
+ VSPACE_SHARED_CMD=( "${VSPACE_SHARED_CMD[@]}" $_VSPACE --enter "$shared" --net -- )
+ fi
+ fi
local mask
getFileValue mask "$d"/mask || \
pushd "$1/vdir" >/dev/null
case "$INITSTYLE" in
sysv)
- { find var/run ! -type d -print0; \
- find var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
+ { $_FIND var/run ! -type d -print0; \
+ $_FIND var/lock ! -type d -print0; } | xargs -0r $_CHROOT_SH rm
;;
plain)
$_CHROOT_SH rm .autofsck forcefsck 2>/dev/null || :
_generateTagOptions "$1"
_generateMemctrlOptions "$1"
_generateSpaceOptions "$1"
+ _generateCgroupOptions
if test -n "$_IS_FAKEINIT"; then
CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
# 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
+ if test -h etc/mtab; then
+ local l=$($_READLINK etc/mtab)
+ test "${l##/proc/}" = "$l" || xflag=-n
+ fi
"$@" $_SECURE_MOUNT -a $xflag --chroot --fstab "$fstab" --rootfs no
popd >/dev/null
}
local ns_opt=$2
local vdir=$1/vdir
local mtab_src
+ local extra_opt=
+ local real_vdir
test -e "$cfgdir"/fstab -o \
-e "$cfgdir"/fstab.local -o \
isNamespaceCleanup "$cfgdir" && \
_namespaceCleanup "$cfgdir"
+ real_vdir=$(getPhysicalDir "$vdir")
isAvoidNamespace "$cfgdir" || \
- $_SECURE_MOUNT --rbind -n "$vdir" "/"
+ $_SECURE_MOUNT --rbind -n -o dev "$vdir" "$real_vdir"
+ ! $_VSERVER_INFO - FEATURE PIVOT_ROOT || \
+ $_SECURE_MOUNT -n -o shared,rec "$real_vdir" "$real_vdir"
}
function _umountVserverInternal
rc=$?
if test "$rc" -ne 0 -a "$rc" -ne 1; then
- $_VPS axf | $_EGREP -e "^[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
+ $_VPS axf | $_EGREP -e "^[ \t]*[^ \t]+[ \t]+$S_CONTEXT[ \t]+" >&4
killContext "$S_CONTEXT" 9
fi
ln -s ../.defaults/cachebase/$VSERVER_NAME $cfgdir/cache
"
- find "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
+ $_FIND "$cfgdir" -type f -exec "$_CHECK_UNIXFILE" '{}' ';'
vshelper.doSanityCheck
while read -r dev path opts; do
test -n "$path" || continue
for i in "$root" /dev /proc; do
- test "${path#$i}" != "$path" && continue 2
+ path_dir="${path}/"
+ test "${path_dir#${i}/}" != "${path_dir}" && continue 2
done
for i in "${list[@]}" /; do
test "$path" = "$i" && continue 2
$_VDEVMAP --xid "$xid" "$op" "${vdevmap_opts[@]}" || return $?
done
}
+
+function hasCgroup
+{
+ $_GREP -q "cgroup" /proc/filesystems
+}
+
+function _generateCgroupOptions
+{
+ local file
+
+ hasCgroup || return 0
+
+ findFile file "$__CONFDIR/.defaults/cgroup/mnt" ""
+ if test -n "$file"; then
+ read CGROUP_MNT < "$file"
+ fi
+ findFile file "$__CONFDIR/.defaults/cgroup/subsys" ""
+ if test -n "$file"; then
+ read CGROUP_SUBSYS < "$file"
+ elif $_GREP -q '^ns[[:space:]]' /proc/cgroups; then
+ # Hack for the ns subsystem, with which we are incompatible
+ CGROUP_SUBSYS=$($_SED '/^#/d;/^ns[[:space:]]/d;s/[[:space:]].*//' /proc/cgroups | \
+ (s=""; while read x; do test -n "$s" && s="$s,"; s="$s$x"; done; echo "$s"))
+ fi
+ findFile file "$__CONFDIR/.defaults/cgroup/inherit" ""
+ if test -n "$file"; then
+ _readFileToArray CGROUP_INHERIT "$file" ""
+ fi
+
+ return 0
+}
+
+function useCgroup
+{
+ hasCgroup || return 1
+ test -d "$CGROUP_MNT" || return 1
+ test -d "$1/cgroup" -o \
+ \( -d "$__CONFDIR/.defaults/cgroup" -a \
+ ! -e "$1/nocgroup" \)
+}
+
+function _handleCgroup
+{
+ local action="$1"
+ local vdir="$2"
+ local dir
+ local name
+ local i
+ local parent
+
+ useCgroup "$vdir" || return 0
+
+ findDir dir "$vdir/cgroup" "$__CONFDIR/.defaults/cgroup" ""
+ test -d "$dir" || return 0
+
+ if test -r "$dir"/name; then
+ read name < "$dir"/name
+ else
+ name="$VSERVER_NAME"
+ fi
+
+ if test "$action" = "attach"; then
+ if mkdir "$CGROUP_MNT/$name" 2>/dev/null; then
+ parent="$CGROUP_MNT/$name"
+ parent="${parent%/*}"
+ for i in "${CGROUP_INHERIT[@]}"; do
+ test -f "$parent/$i" || continue
+ cat "$parent/$i" > "$CGROUP_MNT/$name/$i"
+ done
+
+ shopt -s nullglob
+ for i in "$dir"/*; do
+ f="${i##*/}"
+ test "$f" != mnt -a "$f" != subsys -a \
+ "$f" != inherit -a "$f" != name || continue
+ cat "$i" > "$CGROUP_MNT/$name/$f"
+ done
+ fi
+ echo "$$" > "$CGROUP_MNT/$name/tasks"
+ elif test "$action" = "destroy"; then
+ rmdir "$CGROUP_MNT/$name" 2>/dev/null || :
+ fi
+
+ return 0
+}
+
+function attachToCgroup
+{
+ _handleCgroup attach "$@"
+}
+
+function destroyCgroup
+{
+ _handleCgroup destroy "$@"
+}