summaryrefslogtreecommitdiffstats
path: root/vserver.netns
blob: 6ad930dcadf50af0d9e9aba06bedee93e03360f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/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