added Vector_zeroEnd() function
[util-vserver.git] / util-vserver / scripts / vserver.functions
index ae9bd05..b4c0c64 100644 (file)
@@ -38,7 +38,7 @@ declare -a ENTER_SHELL=()
 
 declare -a OPTS_VCONTEXT_CREATE=()
 declare -a OPTS_VCONTEXT_MIGRATE=()
-declare -a OPTS_VATTRIBUTE=()
+declare -a OPTS_VATTRIBUTE=( --flag fakeinit )
 declare -a OPTS_VSCHED=()
 
 declare -a VSERVER_EXTRA_CMDS=()
@@ -182,7 +182,7 @@ function sendKillSequence
     while isCtxRunning "$ctx"; do
        test -z "$wait" || sleep "$wait"
        
-       $_VKILL -c "$ctx" ${1:+-s "$1"}
+       $_VKILL -c "$ctx" ${1:+-s "$1"} 2>/dev/null || :
        test "$2" || break
        wait="$2"
        shift 2
@@ -411,6 +411,17 @@ function _addInterfaceCmd
     let ++INTERFACE_CMDS_IDX
 }
 
+## Usage: _generateMac <var> <iface> <ctx>
+function _generateMac
+{
+    isNumber "$2" || {
+       echo $"Interface basename '$iface' must be either a number, or the mac must be configured explicitly" >&2
+       return 1
+    }
+
+    eval $1=$(printf "f0:ff:%02x:%02x:%02x:%02x" $[ (~($2>>8)) & 0xff ] $[ ($2 & 0xff) ] $[ ($3>>8) & 0xff ] $[ $3 & 0xff ])
+}
+
 ## Usage: _processSingleInterface <interface-directory>
 function _processSingleInterface
 {
@@ -423,25 +434,34 @@ function _processSingleInterface
     local bcast
     local name
     local scope
+    local mac
+    local extip
+    local up="up"
 
     _getInterfaceValue ip     '' "$iface"
+    _getInterfaceValue extip  '' "$iface" "$iface/.."
     _getInterfaceValue dev    '' "$iface" "$iface/.."
     _getInterfaceValue prefix '' "$iface" "$iface/.."
     _getInterfaceValue mask   '' "$iface" "$iface/.."
     _getInterfaceValue bcast  '' "$iface" "$iface/.."
     _getInterfaceValue name   '' "$iface"
     _getInterfaceValue scope  '' "$iface" "$iface/.."
+    _getInterfaceValue mac    '' "$iface"
 
     test "$ip" || { echo $"Can not read ip for '$iface'"  >&2; return 1; }
+
+    test ! -e "$iface"/down    || up=
     
-    test ! -e "$iface"/only_ip || {
-       echo $"The 'only_ip' flag for interface '$iface' is deprecated; use 'nodev' instead of" >&2
-       unset dev
-    }
-    test ! -e "$iface"/nodev   || unset dev
-    
-    if test "$dev"; then
+    while test "$dev"; do
        _transformMask2Prefix prefix "$prefix" "$mask"
+       INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
+
+       test ! -e "$iface"/nodev || break
+       test ! -e "$iface"/only_ip || {
+           ## LEGACY ALERT
+           echo $"The 'only_ip' flag for interface '$iface' is deprecated; use 'nodev' instead of" >&2
+           break
+       }
 
        case "$dev" in
            (*.*)
@@ -452,22 +472,38 @@ function _processSingleInterface
                test -f /proc/net/vlan || {
                    _addInterfaceCmd VCONFIG "${dev/./ }"
                    _addInterfaceCmd IP_ADDR 127.0.0.1/8 broadcast 127.255.255.255 dev "$dev"
-                   _addInterfaceCmd IP_LINK "$dev"
+                   _addInterfaceCmd IP_LINK "$dev" $up
                }
                ;;
        esac
 
-       INTERFACES=( "${INTERFACES[@]}" "$ip${prefix:+/$prefix}" )
-       _addInterfaceCmd IP_ADDR  "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev"
-       #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
-       _addInterfaceCmd IP_LINK  "$dev"
-    fi
+       if ! test -e "$iface"/indirect; then
+           _addInterfaceCmd IP_ADDR  "$ip${prefix:+/$prefix}" broadcast ${bcast:-+} ${name:+label "$dev:$name"} dev "$dev"
+           #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev"
+           _addInterfaceCmd IP_LINK  "$dev" $up
+       elif ! test "$ctx"; then
+           echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2
+           return 1
+       else
+           test "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1
+           _addInterfaceCmd MODPROBE dummy "$dev"
+           _addInterfaceCmd IP_LINK  dev dummy0 address "$mac"
+           _addInterfaceCmd NAMEIF   "$dev" "$mac"
+           _addInterfaceCmd IP_ADDR  "$ip${prefix:+/$prefix}" dev "$dev"
+           test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip"
+       fi
+
+       break
+    done
 }
 
 ## Usage: _generateInterfaceOptions <vserver-directory>
 function _generateInterfaceOptions
 {
     local iface
+    local ctx
+
+    test ! -e "$1"/context || read ctx <"$1"/context
 
     for iface in "$1/interfaces/"*; do
         test   -d "$iface"          || continue
@@ -483,21 +519,35 @@ function enableInterfaces
     local i=0
     declare -a var
 
+    lock "$LOCKDIR"/vserver.interfaces
+
     while test $i -lt $INTERFACE_CMDS_IDX; do
        eval var='( "${INTERFACE_CMDS_'$i'[@]}" )'
        local type=${var[0]}
        unset var[0]
-       
+
+       set -- "${var[@]}"
        case "$type" in
-           VCONFIG)    $_VCONFIG  add "${var[@]}";;
-           IP_ADDR)    $_IP addr  add "${var[@]}";;
-           IP_LINK)    $_IP link  set "${var[@]}" up;;
-           IP_ROUTE)   $_IP route add "${var[@]}";;
-           *)          echo "Unknown interface-command type '$type'" >&2; false;;
+           IPTABLES)   ;; ## TODO
+           MODPROBE)
+               local mod=$1
+               local name=$2
+               shift 2
+               $_MODPROBE ${name:+-o "$name"} "$mod" "$@"
+               ;;
+           NAMEIF)             $_NAMEIF "$@";;
+           VCONFIG)            $_VCONFIG  add   "$@";;
+           IP_ADDR)            $_IP addr  add   "$@";;
+           IP_ADDR_FLUSH)      $_IP addr  flush "$@";;
+           IP_LINK)            $_IP link  set   "$@";;
+           IP_ROUTE)           $_IP route add   "$@";;
+           *)                  echo "Unknown interface-command type '$type'" >&2; false;;
        esac
 
        let ++i
     done
