iPXE
Defines | Enumerations | Functions
autoboot.h File Reference

Automatic booting. More...

#include <ipxe/device.h>

Go to the source code of this file.

Defines

#define URIBOOT_NO_SAN

Enumerations

enum  uriboot_flags { URIBOOT_NO_SAN_DESCRIBE = 0x0001, URIBOOT_NO_SAN_BOOT = 0x0002, URIBOOT_NO_SAN_UNHOOK = 0x0004 }
 uriboot() flags More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
void set_autoboot_busloc (unsigned int bus_type, unsigned int location)
 Identify autoboot device by bus type and location.
void set_autoboot_ll_addr (const void *ll_addr, size_t len)
 Identify autoboot device by link-layer address.
int uriboot (struct uri *filename, struct uri **root_paths, unsigned int root_path_count, int drive, const char *san_filename, unsigned int flags)
 Boot from filename and root-path URIs.
struct urifetch_next_server_and_filename (struct settings *settings)
 Fetch next-server and filename settings into a URI.
int netboot (struct net_device *netdev)
 Boot from a network device.
int ipxe (struct net_device *netdev)
 Main iPXE flow of execution.
int pxe_menu_boot (struct net_device *netdev)
 Boot using PXE boot menu.

Detailed Description

Automatic booting.

Definition in file autoboot.h.


Define Documentation

#define URIBOOT_NO_SAN
Value:
( URIBOOT_NO_SAN_DESCRIBE | \
                         URIBOOT_NO_SAN_BOOT |     \
                         URIBOOT_NO_SAN_UNHOOK )

Definition at line 25 of file autoboot.h.

Referenced by netboot(), and pxe_menu_boot().


Enumeration Type Documentation

uriboot() flags

Enumerator:
URIBOOT_NO_SAN_DESCRIBE 
URIBOOT_NO_SAN_BOOT 
URIBOOT_NO_SAN_UNHOOK 

Definition at line 19 of file autoboot.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
void set_autoboot_busloc ( unsigned int  bus_type,
unsigned int  location 
)

Identify autoboot device by bus type and location.

Parameters:
bus_typeBus type
locationLocation

Definition at line 478 of file autoboot.c.

References autoboot_desc, device_description::bus_type, is_autoboot_busloc(), is_autoboot_device, and device_description::location.

Referenced by pci_autoboot_init().

                                                                          {

        /* Record autoboot device description */
        autoboot_desc.bus_type = bus_type;
        autoboot_desc.location = location;

        /* Mark autoboot device as present */
        is_autoboot_device = is_autoboot_busloc;
}
void set_autoboot_ll_addr ( const void *  ll_addr,
size_t  len 
)

Identify autoboot device by link-layer address.

Parameters:
ll_addrLink-layer address
lenLength of link-layer address

Definition at line 506 of file autoboot.c.

References autoboot_ll_addr, is_autoboot_device, is_autoboot_ll_addr(), and memcpy().

Referenced by efi_set_autoboot().

                                                              {

        /* Record autoboot link-layer address (truncated if necessary) */
        if ( len > sizeof ( autoboot_ll_addr ) )
                len = sizeof ( autoboot_ll_addr );
        memcpy ( autoboot_ll_addr, ll_addr, len );

        /* Mark autoboot device as present */
        is_autoboot_device = is_autoboot_ll_addr;
}
int uriboot ( struct uri filename,
struct uri **  root_paths,
unsigned int  root_path_count,
int  drive,
const char *  san_filename,
unsigned int  flags 
)

Boot from filename and root-path URIs.

Parameters:
filenameFilename
root_pathsRoot path(s)
root_path_countNumber of root paths
driveSAN drive (if applicable)
san_filenameSAN filename (or NULL to use default)
flagsBoot action flags
Return values:
rcReturn status code

The somewhat tortuous flow of control in this function exists in order to ensure that the "sanboot" command remains identical in function to a SAN boot via a DHCP-specified root path, and to provide backwards compatibility for the "keep-san" and "skip-san-boot" options.

Definition at line 125 of file autoboot.c.

