]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[autoboot] Enable infrastructure to specify an autoboot device location
authorAlex Williamson <alex.williamson@redhat.com>
Tue, 25 Feb 2014 23:00:23 +0000 (16:00 -0700)
committerMichael Brown <mcb30@ipxe.org>
Mon, 3 Mar 2014 15:11:03 +0000 (15:11 +0000)
iPXE will currently attempt to boot from every network device for
which it has a driver.  Where a system has more than one network
device supported by iPXE, this renders BIOS IPL lists ineffective.

Allow an autoboot device location to be specified.  If such a location
is specified, then only devices matching that location will be used as
part of the automatic boot sequence.  If no such location is
specified, then all devices will be used.

Note that this does not affect the "autoboot" command, which will
continue to use all devices.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/usr/autoboot.h
src/usr/autoboot.c

index cfa4c41eb290cba36486f9505216314a16b94251..f562b2b12f2aae66af4e479ccb8940c3f4d2b5ed 100644 (file)
@@ -10,6 +10,7 @@
 FILE_LICENCE ( GPL2_OR_LATER );
 
 #include <ipxe/in.h>
+#include <ipxe/device.h>
 struct net_device;
 struct uri;
 struct settings;
@@ -25,12 +26,13 @@ enum uriboot_flags {
                         URIBOOT_NO_SAN_BOOT |     \
                         URIBOOT_NO_SAN_UNHOOK )
 
+extern struct device_description autoboot_device;
+
 extern int uriboot ( struct uri *filename, struct uri *root_path, int drive,
                     unsigned int flags );
 extern struct uri *
 fetch_next_server_and_filename ( struct settings *settings );
 extern int netboot ( struct net_device *netdev );
-extern int autoboot ( void );
 extern void ipxe ( struct net_device *netdev );
 
 extern int pxe_menu_boot ( struct net_device *netdev );
index 3a5fb046c6df07bdae390fe13d645605c1b6f18e..c9012f21d59c2db79dfdd3131259259514c658e0 100644 (file)
@@ -49,6 +49,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
  *
  */
 
+/** Device location of preferred autoboot device */
+struct device_description autoboot_device;
+
 /* Disambiguate the various error causes */
 #define ENOENT_BOOT __einfo_error ( EINFO_ENOENT_BOOT )
 #define EINFO_ENOENT_BOOT \
@@ -73,15 +76,6 @@ __weak int pxe_menu_boot ( struct net_device *netdev __unused ) {
        return -ENOTSUP;
 }
 
-/**
- * Identify the boot network device
- *
- * @ret netdev         Boot network device
- */
-static struct net_device * find_boot_netdev ( void ) {
-       return NULL;
-}
-
 /**
  * Parse next-server and filename into a URI
  *
@@ -427,22 +421,37 @@ int netboot ( struct net_device *netdev ) {
        return rc;
 }
 
+/**
+ * Test if network device matches the autoboot device location
+ *
+ * @v netdev           Network device
+ * @ret is_autoboot    Network device matches the autoboot device location
+ */
+static int is_autoboot_device ( struct net_device *netdev ) {
+
+       return ( ( netdev->dev->desc.bus_type == autoboot_device.bus_type ) &&
+                ( netdev->dev->desc.location == autoboot_device.location ) );
+}
+
 /**
  * Boot the system
  */
-int autoboot ( void ) {
-       struct net_device *boot_netdev;
+static int autoboot ( void ) {
        struct net_device *netdev;
        int rc = -ENODEV;
 
-       /* If we have an identifable boot device, try that first */
-       if ( ( boot_netdev = find_boot_netdev() ) )
-               rc = netboot ( boot_netdev );
-
-       /* If that fails, try booting from any of the other devices */
+       /* Try booting from each network device.  If we have a
+        * specified autoboot device location, then use only devices
+        * matching that location.
+        */
        for_each_netdev ( netdev ) {
-               if ( netdev == boot_netdev )
+
+               /* Skip any non-matching devices, if applicable */
+               if ( autoboot_device.bus_type &&
+                    ( ! is_autoboot_device ( netdev ) ) )
                        continue;
+
+               /* Attempt booting from this device */
                rc = netboot ( netdev );
        }