+
+    unlock 1
 }
 
 function disableInterfaces
@@ -507,6 +557,8 @@ function disableInterfaces
     local i=$INTERFACE_CMDS_IDX
     declare -a var
 
+    lock "$LOCKDIR"/vserver.interfaces
+    
     while test $i -gt 0; do
        let --i || :
 
@@ -514,14 +566,21 @@ function disableInterfaces
        local type=${var[0]}
        unset var[0]
        
+       set -- "${var[@]}"
        case "$type" in
-           VCONFIG)    $_VCONFIG  rem "${var[@]}";;
-           IP_ADDR)    $_IP addr  del "${var[@]}";;
-           IP_LINK)    ;; ## Ignore the link-down command for now
-           IP_ROUTE)   $_IP route del "${var[@]}";;
-           *)          echo "Unknown interface-command type '$type'" >&2; false;;
+           IPTABLES)           ;; ## TODO
+           MODPROBE)           $_RMMOD "${2:-$1}";;
+           NAMEIF)             ;;
+           VCONFIG)            $_VCONFIG  rem "$@";;
+           IP_ADDR)            $_IP addr  del "$@";;
+           IP_ADDR_FLUSH)      ;;
+           IP_LINK)            ;; ## Ignore the link-down command for now
+           IP_ROUTE)           $_IP route del "$@";;
+           *)                  echo "Unknown interface-command type '$type'" >&2; false;;
        esac
     done
+
+    unlock 1
 }
 
 ## Usage: prepareInit <vserver-directory>
@@ -551,7 +610,7 @@ function generateOptions
 
     if test "$_IS_FAKEINIT"; then
        CHCONTEXT_INIT_OPTS=( --disconnect --flag fakeinit )
-       OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --fakeinit --disconnect )
+       OPTS_VCONTEXT_MIGRATE=( "${OPTS_VCONTEXT_MIGRATE[@]}" --initpid --disconnect )
     fi
 }
 
@@ -663,22 +722,30 @@ will be killed nevertheless..."
 
 function _sourceWrap
 {
-    local vdir name flavor start i
+    local vdir name flavor start i already_handled base
     . "$@"
 }
 
 ## Usage: execScriptlets <vserver-cfgdir> <vserver-name> <script-flavor>
 function execScriptlets
 {
-    local vdir=$1
-    local name=$2
-    local flavor=$3
-    local start=
-    local i
+    declare -r vdir=$1
+    declare -r name=$2
+    declare -r flavor=$3
+    local base i
+
+    for base in "$vdir"/scripts "$CONFDIR"/.defaults/scripts; do
+       local   DONT_SKIP_DEFAULTS=
+       local   already_handled=
+       
+       for i in "$base/$flavor" "$base/$flavor.d"/*; do
+           test -f "$i" -a -r "$i" || continue
+           already_handled=1
+           local start=
+           test -x "$i" || start=_sourceWrap
+           $start "$i" "$flavor" "$name"
+       done
 
-    for i in "$vdir/scripts/$flavor" "$vdir/scripts/$flavor.d"/*; do
-       test -f "$i" -a -r "$i" || continue
-       test -x "$i" || start=_sourceWrap
-       $start "$i" "$flavor" "$name"
+       test -z "$already_handled" -o "$DONT_SKIP_DEFAULTS" || break
     done
 }