summaryrefslogtreecommitdiffstats
path: root/vserver.netns
blob: 8e55c02579e7b8e0d3b86f1b8e10165d36c0e3e9 (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
#!/bin/bash

: ${UTIL_VSERVER_VARS:=/usr/lib/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"
. $__PKGLIBDIR/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 dev "$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}/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

    for net in "$VSERVER_DIR/netns/"*; do
        test   -d "$net"            || continue
        test ! -e "${net}/disabled" || continue

        _processSingleNetwork add "$net"
    done
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
    for net in "${VSERVER_DIR}/netns/"*; do
        test   -d "$net"            || continue
        test ! -e "${net}/disabled" || continue

        _processSingleNetwork remove "$net"
    done

    $_IP netns delete "$VSERVER_NAME"
fi

exit $ret