References drive, fetch_intz_setting(), image::flags, IMAGE_AUTO_UNREGISTER, image_exec(), imgdownload(), imgstat(), NULL, printf(), rc, san_boot(), san_describe(), san_hook(), SAN_NO_DESCRIBE, san_unhook(), strerror(), URIBOOT_NO_SAN_BOOT, URIBOOT_NO_SAN_DESCRIBE, and URIBOOT_NO_SAN_UNHOOK.

Referenced by netboot(), pxe_menu_boot(), and sanboot_core_exec().

                                                             {
        struct image *image;
        int rc;

        /* Hook SAN device, if applicable */
        if ( root_path_count ) {
                drive = san_hook ( drive, root_paths, root_path_count,
                                   ( ( flags & URIBOOT_NO_SAN_DESCRIBE ) ?
                                     SAN_NO_DESCRIBE : 0 ) );
                if ( drive < 0 ) {
                        rc = drive;
                        printf ( "Could not open SAN device: %s\n",
                                 strerror ( rc ) );
                        goto err_san_hook;
                }
                printf ( "Registered SAN device %#02x\n", drive );
        }

        /* Describe SAN device, if applicable */
        if ( ! ( flags & URIBOOT_NO_SAN_DESCRIBE ) ) {
                if ( ( rc = san_describe() ) != 0 ) {
                        printf ( "Could not describe SAN devices: %s\n",
                                 strerror ( rc ) );
                        goto err_san_describe;
                }
        }

        /* Allow a root-path-only boot with skip-san enabled to succeed */
        rc = 0;

        /* Attempt filename boot if applicable */
        if ( filename ) {
                if ( ( rc = imgdownload ( filename, 0, &image ) ) != 0 )
                        goto err_download;
                imgstat ( image );
                image->flags |= IMAGE_AUTO_UNREGISTER;
                if ( ( rc = image_exec ( image ) ) != 0 ) {
                        printf ( "Could not boot image: %s\n",
                                 strerror ( rc ) );
                        /* Fall through to (possibly) attempt a SAN boot
                         * as a fallback.  If no SAN boot is attempted,
                         * our status will become the return status.
                         */
                } else {
                        /* Always print an extra newline, because we
                         * don't know where the NBP may have left the
                         * cursor.
                         */
                        printf ( "\n" );
                }
        }

        /* Attempt SAN boot if applicable */
        if ( ! ( flags & URIBOOT_NO_SAN_BOOT ) ) {
                if ( fetch_intz_setting ( NULL, &skip_san_boot_setting) == 0 ) {
                        printf ( "Booting%s%s from SAN device %#02x\n",
                                 ( san_filename ? " " : "" ),
                                 ( san_filename ? san_filename : "" ), drive );
                        rc = san_boot ( drive, san_filename );
                        printf ( "Boot from SAN device %#02x failed: %s\n",
                                 drive, strerror ( rc ) );
                } else {
                        printf ( "Skipping boot from SAN device %#02x\n",
                                 drive );
                        /* Avoid overwriting a possible failure status
                         * from a filename boot.
                         */
                }
        }

 err_download:
 err_san_describe:
        /* Unhook SAN device, if applicable */
        if ( ! ( flags & URIBOOT_NO_SAN_UNHOOK ) ) {
                if ( fetch_intz_setting ( NULL, &keep_san_setting ) == 0 ) {
                        san_unhook ( drive );
                        printf ( "Unregistered SAN device %#02x\n", drive );
                } else {
                        printf ( "Preserving SAN device %#02x\n", drive );
                }
        }
 err_san_hook:
        return rc;
}
struct uri* fetch_next_server_and_filename ( struct settings settings) [read]

Fetch next-server and filename settings into a URI.

Parameters:
settingsSettings block
Return values:
uriURI, or NULL on failure

Definition at line 234 of file autoboot.c.

References AF_INET, expand_settings(), fetch_ipv4_setting(), fetch_setting(), fetch_string_setting_copy(), free, inet_ntoa(), memset(), NULL, printf(), and pxe_uri().

