File: ifupdown-hotplug

package info (click to toggle)
ifupdown 0.8.44
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 952 kB
  • sloc: ansic: 2,781; sh: 899; perl: 513; makefile: 90
file content (130 lines) | stat: -rwxr-xr-x 2,773 bytes parent folder | download
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
#!/bin/sh -e
#
# run {ifup,ifdown} with the --allow=hotplug option.
#

PATH='/sbin:/bin:/usr/sbin:/usr/bin'

if [ -x "$(command -v logger)" ]; then
	LOGGER=logger
else
	unset LOGGER
fi

# for diagnostics
if [ -t 1 -a -z "$LOGGER" ] || [ ! -e '/dev/log' ]; then
	mesg() {
		echo "$@" >&2
	}
elif [ -t 1 ]; then
	mesg() {
		echo "$@"
		$LOGGER -t "${0##*/}[$$]" "$@"
	}
else
	mesg() {
		$LOGGER -t "${0##*/}[$$]" "$@"
	}
fi

if [ -z "$INTERFACE" ]; then
    mesg "Bad ifupdown udev helper invocation: \$INTERFACE is not set"
    exit 1
fi

check_program() {
    [ -x "$(command -v $1)" ] && return 0

    mesg "ERROR: $1 not found. You need to install the ifupdown package."
    mesg "ifupdown udev helper $ACTION event for $INTERFACE not handled."
    exit 1
}

wait_for_interface() {
    local interface=$1
    local state

    while :; do
	read state /sys/class/net/$interface/operstate 2>/dev/null || true
	if [ "$state" != down ]; then
		return 0
	fi
	sleep 1
    done
}

net_ifup() {
    check_program ifup

    # exit if the interface is not configured as allow-hotplug
    TARGET_IFACE=$(ifquery --allow hotplug -l "$INTERFACE" || true)
    if [ -z "$TARGET_IFACE" ]; then
        exit 0
    fi

    if [ -d /run/systemd/system ]; then
        exec systemctl --no-block start $(systemd-escape --template ifup@.service $TARGET_IFACE)
    fi

    wait_for_interface lo

    exec ifup --allow=hotplug $INTERFACE
}

net_ifdown() {
    check_program ifdown

    # systemd will automatically ifdown the interface on device
    # removal by binding the instanced service to the network device
    if [ -d /run/systemd/system ]; then
        exit 0
    fi

    exec ifdown --allow=hotplug $INTERFACE
}

do_everything() {

case "$ACTION" in
    add)
    # these interfaces generate hotplug events *after* they are brought up
    case $INTERFACE in
	ppp*|ippp*|isdn*|plip*|lo|irda*|ipsec*)
	exit 0 ;;
    esac

    net_ifup
    ;;

    remove)
    # the pppd persist option may have been used, so it should not be killed
    case $INTERFACE in
	ppp*)
	exit 0 ;;
    esac

    net_ifdown
    ;;

    *)
    mesg "NET $ACTION event not supported"
    exit 1
    ;;
esac

}

# under systemd we don't do synchronous operations, so we can run in the
# foreground; we also need to, as forked children get killed right away under
# systemd
if [ -d /run/systemd/system ]; then
    do_everything
else
    # under sysvinit we need to fork as we start the long-running
    # "ifup". but there, forked processes won't get killed.
    # When udev_log="debug" stdout and stderr are pipes connected to udevd.
    # They need to be closed or udevd will wait for this process which will
    # deadlock with udevsettle until the timeout.
    exec > /dev/null 2> /dev/null
    do_everything &
fi