autoboot.c File Reference

Automatic booting. More...

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <gpxe/netdevice.h>
#include <gpxe/dhcp.h>
#include <gpxe/settings.h>
#include <gpxe/image.h>
#include <gpxe/sanboot.h>
#include <gpxe/uri.h>
#include <usr/ifmgmt.h>
#include <usr/route.h>
#include <usr/dhcpmgmt.h>
#include <usr/imgmgmt.h>
#include <usr/autoboot.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static struct net_devicefind_boot_netdev (void)
 Identify the boot network device.
int boot_next_server_and_filename (struct in_addr next_server, const char *filename)
 Boot using next-server and filename.
int boot_root_path (const char *root_path)
 Boot using root path.
static int netboot (struct net_device *netdev)
 Boot from a network device.
static void close_all_netdevs (void)
 Close all open net devices.
void autoboot (void)
 Boot the system.

Variables

int shutdown_exit_flags = 0
 Shutdown flags for exit.


Detailed Description

Automatic booting.

Definition in file autoboot.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static struct net_device* find_boot_netdev ( void   )  [static, read]

Identify the boot network device.

Return values:
netdev Boot network device

Definition at line 50 of file autoboot.c.

References NULL.

Referenced by autoboot().

00050                                                      {
00051         return NULL;
00052 }

int boot_next_server_and_filename ( struct in_addr  next_server,
const char *  filename 
)

Boot using next-server and filename.

Parameters:
filename Boot filename
Return values:
rc Return status code

Definition at line 60 of file autoboot.c.

References alloc_image(), ENOMEM, image_put(), imgexec(), imgfetch(), inet_ntoa(), parse_uri(), register_and_autoload_image(), snprintf(), strlen(), uri_encode(), uri_is_absolute(), and URI_PATH.

Referenced by netboot(), and pxe_menu_boot().

00061                                                            {
00062         struct uri *uri;
00063         struct image *image;
00064         char buf[ 23 /* tftp://xxx.xxx.xxx.xxx/ */ +
00065                   ( 3 * strlen(filename) ) /* completely URI-encoded */
00066                   + 1 /* NUL */ ];
00067         int filename_is_absolute;
00068         int rc;
00069 
00070         /* Construct URI */
00071         uri = parse_uri ( filename );
00072         if ( ! uri )
00073                 return -ENOMEM;
00074         filename_is_absolute = uri_is_absolute ( uri );
00075         uri_put ( uri );
00076         if ( ! filename_is_absolute ) {
00077                 /* Construct a tftp:// URI for the filename.  We can't
00078                  * just rely on the current working URI, because the
00079                  * relative URI resolution will remove the distinction
00080                  * between filenames with and without initial slashes,
00081                  * which is significant for TFTP.
00082                  */
00083                 snprintf ( buf, sizeof ( buf ), "tftp://%s/",
00084                            inet_ntoa ( next_server ) );
00085                 uri_encode ( filename, buf + strlen ( buf ),
00086                              sizeof ( buf ) - strlen ( buf ), URI_PATH );
00087                 filename = buf;
00088         }
00089 
00090         image = alloc_image();
00091         if ( ! image )
00092                 return -ENOMEM;
00093         if ( ( rc = imgfetch ( image, filename,
00094                                register_and_autoload_image ) ) != 0 ) {
00095                 goto done;
00096         }
00097         if ( ( rc = imgexec ( image ) ) != 0 )
00098                 goto done;
00099 
00100  done:
00101         image_put ( image );
00102         return rc;
00103 }

int boot_root_path ( const char *  root_path  ) 

Boot using root path.

Parameters:
root_path Root path
Return values:
rc Return status code

Definition at line 111 of file autoboot.c.

References sanboot_protocol::boot, ENOTSUP, for_each_table_entry, sanboot_protocol::prefix, SANBOOT_PROTOCOLS, strlen(), and strncmp().

Referenced by netboot(), and sanboot_exec().

00111                                              {
00112         struct sanboot_protocol *sanboot;
00113 
00114         /* Quick hack */
00115         for_each_table_entry ( sanboot, SANBOOT_PROTOCOLS ) {
00116                 if ( strncmp ( root_path, sanboot->prefix,
00117                                strlen ( sanboot->prefix ) ) == 0 ) {
00118                         return sanboot->boot ( root_path );
00119                 }
00120         }
00121 
00122         return -ENOTSUP;
00123 }

static int netboot ( struct net_device netdev  )  [static]

Boot from a network device.

Parameters:
netdev Network device
Return values:
rc Return status code

Definition at line 131 of file autoboot.c.

References boot_next_server_and_filename(), boot_root_path(), dhcp(), DHCP_PXE_BOOT_MENU, DHCP_PXE_DISCOVERY_CONTROL, DHCP_VENDOR_CLASS_ID, ENOENT, fetch_ipv4_setting(), fetch_string_setting(), fetch_uintz_setting(), ifopen(), ifstat(), NULL, printf(), pxe_menu_boot(), PXEBS_SKIP, route(), setting_exists(), strcmp(), strerror(), and setting::tag.

