diff --git a/src/core/main.c b/src/core/main.c index 97394d71..638dea9c 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @ret rc Return status code */ __asmcall int main ( void ) { + int rc; /* Perform one-time-only initialisation (e.g. heap) */ initialise(); @@ -35,9 +36,11 @@ __asmcall int main ( void ) { startup(); printf ( "ok\n" ); - ipxe ( NULL ); + /* Attempt to boot */ + if ( ( rc = ipxe ( NULL ) ) != 0 ) + goto err_ipxe; + err_ipxe: shutdown_exit(); - - return 0; + return rc; } diff --git a/src/include/usr/autoboot.h b/src/include/usr/autoboot.h index c0603a0a..4db226b9 100644 --- a/src/include/usr/autoboot.h +++ b/src/include/usr/autoboot.h @@ -35,7 +35,7 @@ extern int uriboot ( struct uri *filename, struct uri *root_path, int drive, extern struct uri * fetch_next_server_and_filename ( struct settings *settings ); extern int netboot ( struct net_device *netdev ); -extern void ipxe ( struct net_device *netdev ); +extern int ipxe ( struct net_device *netdev ); extern int pxe_menu_boot ( struct net_device *netdev ); diff --git a/src/interface/efi/efi_snp.c b/src/interface/efi/efi_snp.c index 1b21c40c..3dfcc5e1 100644 --- a/src/interface/efi/efi_snp.c +++ b/src/interface/efi/efi_snp.c @@ -871,6 +871,7 @@ efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file, struct efi_snp_device *snpdev = container_of ( load_file, struct efi_snp_device, load_file ); struct net_device *netdev = snpdev->netdev; + int rc; /* Fail unless this is a boot attempt */ if ( ! booting ) { @@ -886,16 +887,13 @@ efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file, efi_watchdog_start(); /* Boot from network device */ - ipxe ( netdev ); + if ( ( rc = ipxe ( netdev ) ) != 0 ) + goto err_ipxe; - /* Stop watchdog holdoff timer */ + err_ipxe: efi_watchdog_stop(); - - /* Release network devices for use via SNP */ efi_snp_release(); - - /* Assume boot process was aborted */ - return EFI_ABORTED; + return EFIRC ( rc ); } /** Load file protocol */ diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c index ccafeae7..6dbe25ca 100644 --- a/src/usr/autoboot.c +++ b/src/usr/autoboot.c @@ -542,11 +542,13 @@ static int shell_banner ( void ) { * Main iPXE flow of execution * * @v netdev Network device, or NULL + * @ret rc Return status code */ -void ipxe ( struct net_device *netdev ) { +int ipxe ( struct net_device *netdev ) { struct feature *feature; struct image *image; char *scriptlet; + int rc; /* * Print welcome banner @@ -570,28 +572,30 @@ void ipxe ( struct net_device *netdev ) { /* Boot system */ if ( ( image = first_image() ) != NULL ) { /* We have an embedded image; execute it */ - image_exec ( image ); + return image_exec ( image ); } else if ( shell_banner() ) { /* User wants shell; just give them a shell */ - shell(); + return shell(); } else { fetch_string_setting_copy ( NULL, &scriptlet_setting, &scriptlet ); if ( scriptlet ) { /* User has defined a scriptlet; execute it */ - system ( scriptlet ); + rc = system ( scriptlet ); free ( scriptlet ); + return rc; } else { /* Try booting. If booting fails, offer the * user another chance to enter the shell. */ if ( netdev ) { - netboot ( netdev ); + rc = netboot ( netdev ); } else { - autoboot(); + rc = autoboot(); } if ( shell_banner() ) - shell(); + rc = shell(); + return rc; } } }