Referenced by netboot(), and pxe_menu_boot().

                                                                          {
        union {
                struct sockaddr sa;
                struct sockaddr_in sin;
        } next_server;
        char *raw_filename = NULL;
        struct uri *uri = NULL;
        char *filename;

        /* Initialise server address */
        memset ( &next_server, 0, sizeof ( next_server ) );

        /* If we have a filename, fetch it along with the next-server
         * setting from the same settings block.
         */
        if ( fetch_setting ( settings, &filename_setting, &settings,
                             NULL, NULL, 0 ) >= 0 ) {
                fetch_string_setting_copy ( settings, &filename_setting,
                                            &raw_filename );
                fetch_ipv4_setting ( settings, &next_server_setting,
                                     &next_server.sin.sin_addr );
        }
        if ( ! raw_filename )
                goto err_fetch;

        /* Populate server address */
        if ( next_server.sin.sin_addr.s_addr ) {
                next_server.sin.sin_family = AF_INET;
                printf ( "Next server: %s\n",
                         inet_ntoa ( next_server.sin.sin_addr ) );
        }

        /* Expand filename setting */
        filename = expand_settings ( raw_filename );
        if ( ! filename )
                goto err_expand;
        if ( filename[0] )
                printf ( "Filename: %s\n", filename );

        /* Construct URI */
        uri = pxe_uri ( &next_server.sa, filename );
        if ( ! uri )
                goto err_parse;

 err_parse:
        free ( filename );
 err_expand:
        free ( raw_filename );
 err_fetch:
        return uri;
}
int netboot ( struct net_device netdev)

Boot from a network device.

Parameters:
netdevNetwork device
Return values:
rcReturn status code

Definition at line 384 of file autoboot.c.

References close_all_netdevs(), ENOENT_BOOT, fetch_next_server_and_filename(), fetch_root_path(), fetch_san_filename(), free, have_pxe_menu(), ifconf(), ifopen(), ifstat(), NULL, printf(), pxe_menu_boot(), rc, route(), san_default_drive(), uri::scheme, strerror(), uri_is_absolute(), uri_put(), uriboot(), URIBOOT_NO_SAN, and xfer_uri_opener().

Referenced by autoboot(), autoboot_payload(), and ipxe().

                                          {
        struct uri *filename;
        struct uri *root_path;
        char *san_filename;
        int rc;

        /* Close all other network devices */
        close_all_netdevs();

        /* Open device and display device status */
        if ( ( rc = ifopen ( netdev ) ) != 0 )
                goto err_ifopen;
        ifstat ( netdev );

        /* Configure device */
        if ( ( rc = ifconf ( netdev, NULL ) ) != 0 )
                goto err_dhcp;
        route();

        /* Try PXE menu boot, if applicable */
        if ( have_pxe_menu() ) {
                printf ( "Booting from PXE menu\n" );
                rc = pxe_menu_boot ( netdev );
                goto err_pxe_menu_boot;
        }

        /* Fetch next server and filename (if any) */
        filename = fetch_next_server_and_filename ( NULL );

        /* Fetch root path (if any) */
        root_path = fetch_root_path ( NULL );

        /* Fetch SAN filename (if any) */
        san_filename = fetch_san_filename ( NULL );

        /* If we have both a filename and a root path, ignore an
         * unsupported or missing URI scheme in the root path, since
         * it may represent an NFS root.
         */
        if ( filename && root_path &&
             ( ( ! uri_is_absolute ( root_path ) ) ||
               ( xfer_uri_opener ( root_path->scheme ) == NULL ) ) ) {
                printf ( "Ignoring unsupported root path\n" );
                uri_put ( root_path );
                root_path = NULL;
        }

        /* Check that we have something to boot */
        if ( ! ( filename || root_path ) ) {
                rc = -ENOENT_BOOT;
                printf ( "Nothing to boot: %s\n", strerror ( rc ) );
                goto err_no_boot;
        }

        /* Boot using next server, filename and root path */
        if ( ( rc = uriboot ( filename, &root_path, ( root_path ? 1 : 0 ),
                              san_default_drive(), san_filename,
                              ( root_path ? 0 : URIBOOT_NO_SAN ) ) ) != 0 )
                goto err_uriboot;

 err_uriboot:
 err_no_boot:
        free ( san_filename );
        uri_put ( root_path );
        uri_put ( filename );
 err_pxe_menu_boot:
 err_dhcp:
 err_ifopen:
        return rc;
}
int ipxe ( struct net_device netdev)

Main iPXE flow of execution.

