Bruce Dubbs wrote: > What I'm using right now is: > > # Ignore Xen virtual interfaces > if [ -e /proc/xen ]; then > msg="The rules file should not be created in the Xen environment" > usage > fi > > I'm not sure if that is right or not. Someone with Xen needs to verify.
Hmm, I don't know much about how Xen actually works for network devices, but I can see two ways to do it in general. First, it could provide exclusively virtual NICs, with effectively random MAC addresses at each boot. (Like qemu does AFAIK.) It would use tun/tap or something like that to get out to the real network. But second, it could provide access to the host's NIC directly to the VM, intercepting the actual hardware MMIO operations and watching to make sure the VM<->VM isolation is maintained. If it does only the first, then your method seems like it should work -- if Xen is running at all, then refuse to write a rules file. But if it ever does the second, then the script will have to filter out interface by interface, which ones are OK and which ones are not. The latter (filtering by interface) is what the current rules do, but of course that doesn't mean that's the only way to successfully do it. Anyone run Xen? Should we just try it and see what happens? :-) > I did find > > NIC=/sys/class/net/eth0 > $ basename $(readlink -f $NIC/device/subsystem) > pci > > but I'm not sure how robust that is. That matches the current libudev code FWIW. In libudev-device.c, udev_device_get_subsystem, it caches the subsystem string per device, and the way it finds it the first time is by reading the "subsystem" symlink (util_get_sys_core_link_value(<udev>, "subsystem", <...>), and the code in libudev-util.c shows that doing a readlink() and then some string manipulation to do "basename"). > I'm going to post a new tarball in a few minutes after I finish some > testing. Take a look at that. Are the sources for this tarball in a source control repository somewhere? I might have missed where, in the discussion earlier when it was being created. I don't see them in the book repository, but that repository may not be the best place to keep track of them, either. Anyway, an alternative patch to add indirection to the ifup / ifdown scripts is attached. It needs to add 2 lines to udev-config; one to run the path_id builtin on network-subsystem devices, and the other to pull attr{address} into the udev database (ENV{ID_ADDRESS} is what I used, but the name doesn't matter that much). The biggest change (in line count) is to the init-functions script; this is the central part of the dereferencing, and is used by both ifup and ifdown. It handles both mac-based and path-based "persistence", so it should handle real physical (broken :-) ) devices whose MAC changes for some reason, somewhat better than today, if the user decides to go with path-based config and they don't move the device. It will also handle replacing a network card, if the new card goes in the same slot that the old one came out of. The boilerplate to call dereference_network_device and use its output (on both the main interface and the INTERFACE_COMPONENTS list; no point in being able to create br0 if you can't control which physical NIC or NICs go into it) is in both ifup and ifdown. The service scripts are unchanged; $1 and $IFACE are still the interface to bring up (though see below). This is tested with ipv4-static and dhcpcd (though the dhcpcd script might be older than what we have in blfs), plus a service script I wrote for wake on LAN. HOWEVER: I have *not* tested any bridging (though I believe that should work), or much else that's very complicated. I also don't know why $1 is separate from $IFACE, with $IFACE being required in every service config file; this information was duplicated in the filename before. It's no longer required today (and in fact will be overwritten to the interface found by udev, if set). It's possible that $IFACE doesn't mean what I think it means, but if so, I think this should continue to work if a system still has ifconfig.ethX config files (they get "dereferenced" to ethX directly if /sys/class/net/eth* exists). People who know the service file interface better than I do -- help? :-)
Index: udev-config/55-lfs.rules =================================================================== --- udev-config/55-lfs.rules (revision 9920) +++ udev-config/55-lfs.rules (working copy) @@ -12,3 +12,8 @@ KERNEL=="isdn[0-9]*", GROUP="dialout" KERNEL=="isdnctrl[0-9]*", GROUP="dialout" KERNEL=="dcbri[0-9]*", GROUP="dialout" + +# This causes device path and address information to be stored in the udev +# database for network cards, for use by the bootscripts +SUBSYSTEM=="net", IMPORT{builtin}="path_id" +SUBSYSTEM=="net", ENV{ID_ADDRESS}="$attr{address}" Index: bootscripts/lfs/lib/services/init-functions =================================================================== --- bootscripts/lfs/lib/services/init-functions (revision 9920) +++ bootscripts/lfs/lib/services/init-functions (working copy) @@ -790,4 +790,56 @@ [ "$1" = "t" ] } +################################################################################ +# dereference_network_device() # +# Usage: dereference_network_device [ mac-{address} | path-{path_id path} ] # +# # +# Purpose: Find the "real" network device name whose MAC or path is given. # +# Used to map persistent identifiers to the real device so that # +# configuration can be stable while physical devices move around. # +# Sets the real_device variable to the device found, or "" if none. # +# # +# Inputs: Accepts a single string value in the form mac-XX:XX:XX:XX:XX:XX or # +# path-XXXXXXXXXX (matching udev's ID_PATH environment key) # +# # +# Return values: # +# 0 - Found a matching physical device; ${real_device} is it # +# 1 - No matching physical device found; ${real_device} is "" # +################################################################################ +dereference_network_device() +{ + # Accept real interfaces as well as identifiers + if [ -e /sys/class/net/"${1}" ] ; then + real_device="${1}" + return 0 + fi + + real_device="" + local id="${1#*-}" + + case "$1" in + mac-*) + for dev in /sys/class/net/* ; do + if /sbin/udevadm info -q env -p "$dev" | grep -q "ID_ADDRESS=${id}" ; then + real_device="${dev##*/}" + return 0 + fi + done + return 1 + ;; + path-*) + for dev in /sys/class/net/* ; do + if /sbin/udevadm info -q env -p "$dev" | grep -q "ID_PATH=${id}" ; then + real_device="${dev##*/}" + return 0 + fi + done + return 1 + ;; + *) + log_failure_msg "\nDon't know how to dereference $1." + exit 1 + esac +} + # End /lib/lsb/init-functions Index: bootscripts/lfs/sbin/ifup =================================================================== --- bootscripts/lfs/sbin/ifup (revision 9920) +++ bootscripts/lfs/sbin/ifup (working copy) @@ -81,11 +81,24 @@ . $file -if [ "$IFACE" = "" ]; then - log_failure_msg2 "${file} does not define an interface [IFACE]." +if ! dereference_network_device "$1" ; then + log_failure_msg "${1} could not be found." exit 1 fi +IFACE="${real_device}" + +real_components="" +for identifier in ${INTERFACE_COMPONENTS} ; do + if ! dereference_network_device "${identifier}" ; then + log_failure_msg "${identifier} (component ID for ${1}) could not be found." + exit 1 + fi + real_components="${real_components} ${real_device}" +done + +INTERFACE_COMPONENTS="${real_components}" + # Do not process this service if started by boot, and ONBOOT # is not set to yes if [ "${IN_BOOT}" = "1" -a "${ONBOOT}" != "yes" ]; then Index: bootscripts/lfs/sbin/ifdown =================================================================== --- bootscripts/lfs/sbin/ifdown (revision 9920) +++ bootscripts/lfs/sbin/ifdown (working copy) @@ -62,11 +62,24 @@ . ${file} -if [ "$IFACE" = "" ]; then - log_failure_msg "${file} does not define an interface [IFACE]." +if ! dereference_network_device "$1" ; then + log_failure_msg "${1} could not be found." exit 1 fi +IFACE="${real_device}" + +real_components="" +for identifier in ${INTERFACE_COMPONENTS} ; do + if ! dereference_network_device "${identifier}" ; then + log_failure_msg "${identifier} (component ID for ${1}) could not be found." + exit 1 + fi + real_components="${real_components} ${real_device}" +done + +INTERFACE_COMPONENTS="${real_components}" + # We only need to first service to bring down the interface S=`echo ${SERVICE} | cut -f1 -d" "` Index: bootscripts/lfs/sbin/ifup.8 =================================================================== --- bootscripts/lfs/sbin/ifup.8 (revision 9920) +++ bootscripts/lfs/sbin/ifup.8 (working copy) @@ -34,19 +34,36 @@ /etc/sysconfig/ifconfig.eth0 ONBOOT=no - IFACE=eth0 SERVICE=ipv4-static IP=192.168.1.22 GATEWAY=192.168.1.1 PREFIX=24 BROADCAST=192.168.1.255 + ifup mac-XX:XX:XX:XX:XX:XX + Bring up the interface defined in the file + /etc/sysconfig/ifconfig.mac-XX:XX:XX:XX:XX:XX, + and handle its interface name changing from one + ifup run to the next by asking udev to look up + the MAC address. + + ONBOOT=no + SERVICE=ipv4-static + IP=192.168.1.22 + GATEWAY=192.168.1.1 + PREFIX=24 + BROADCAST=192.168.1.255 + + ifup path-pci-0000:00:13.1-usb-0:2.1:1.1 + Same as above, but find the real interface name + by looking at the udev ID_PATH value instead of + the interface's MAC address. + ifdown eth0:2 Bring down the interface defined in the file /etc/sysconfig/ifconfig.eth0:2 ONBOOT=no - IFACE=eth0:2 SERVICE=dhcpcd DHCP_START="--waitip" @@ -64,14 +81,13 @@ /etc/sysconfig/ifconfig.br0 ONBOOT=yes - IFACE=br0 SERVICE="bridge ipv4-static" IP=192.168.1.22 GATEWAY=192.168.1.1 PREFIX=24 BROADCAST=192.168.1.255 STP=no # Spanning tree protocol, default no - INTERFACE_COMPONENTS=eth0 # Add to IFACE + INTERFACE_COMPONENTS=eth0 # Add these to the current interface IP_FORWARD=true NOTES @@ -79,12 +95,15 @@ ly. It runs scripts defined by the SERVICE variable in the network configuration file. + The program will handle network devices moving around from + run to run, if the first argument is a mac-* or path-* + persistent identifier rather than an interface name. These + persistent identifiers are dereferenced each time ifup or + ifdown runs, by querying the udev database. + The configuration files must have the following environ- ment variables set: - IFACE - The interface to configure, e.g. eth0. It must - be available in /sys/class/net. - SERVICE - The service script to run to bring up the inter- face. Standard services are ipv4-static and ipv4-static-route. Other services such as dhcp @@ -104,7 +123,10 @@ INTERFACE_COMPONENTS - A list of component interfaces only needed for a compound device such as a bridge. This list is normally a single value, e.g. eth0, - for use with a virtual host such as kvm. + for use with a virtual host such as kvm. The + entries in this list may be either interface names + or persistent identifiers; the latter are + dereferenced at runtime as needed. Other paramters that are service specific include:
signature.asc
Description: OpenPGP digital signature
-- http://linuxfromscratch.org/mailman/listinfo/lfs-dev FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page