X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=scripts%2Fvserver.functions;h=a10344d7c10207269208fa147357f6fc022758df;hb=be766a320397bace4e8ad1a02d543393dd633d9c;hp=e41334c0af1d51a01b4a28cbfe9f2355f7a5bc50;hpb=aef33b9810242b2a769ad29facc1678f30c0d235;p=util-vserver.git diff --git a/scripts/vserver.functions b/scripts/vserver.functions index e41334c..a10344d 100644 --- a/scripts/vserver.functions +++ b/scripts/vserver.functions @@ -75,8 +75,10 @@ N_CONTEXT= SILENT_OPT= CGROUP_MNT=/dev/cgroup -CGROUP_SUBSYS=all +declare -a CGROUP_SUBSYS=() declare -a CGROUP_INHERIT=( cpuset.cpus cpuset.mems ) +CGROUP_BASE="" +CGROUP_MNT_PER_SS="" : ${VSERVER_NAME:=$(basename "$VSERVER_DIR")} @@ -112,6 +114,12 @@ function _generateChbindOptions test -n "$_HAVE_INTERFACE_OPTIONS" || _generateInterfaceOptions "$vdir" + if test -e "$vdir"/noncontext -o \ + \( -e "$vdir"/spaces/net -a ! -e "$vdir"/ncontext \); then + _HAVE_CHBIND_OPTIONS=1 + return 0 + fi + local f="$vdir"/interfaces/bcast getFileValue bcast "$f" f="$vdir"/interfaces/lback @@ -754,7 +762,11 @@ function disableInterfaces IP_ADDR_FLUSH) ;; IP_LINK) ;; ## Ignore the link-down command for now IP_ROUTE) $_IP route del "$@";; - TUNCTL) $_TUNCTL --~persist "$1";; + TUNCTL) + local dev="$1" + shift + $_TUNCTL --~persist "$@" "$dev" + ;; *) echo "Unknown interface-command type '$type'" >&2; false;; esac done @@ -790,29 +802,21 @@ function _generateSpaceOptions local vdir="$1" local d="$vdir"/spaces local shared - - 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 --xid "$shared" --pid -- ) - fi - fi - - 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 --xid "$shared" --net -- ) + local space + + for space in pid net; do + if test -e "$d"/$space; then + getFileValue shared "$d"/$space || shared="" + if test -z "$shared"; then + OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --$space ) + elif test "$shared" = "0"; then + : # Do nothing + else + OPTS_VSPACE_SHARED=( "${OPTS_VSPACE_SHARED[@]}" --$space ) + VSPACE_SHARED_CMD=( "${VSPACE_SHARED_CMD[@]}" $_VSPACE --enter "$shared" --$space -- ) + fi fi - fi + done local mask getFileValue mask "$d"/mask || \ @@ -1459,16 +1463,24 @@ function _generateCgroupOptions 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")) + _readFileToArray CGROUP_SUBSYS "$file" + else + CGROUP_SUBSYS=( $($_SED '/^#/d;/^ns[[:space:]]/d;s/[[:space:]].*//' /proc/cgroups) ) fi findFile file "$__CONFDIR/.defaults/cgroup/inherit" "" if test -n "$file"; then _readFileToArray CGROUP_INHERIT "$file" "" fi + findFile file "$__CONFDIR/.defaults/cgroup/base" "" + if test -n "$file"; then + read CGROUP_BASE < "$file" + test "$CGROUP_BASE" != "${CGROUP_BASE%/}" || \ + CGROUP_BASE="${CGROUP_BASE}/" + fi + findFile file "$__CONFDIR/.defaults/cgroup/per-ss" "" + if test -n "$file"; then + CGROUP_MNT_PER_SS=1 + fi return 0 } @@ -1476,9 +1488,24 @@ function _generateCgroupOptions function useCgroup { hasCgroup || return 1 - test -d "$CGROUP_MNT" || return 1 + if test -n "$CGROUP_MNT_PER_SS"; then + local existing=0 + local ss + for ss in "${CGROUP_SUBSYS[@]}"; do + if test -e "$CGROUP_MNT/$ss/tasks"; then + let existing=${existing}+1 + fi + done + test "$existing" -gt 0 || return 1 + else + test -e "$CGROUP_MNT/tasks" || return 1 + fi + local memcg="" + if $_VSERVER_INFO - FEATURE memcg; then + memcg=1 + fi test -d "$1/cgroup" -o \ - \( -d "$__CONFDIR/.defaults/cgroup" -a \ + \( \( -d "$__CONFDIR/.defaults/cgroup" -o -n "$memcg" \) -a \ ! -e "$1/nocgroup" \) } @@ -1489,40 +1516,78 @@ function _handleCgroup local dir local name local i + local j local parent + local -a mnts + local ss useCgroup "$vdir" || return 0 findDir dir "$vdir/cgroup" "$__CONFDIR/.defaults/cgroup" "" - test -d "$dir" || return 0 - if test -r "$dir"/name; then + if test -n "$dir" -a -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 || : + if test -n "$CGROUP_MNT_PER_SS"; then + mnts=() + for ss in "${CGROUP_SUBSYS[@]}"; do + mnts=( "${mnts[@]}" "$CGROUP_MNT/$ss" ) + done + else + mnts=( "$CGROUP_MNT" ) fi + for mnt in "${mnts[@]}"; do + test -d "$mnt" || continue + if test "$action" = "attach"; then + if test -n "$CGROUP_BASE"; then + local -a dirs=() + i="$mnt/$CGROUP_BASE" + while test "$mnt" != "$i"; do + dirs=( "$i" "${dirs[@]}" ) + i="${i%/*}" + done + for i in "${dirs[@]}"; do + if mkdir "$i" 2>/dev/null; then + parent="${i%/*}" + for j in "${CGROUP_INHERIT[@]}"; do + test -f "$parent/$j" || continue + cat "$parent/$j" > "$i/$j" + done + fi + done + fi + if mkdir "$mnt/$CGROUP_BASE$name" 2>/dev/null; then + parent="$mnt/$CGROUP_BASE$name" + parent="${parent%/*}" + for i in "${CGROUP_INHERIT[@]}"; do + test -f "$parent/$i" || continue + cat "$parent/$i" > "$mnt/$CGROUP_BASE$name/$i" + done + + if test -n "$dir"; then + shopt -s nullglob + for i in "$dir"/*; do + f="${i##*/}" + test "$f" != mnt -a "$f" != subsys -a \ + "$f" != inherit -a "$f" != name -a "$f" != base -a \ + "$f" != per-ss \ + || continue + if test -n "$CGROUP_MNT_PER_SS"; then + ss="${f%%.*}" + test "$ss" = "${mnt##*/}" || continue + fi + cat "$i" > "$mnt/$CGROUP_BASE$name/$f" + done + fi + fi + echo "$$" > "$mnt/$CGROUP_BASE$name/tasks" + elif test "$action" = "destroy"; then + rmdir "$mnt/$name" 2>/dev/null || : + fi + done return 0 }