#!/bin/bash : ${UTIL_VSERVER_VARS:=/usr/share/util-vserver/netns/util-vserver-vars} test -e "$UTIL_VSERVER_VARS" || { echo $"Can not find util-vserver installation (the file '$UTIL_VSERVER_VARS' would be expected); aborting..." >&2 exit 1 } . "$UTIL_VSERVER_VARS" . "$_LIB_FUNCTIONS" . "$_LIB_VSERVER_FUNCTIONS" function _processSingleNetwork() { local dev local iface local vlan local mac getFileValue dev "${2}/dev" "${2}/../dev" [ -n "$dev" ] || return 1 iface="$(netnsCreateIfaceName "$2")" getFileValue vlan "${2}/vlan" case "$1" in add) if [ ! -e "${2}/nocleanup" ]; then $_IP link show dev "$iface" >/dev/null 2>&1 && $_IP link del "$iface" $_IP netns exec "$VSERVER_NAME" $_IP link show dev "$iface" >/dev/null 2>&1 && $_IP netns exec "$VSERVER_NAME" $_IP link del "$iface" fi if [ -z "$vlan" ]; then $_IP link add link "$dev" name "$iface" type macvlan mode bridge else $_IP link add link "$dev" name "$iface" type vlan id "$vlan" fi getFileValue mac "${2}/mac" [ -n "$mav" ] || mac="$(netnsCreateMac "$2")" $_IP link set dev "$iface" netns "$VSERVER_NAME" $_IP netns exec "$VSERVER_NAME" $_IP link set "$iface" down $_IP netns exec "$VSERVER_NAME" $_IP link set "$iface" address "$mac" $_IP netns exec "$VSERVER_NAME" $_VPROCUNHIDE ;; remove) $_IP netns exec "$VSERVER_NAME" $_IP link del "$iface" ;; esac } # preserve args ARGS=( "$@" ) SELF=( "$0" ) # skip arguments starting with - while : do case "$1" in --) SELF=( "${SELF[@]}" "$1" ) shift break ;; -*) SELF=( "${SELF[@]}" "$1" ) shift ;; *) break ;; esac done VSERVER_NAME="$1" ACTION="$2" NETNS=() _setVserverDir "$VSERVER_NAME" [ -d "${VSERVER_DIR}/spline-netns/" ] && _USE_NETNS="1" if [[ "$ACTION" == "start" && -n "${_USE_NETNS}" ]]; then pushd "$VSERVER_DIR" >/dev/null execScriptlets "$VSERVER_DIR" "$VSERVER_NAME" pre-netns popd >/dev/null # create and init netns $_IP netns list | grep -q "^${VSERVER_NAME}\$" || $_IP netns add "$VSERVER_NAME" $_IP netns exec "$VSERVER_NAME" $_IP link set dev lo up shopt -s nullglob for net in "$VSERVER_DIR/spline-netns/"*; do test -d "$net" || continue test ! -e "${net}/disabled" || continue _processSingleNetwork add "$net" done shopt -u nullglob fi if [[ "$ACTION" == "start" || "$ACTION" == "stop" || "$ACTION" == "enter" || "$ACTION" == "exec" || "$ACTION" == "suexec" ]] then if [ -n "${_USE_NETNS}" ]; then # enter netns NETNS=( $_IP netns exec "$VSERVER_NAME" ) fi fi if [[ "$ACTION" == "restart" ]]; then "${SELF[@]}" --sync "$VSERVER_NAME" stop exec "${SELF[@]}" "$VSERVER_NAME" start fi # prepare for executing real _VSERVER export _USE_NETNS export UTIL_VSERVER_VARS if [[ "$ACTION" != "stop" ]]; then exec "${NETNS[@]}" "$_REAL_VSERVER" "${ARGS[@]}" fi # ACTION = stop: if namespace does not exists anymore, # do not try to execute vserver in it if ! $_IP netns list | grep -q "^$VSERVER_NAME\$"; then exec "$_REAL_VSERVER" "${ARGS[@]}" fi # ACTION = stop: need to do something after the stop, so no exec here "${NETNS[@]}" "$_REAL_VSERVER" "${ARGS[@]}" ret=$? if [ -n "${_USE_NETNS}" ]; then shopt -s nullglob for net in "${VSERVER_DIR}/spline-netns/"*; do test -d "$net" || continue test ! -e "${net}/disabled" || continue _processSingleNetwork remove "$net" done shopt -u nullglob procs="$($_IP netns exec "$VSERVER_NAME" netstat -tulpenW | sed '1d;2d')" if [ -n "$procs" ]; then echo "There are still processes active in the network namespace:" echo "$procs" echo echo "Deleting of the network namespace would produce a bad state." echo "So we DO NOT delete the network namespace. You maybe want" echo "to kill the processes and execute the following commands:" echo " $_IP netns exec \"$VSERVER_NAME\" netstat -tulpen" echo " $_IP netns delete \"$VSERVER_NAME\"" else $_IP netns delete "$VSERVER_NAME" fi fi exit $ret