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:
 

Attachment: 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

Reply via email to