Parameters:
netdevNetwork device, or NULL
Return values:
rcReturn status code

Definition at line 567 of file autoboot.c.

References autoboot(), BOLD, CYAN, feature, FEATURES, fetch_string_setting_copy(), first_image(), for_each_table_entry, free, image_exec(), feature::name, netboot(), NORMAL, NULL, printf(), PRODUCT_NAME, PRODUCT_SHORT_NAME, PRODUCT_TAG_LINE, PRODUCT_URI, product_version, rc, shell(), shell_banner(), and system.

Referenced by efi_snp_load_file(), and main().

                                       {
        struct feature *feature;
        struct image *image;
        char *scriptlet;
        int rc;

        /*
         * Print welcome banner
         *
         *
         * If you wish to brand this build of iPXE, please do so by
         * defining the string PRODUCT_NAME in config/branding.h.
         *
         * While nothing in the GPL prevents you from removing all
         * references to iPXE or http://ipxe.org, we prefer you not to
         * do so.
         *
         */
        printf ( NORMAL "\n\n" PRODUCT_NAME "\n" BOLD PRODUCT_SHORT_NAME " %s"
                 NORMAL " -- " PRODUCT_TAG_LINE " -- "
                 CYAN PRODUCT_URI NORMAL "\nFeatures:", product_version );
        for_each_table_entry ( feature, FEATURES )
                printf ( " %s", feature->name );
        printf ( "\n" );

        /* Boot system */
        if ( ( image = first_image() ) != NULL ) {
                /* We have an embedded image; execute it */
                return image_exec ( image );
        } else if ( shell_banner() ) {
                /* User wants shell; just give them a shell */
                return shell();
        } else {
                fetch_string_setting_copy ( NULL, &scriptlet_setting,
                                            &scriptlet );
                if ( scriptlet ) {
                        /* User has defined a scriptlet; execute it */
                        rc = system ( scriptlet );
                        free ( scriptlet );
                        return rc;
                } else {
                        /* Try booting.  If booting fails, offer the
                         * user another chance to enter the shell.
                         */
                        if ( netdev ) {
                                rc = netboot ( netdev );
                        } else {
                                rc = autoboot();
                        }
                        if ( shell_banner() )
                                rc = shell();
                        return rc;
                }
        }
}
int pxe_menu_boot ( struct net_device netdev)

Boot using PXE boot menu.

Return values:
rcReturn status code

Note that a success return status indicates that a PXE boot menu item has been selected, and that the DHCP session should perform a boot server request/ack.

Definition at line 344 of file pxemenu.c.

References assert, ENOMEM, fetch_next_server_and_filename(), find_settings(), free, pxe_menu::items, NULL, pxe_menu_parse(), pxe_menu_prompt_and_select(), pxebs(), PXEBS_SETTINGS_NAME, rc, pxe_menu::selection, pxe_menu_item::type, uri_put(), uriboot(), and URIBOOT_NO_SAN.

                                                {
        struct pxe_menu *menu;
        unsigned int pxe_type;
        struct settings *pxebs_settings;
        struct uri *uri;
        int rc;

        /* Parse and allocate boot menu */
        if ( ( rc = pxe_menu_parse ( &menu ) ) != 0 )
                return rc;

        /* Make selection from boot menu */
        if ( ( rc = pxe_menu_prompt_and_select ( menu ) ) != 0 ) {
                free ( menu );
                return rc;
        }
        pxe_type = menu->items[menu->selection].type;

        /* Free boot menu */
        free ( menu );

        /* Return immediately if local boot selected */
        if ( ! pxe_type )
                return 0;

        /* Attempt PXE Boot Server Discovery */
        if ( ( rc = pxebs ( netdev, pxe_type ) ) != 0 )
                return rc;

        /* Fetch next server and filename */
        pxebs_settings = find_settings ( PXEBS_SETTINGS_NAME );
        assert ( pxebs_settings );
        uri = fetch_next_server_and_filename ( pxebs_settings );
        if ( ! uri )
                return -ENOMEM;

        /* Attempt boot */
        rc = uriboot ( uri, NULL, 0, 0, NULL, URIBOOT_NO_SAN );
        uri_put ( uri );
        return rc;
}