mirror of
https://github.com/ipxe/ipxe
synced 2026-01-28 20:12:28 +03:00
[block] Allow use of a non-default EFI SAN boot filename
Some older operating systems (e.g. RHEL6) use a non-default filename
on the root disk and rely on setting an EFI variable to point to the
bootloader. This does not work when performing a SAN boot on a
machine where the EFI variable is not present.
Fix by allowing a non-default filename to be specified via the
"sanboot --filename" option or the "san-filename" setting. For
example:
sanboot --filename \efi\redhat\grub.efi \
iscsi:192.168.0.1::::iqn.2010-04.org.ipxe.demo:rhel6
or
option ipxe.san-filename code 188 = string;
option ipxe.san-filename "\\efi\\redhat\\grub.efi";
option root-path "iscsi:192.168.0.1::::iqn.2010-04.org.ipxe.demo:rhel6";
Originally-implemented-by: Vishvananda Ishaya Abrams <vish.ishaya@oracle.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -112,6 +112,7 @@ const struct setting skip_san_boot_setting __setting ( SETTING_SANBOOT_EXTRA,
|
||||
* @v root_paths Root path(s)
|
||||
* @v root_path_count Number of root paths
|
||||
* @v drive SAN drive (if applicable)
|
||||
* @v san_filename SAN filename (or NULL to use default)
|
||||
* @v flags Boot action flags
|
||||
* @ret rc Return status code
|
||||
*
|
||||
@@ -122,7 +123,8 @@ const struct setting skip_san_boot_setting __setting ( SETTING_SANBOOT_EXTRA,
|
||||
* "skip-san-boot" options.
|
||||
*/
|
||||
int uriboot ( struct uri *filename, struct uri **root_paths,
|
||||
unsigned int root_path_count, int drive, unsigned int flags ) {
|
||||
unsigned int root_path_count, int drive,
|
||||
const char *san_filename, unsigned int flags ) {
|
||||
struct image *image;
|
||||
int rc;
|
||||
|
||||
@@ -177,8 +179,10 @@ int uriboot ( struct uri *filename, struct uri **root_paths,
|
||||
/* Attempt SAN boot if applicable */
|
||||
if ( ! ( flags & URIBOOT_NO_SAN_BOOT ) ) {
|
||||
if ( fetch_intz_setting ( NULL, &skip_san_boot_setting) == 0 ) {
|
||||
printf ( "Booting from SAN device %#02x\n", drive );
|
||||
rc = san_boot ( drive );
|
||||
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 {
|
||||
@@ -300,10 +304,10 @@ static struct uri * fetch_root_path ( struct settings *settings ) {
|
||||
root_path = expand_settings ( raw_root_path );
|
||||
if ( ! root_path )
|
||||
goto err_expand;
|
||||
|
||||
/* Parse root path */
|
||||
if ( root_path[0] )
|
||||
printf ( "Root path: %s\n", root_path );
|
||||
|
||||
/* Parse root path */
|
||||
uri = parse_uri ( root_path );
|
||||
if ( ! uri )
|
||||
goto err_parse;
|
||||
@@ -316,6 +320,35 @@ static struct uri * fetch_root_path ( struct settings *settings ) {
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch san-filename setting
|
||||
*
|
||||
* @v settings Settings block
|
||||
* @ret san_filename SAN filename, or NULL on failure
|
||||
*/
|
||||
static char * fetch_san_filename ( struct settings *settings ) {
|
||||
char *raw_san_filename;
|
||||
char *san_filename = NULL;
|
||||
|
||||
/* Fetch san-filename setting */
|
||||
fetch_string_setting_copy ( settings, &san_filename_setting,
|
||||
&raw_san_filename );
|
||||
if ( ! raw_san_filename )
|
||||
goto err_fetch;
|
||||
|
||||
/* Expand san-filename setting */
|
||||
san_filename = expand_settings ( raw_san_filename );
|
||||
if ( ! san_filename )
|
||||
goto err_expand;
|
||||
if ( san_filename[0] )
|
||||
printf ( "SAN filename: %s\n", san_filename );
|
||||
|
||||
err_expand:
|
||||
free ( raw_san_filename );
|
||||
err_fetch:
|
||||
return san_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not we have a usable PXE menu
|
||||
*
|
||||
@@ -351,6 +384,7 @@ static int have_pxe_menu ( void ) {
|
||||
int netboot ( struct net_device *netdev ) {
|
||||
struct uri *filename;
|
||||
struct uri *root_path;
|
||||
char *san_filename;
|
||||
int rc;
|
||||
|
||||
/* Close all other network devices */
|
||||
@@ -379,6 +413,9 @@ int netboot ( struct net_device *netdev ) {
|
||||
/* 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.
|
||||
@@ -400,12 +437,13 @@ int netboot ( struct net_device *netdev ) {
|
||||
|
||||
/* Boot using next server, filename and root path */
|
||||
if ( ( rc = uriboot ( filename, &root_path, ( root_path ? 1 : 0 ),
|
||||
san_default_drive(),
|
||||
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:
|
||||
|
||||
@@ -378,7 +378,7 @@ int pxe_menu_boot ( struct net_device *netdev ) {
|
||||
return -ENOMEM;
|
||||
|
||||
/* Attempt boot */
|
||||
rc = uriboot ( uri, NULL, 0, 0, URIBOOT_NO_SAN );
|
||||
rc = uriboot ( uri, NULL, 0, 0, NULL, URIBOOT_NO_SAN );
|
||||
uri_put ( uri );
|
||||
return rc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user