direct-io.hg

view tools/examples/network-bridge @ 15440:ccf240f99263

Make network-bridge fail on NFS or iscsi root.
Since setting up bridging involves bringing down the network interface,
bridging clearly isn't compatible with the likes of NFS or iSCSI root.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
author Keir Fraser <keir@xensource.com>
date Sun Jul 01 22:20:46 2007 +0100 (2007-07-01)
parents f8819cb5f892
children
line source
1 #!/bin/bash
2 #============================================================================
3 # Default Xen network start/stop script.
4 # Xend calls a network script when it starts.
5 # The script name to use is defined in /etc/xen/xend-config.sxp
6 # in the network-script field.
7 #
8 # This script creates a bridge (default ${netdev}), adds a device
9 # (defaults to the device on the default gateway route) to it, copies
10 # the IP addresses from the device to the bridge and adjusts the routes
11 # accordingly.
12 #
13 # If all goes well, this should ensure that networking stays up.
14 # However, some configurations are upset by this, especially
15 # NFS roots. If the bridged setup does not meet your needs,
16 # configure a different script, for example using routing instead.
17 #
18 # Usage:
19 #
20 # network-bridge (start|stop|status) {VAR=VAL}*
21 #
22 # Vars:
23 #
24 # bridge The bridge to use (default ${netdev}).
25 # netdev The interface to add to the bridge (default gateway device).
26 # antispoof Whether to use iptables to prevent spoofing (default no).
27 #
28 # Internal Vars:
29 # pdev="p${netdev}"
30 # tdev=tmpbridge
31 #
32 # start:
33 # Creates the bridge as tdev
34 # Copies the IP and MAC addresses from pdev to bridge
35 # Renames netdev to be pdev
36 # Renames tdev to bridge
37 # Enslaves pdev to bridge
38 #
39 # stop:
40 # Removes pdev from the bridge
41 # Transfers addresses, routes from bridge to pdev
42 # Renames bridge to tdev
43 # Renames pdev to netdev
44 # Deletes tdev
45 #
46 # status:
47 # Print addresses, interfaces, routes
48 #
49 #============================================================================
52 dir=$(dirname "$0")
53 . "$dir/xen-script-common.sh"
54 . "$dir/xen-network-common.sh"
56 findCommand "$@"
57 evalVariables "$@"
59 netdev=${netdev:-$(ip route list | awk '/^default / { print $NF }' |
60 sed 's/.* dev //')}
61 bridge=${bridge:-${netdev}}
62 antispoof=${antispoof:-no}
64 pdev="p${netdev}"
65 tdev=tmpbridge
67 get_ip_info() {
68 addr_pfx=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'`
69 gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
70 }
72 do_ifup() {
73 if ! ifup $1 ; then
74 if [ ${addr_pfx} ] ; then
75 # use the info from get_ip_info()
76 ip addr flush $1
77 ip addr add ${addr_pfx} dev $1
78 ip link set dev $1 up
79 [ ${gateway} ] && ip route add default via ${gateway}
80 fi
81 fi
82 }
84 # Usage: transfer_addrs src dst
85 # Copy all IP addresses (including aliases) from device $src to device $dst.
86 transfer_addrs () {
87 local src=$1
88 local dst=$2
89 # Don't bother if $dst already has IP addresses.
90 if ip addr show dev ${dst} | egrep -q '^ *inet ' ; then
91 return
92 fi
93 # Address lines start with 'inet' and have the device in them.
94 # Replace 'inet' with 'ip addr add' and change the device name $src
95 # to 'dev $src'.
96 ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
97 s/inet/ip addr add/
98 s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/[0-9]\+\)@\1@
99 s/${src}/dev ${dst}/
100 " | sh -e
101 # Remove automatic routes on destination device
102 ip route list | sed -ne "
103 /dev ${dst}\( \|$\)/ {
104 s/^/ip route del /
105 p
106 }" | sh -e
107 }
109 # Usage: transfer_routes src dst
110 # Get all IP routes to device $src, delete them, and
111 # add the same routes to device $dst.
112 # The original routes have to be deleted, otherwise adding them
113 # for $dst fails (duplicate routes).
114 transfer_routes () {
115 local src=$1
116 local dst=$2
117 # List all routes and grep the ones with $src in.
118 # Stick 'ip route del' on the front to delete.
119 # Change $src to $dst and use 'ip route add' to add.
120 ip route list | sed -ne "
121 /dev ${src}\( \|$\)/ {
122 h
123 s/^/ip route del /
124 P
125 g
126 s/${src}/${dst}/
127 s/^/ip route add /
128 P
129 d
130 }" | sh -e
131 }
134 ##
135 # link_exists interface
136 #
137 # Returns 0 if the interface named exists (whether up or down), 1 otherwise.
138 #
139 link_exists()
140 {
141 if ip link show "$1" >/dev/null 2>/dev/null
142 then
143 return 0
144 else
145 return 1
146 fi
147 }
149 # Set the default forwarding policy for $dev to drop.
150 # Allow forwarding to the bridge.
151 antispoofing () {
152 iptables -P FORWARD DROP
153 iptables -F FORWARD
154 iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT
155 }
157 # Usage: show_status dev bridge
158 # Print ifconfig and routes.
159 show_status () {
160 local dev=$1
161 local bridge=$2
163 echo '============================================================'
164 ip addr show ${dev}
165 ip addr show ${bridge}
166 echo ' '
167 brctl show ${bridge}
168 echo ' '
169 ip route list
170 echo ' '
171 route -n
172 echo '============================================================'
173 }
175 is_network_root () {
176 local rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; }}' /etc/mtab)
177 local rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' /etc/mtab)
179 [[ "$rootfs" =~ "^nfs" ]] || [[ "$rootopts" =~ "_netdev" ]] && return 0 || return 1
180 }
182 op_start () {
183 if [ "${bridge}" = "null" ] ; then
184 return
185 fi
187 if is_network_root ; then
188 [ -x /usr/bin/logger ] && /usr/bin/logger "network-bridge: bridging not supported on network root; not starting"
189 return
190 fi
192 if link_exists "$pdev"; then
193 # The device is already up.
194 return
195 fi
197 create_bridge ${tdev}
199 preiftransfer ${netdev}
200 transfer_addrs ${netdev} ${tdev}
201 if ! ifdown ${netdev}; then
202 # If ifdown fails, remember the IP details.
203 get_ip_info ${netdev}
204 ip link set ${netdev} down
205 ip addr flush ${netdev}
206 fi
207 ip link set ${netdev} name ${pdev}
208 ip link set ${tdev} name ${bridge}
210 setup_bridge_port ${pdev}
212 add_to_bridge2 ${bridge} ${pdev}
213 do_ifup ${bridge}
215 if [ ${antispoof} = 'yes' ] ; then
216 antispoofing
217 fi
218 }
220 op_stop () {
221 if [ "${bridge}" = "null" ]; then
222 return
223 fi
224 if ! link_exists "$bridge"; then
225 return
226 fi
228 transfer_addrs ${bridge} ${pdev}
229 if ! ifdown ${bridge}; then
230 get_ip_info ${bridge}
231 fi
232 ip link set ${pdev} down
233 ip addr flush ${bridge}
235 brctl delif ${bridge} ${pdev}
236 ip link set ${bridge} down
238 ip link set ${bridge} name ${tdev}
239 ip link set ${pdev} name ${netdev}
240 do_ifup ${netdev}
242 brctl delbr ${tdev}
243 }
245 # adds $dev to $bridge but waits for $dev to be in running state first
246 add_to_bridge2() {
247 local bridge=$1
248 local dev=$2
249 local maxtries=10
251 echo -n "Waiting for ${dev} to negotiate link."
252 ip link set ${dev} up
253 for i in `seq ${maxtries}` ; do
254 if ifconfig ${dev} | grep -q RUNNING ; then
255 break
256 else
257 echo -n '.'
258 sleep 1
259 fi
260 done
262 if [ ${i} -eq ${maxtries} ] ; then echo '(link isnt in running state)' ; fi
264 add_to_bridge ${bridge} ${dev}
265 }
267 case "$command" in
268 start)
269 op_start
270 ;;
272 stop)
273 op_stop
274 ;;
276 status)
277 show_status ${netdev} ${bridge}
278 ;;
280 *)
281 echo "Unknown command: $command" >&2
282 echo 'Valid commands are: start, stop, status' >&2
283 exit 1
284 esac