Referenced by autoboot().

00131                                                  {
00132         struct setting vendor_class_id_setting
00133                 = { .tag = DHCP_VENDOR_CLASS_ID };
00134         struct setting pxe_discovery_control_setting
00135                 = { .tag = DHCP_PXE_DISCOVERY_CONTROL };
00136         struct setting pxe_boot_menu_setting
00137                 = { .tag = DHCP_PXE_BOOT_MENU };
00138         char buf[256];
00139         struct in_addr next_server;
00140         unsigned int pxe_discovery_control;
00141         int rc;
00142 
00143         /* Open device and display device status */
00144         if ( ( rc = ifopen ( netdev ) ) != 0 )
00145                 return rc;
00146         ifstat ( netdev );
00147 
00148         /* Configure device via DHCP */
00149         if ( ( rc = dhcp ( netdev ) ) != 0 )
00150                 return rc;
00151         route();
00152 
00153         /* Try PXE menu boot, if applicable */
00154         fetch_string_setting ( NULL, &vendor_class_id_setting,
00155                                buf, sizeof ( buf ) );
00156         pxe_discovery_control =
00157                 fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
00158         if ( ( strcmp ( buf, "PXEClient" ) == 0 ) && pxe_menu_boot != NULL &&
00159              setting_exists ( NULL, &pxe_boot_menu_setting ) &&
00160              ( ! ( ( pxe_discovery_control & PXEBS_SKIP ) &&
00161                    setting_exists ( NULL, &filename_setting ) ) ) ) {
00162                 printf ( "Booting from PXE menu\n" );
00163                 return pxe_menu_boot ( netdev );
00164         }
00165 
00166         /* Try to download and boot whatever we are given as a filename */
00167         fetch_ipv4_setting ( NULL, &next_server_setting, &next_server );
00168         fetch_string_setting ( NULL, &filename_setting, buf, sizeof ( buf ) );
00169         if ( buf[0] ) {
00170                 printf ( "Booting from filename \"%s\"\n", buf );
00171                 if ( ( rc = boot_next_server_and_filename ( next_server,
00172                                                             buf ) ) != 0 ) {
00173                         printf ( "Could not boot from filename \"%s\": %s\n",
00174                                  buf, strerror ( rc ) );
00175                         return rc;
00176                 }
00177                 return 0;
00178         }
00179         
00180         /* No filename; try the root path */
00181         fetch_string_setting ( NULL, &root_path_setting, buf, sizeof ( buf ) );
00182         if ( buf[0] ) {
00183                 printf ( "Booting from root path \"%s\"\n", buf );
00184                 if ( ( rc = boot_root_path ( buf ) ) != 0 ) {
00185                         printf ( "Could not boot from root path \"%s\": %s\n",
00186                                  buf, strerror ( rc ) );
00187                         return rc;
00188                 }
00189                 return 0;
00190         }
00191 
00192         printf ( "No filename or root path specified\n" );
00193         return -ENOENT;
00194 }

static void close_all_netdevs ( void   )  [static]

Close all open net devices.

Called before a fresh boot attempt in order to free up memory. We don't just close the device immediately after the boot fails, because there may still be TCP connections in the process of closing.

Definition at line 204 of file autoboot.c.

References for_each_netdev, ifclose(), and netdev.

Referenced by autoboot().

00204                                        {
00205         struct net_device *netdev;
00206 
00207         for_each_netdev ( netdev ) {
00208                 ifclose ( netdev );
00209         }
00210 }

void autoboot ( void   ) 

Boot the system.

Definition at line 215 of file autoboot.c.

References close_all_netdevs(), find_boot_netdev(), for_each_netdev, netboot(), netdev, and printf().

Referenced by autoboot_exec(), and main().

00215                        {
00216         struct net_device *boot_netdev;
00217         struct net_device *netdev;
00218 
00219         /* If we have an identifable boot device, try that first */
00220         close_all_netdevs();
00221         if ( ( boot_netdev = find_boot_netdev() ) )
00222                 netboot ( boot_netdev );
00223 
00224         /* If that fails, try booting from any of the other devices */
00225         for_each_netdev ( netdev ) {
00226                 if ( netdev == boot_netdev )
00227                         continue;
00228                 close_all_netdevs();
00229                 netboot ( netdev );
00230         }
00231 
00232         printf ( "No more network devices\n" );
00233 }


Variable Documentation

Shutdown flags for exit.

Definition at line 43 of file autoboot.c.

Referenced by keep_san(), and main().


Generated on Tue Apr 6 20:01:57 2010 for gPXE by  doxygen 1.5.7.1