#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_device * | find_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. | |
Definition in file autoboot.c.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static struct net_device* find_boot_netdev | ( | void | ) | [static, read] |
Identify the boot network device.
| 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.
| filename | Boot filename |
| 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.
| root_path | Root path |
| 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.
| netdev | Network device |
| 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 }
| int shutdown_exit_flags = 0 |
Shutdown flags for exit.
Definition at line 43 of file autoboot.c.
Referenced by keep_san(), and main().
1.5.7.1