No need to read the name again.
[util-vserver.git] / scripts / vserver.functions
index c97c0c6..0997c2e 100644 (file)
@@ -20,6 +20,7 @@
 #  $VSERVER_NAME  ... name of vserver
 
 declare -a NICE_CMD=()
+declare -a IONICE_CMD=()
 declare -a CHBIND_CMD=()
 declare -a CAP_OPTS=()
 declare -a CHCONTEXT_INIT_OPTS=()
@@ -70,6 +71,10 @@ N_CONTEXT=
 
 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
@@ -135,6 +140,17 @@ function _generateNiceCommand
     NICE_CMD=( $_NICE -n $nice )
 }
 
+function _generateIONiceCommand
+{
+    local vdir=$1
+    local ionice_class=2
+    local ionice_priority=0
+
+    test -r "$vdir/ionice/class" && read ionice_class <"$vdir"/ionice/class
+    test -r "$vdir/ionice/priority" && read ionice_priority <"$vdir"/ionice/priority
+
+    IONICE_CMD=( $_IONICE -c$ionice_class -n$ionice_priority )
+}
 
 function _generatePersonalityOptions
 {
@@ -330,6 +346,13 @@ function _generateInitOptions
            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
@@ -561,6 +584,7 @@ function _processSingleInterface
     local mac
     local extip
     local up="up"
+    local peer
 
     _getInterfaceValue ip     '' "$iface"
     _getInterfaceValue extip  '' "$iface" "$iface/.."
@@ -571,6 +595,7 @@ function _processSingleInterface
     _getInterfaceValue name   '' "$iface"
     _getInterfaceValue scope  '' "$iface" "$iface/.."
     _getInterfaceValue mac    '' "$iface"
+    _getInterfaceValue peer   '' "$iface"
 
     test -n "$ip" || { echo $"Can not read ip for '$iface'"  >&2; return 1; }
     test -n "$dev" -o -e "$iface"/nodev || {
@@ -613,7 +638,7 @@ function _processSingleInterface
                _addInterfaceCmd TUNCTL "$dev" $tun_info
            fi
 
-           _addInterfaceCmd IP_ADDR  "$ip${prefix:+/$prefix}" $use_bcast ${name:+label "$dev:$name"} dev "$dev"
+           _addInterfaceCmd IP_ADDR  "$ip${prefix:+/$prefix}" $use_bcast ${name:+label "$dev:$name"} dev "$dev" ${peer:+peer "$peer"}
            #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
            _addInterfaceCmd IP_LINK  "$dev" $up
        elif ! test -n "$N_CONTEXT"; then
@@ -755,8 +780,8 @@ function _generateSpaceOptions
     local vdir="$1"
     local d="$vdir"/spaces
 
-    test ! -e "$d"/pid || \
-      OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --pid )
+    ( test ! -e "$d"/pid ) || \
+       OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --pid )
 
     test ! -e "$d"/net || {
        OPTS_VSPACE=( "${OPTS_VSPACE[@]}" --net )
@@ -809,6 +834,7 @@ function generateOptions
     _generateInterfaceOptions   "$1"
     test -n "$_HAVE_CHBIND_OPTIONS" || _generateChbindOptions "$1" 
     _generateNiceCommand        "$1"
+    _generateIONiceCommand     "$1"
     _generateInitOptions        "$1"
     _generateChcontextOptions   "$1"
     _generateScheduleOptions    "$1"
@@ -816,6 +842,7 @@ function generateOptions
     _generateTagOptions         "$1"
     _generateMemctrlOptions     "$1"
     _generateSpaceOptions       "$1"
+    _generateCgroupOptions
 
     if test -n "$_IS_FAKEINIT"; then
        CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
@@ -932,7 +959,7 @@ function mountVserver
         _namespaceCleanup "$cfgdir"
 
     isAvoidNamespace "$cfgdir" || \
-       $_SECURE_MOUNT --rbind -n "$vdir" "/"
+       $_SECURE_MOUNT --rbind -n -o dev "$vdir" "/"
 }
 
 function _umountVserverInternal
@@ -1017,7 +1044,7 @@ function initWait
            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
 
@@ -1349,7 +1376,7 @@ function _namespaceCleanup
     done < /proc/mounts
     # separate loop to avoid races while reading /proc/mounts
     for i in "${list_umount[@]}"; do
-       $_UMOUNT -l -n "$i"
+       $_UMOUNT -l -n -i "$i"
     done
 }
 
@@ -1380,3 +1407,91 @@ function handleDeviceMap
        $_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"
+    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
+               cat "$i" > "$CGROUP_MNT/$name/${i##*/}"
+           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 "$@"
+}