Skip to content

Commit 84d406c

Browse files
committed
[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>
1 parent a82f937 commit 84d406c

File tree

12 files changed

+97
-21
lines changed

12 files changed

+97
-21
lines changed

src/arch/x86/interface/pcbios/int13.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1507,6 +1507,7 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
15071507
* Attempt to boot from an INT 13 drive
15081508
*
15091509
* @v drive Drive number
1510+
* @v filename Filename (or NULL to use default)
15101511
* @ret rc Return status code
15111512
*
15121513
* This boots from the specified INT 13 drive by loading the Master
@@ -1516,7 +1517,7 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) {
15161517
*
15171518
* Note that this function can never return success, by definition.
15181519
*/
1519-
static int int13_boot ( unsigned int drive ) {
1520+
static int int13_boot ( unsigned int drive, const char *filename __unused ) {
15201521
struct memory_map memmap;
15211522
struct segoff address;
15221523
int rc;

src/core/dummy_sanboot.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,11 @@ static void dummy_san_unhook ( unsigned int drive ) {
9595
* Boot from dummy SAN device
9696
*
9797
* @v drive Drive number
98+
* @v filename Filename (or NULL to use default)
99+
* @ret rc Return status code
98100
*/
99-
static int dummy_san_boot ( unsigned int drive __unused ) {
101+
static int dummy_san_boot ( unsigned int drive __unused,
102+
const char *filename __unused ) {
100103

101104
return -EOPNOTSUPP;
102105
}

src/core/null_sanboot.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ static void null_san_unhook ( unsigned int drive __unused ) {
3737
/* Do nothing */
3838
}
3939

40-
static int null_san_boot ( unsigned int drive __unused ) {
40+
static int null_san_boot ( unsigned int drive __unused,
41+
const char *filename __unused ) {
4142
return -EOPNOTSUPP;
4243
}
4344

src/core/settings.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2396,6 +2396,15 @@ const struct setting root_path_setting __setting ( SETTING_SANBOOT, root-path)={
23962396
.type = &setting_type_string,
23972397
};
23982398

2399+
/** SAN filename setting */
2400+
const struct setting san_filename_setting __setting ( SETTING_SANBOOT,
2401+
san-filename ) = {
2402+
.name = "san-filename",
2403+
.description = "SAN filename",
2404+
.tag = DHCP_EB_SAN_FILENAME,
2405+
.type = &setting_type_string,
2406+
};
2407+
23992408
/** Username setting */
24002409
const struct setting username_setting __setting ( SETTING_AUTH, username ) = {
24012410
.name = "username",

src/hci/commands/sanboot_cmd.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ struct sanboot_options {
4747
int no_describe;
4848
/** Keep SAN device */
4949
int keep;
50+
/** Filename */
51+
char *filename;
5052
};
5153

5254
/** "sanboot" option list */
5355
static union {
54-
/* "sanboot" takes all three options */
55-
struct option_descriptor sanboot[3];
56+
/* "sanboot" takes all four options */
57+
struct option_descriptor sanboot[4];
5658
/* "sanhook" takes only --drive and --no-describe */
5759
struct option_descriptor sanhook[2];
5860
/* "sanunhook" takes only --drive */
@@ -65,6 +67,8 @@ static union {
6567
struct sanboot_options, no_describe, parse_flag ),
6668
OPTION_DESC ( "keep", 'k', no_argument,
6769
struct sanboot_options, keep, parse_flag ),
70+
OPTION_DESC ( "filename", 'f', required_argument,
71+
struct sanboot_options, filename, parse_string ),
6872
},
6973
};
7074

@@ -130,7 +134,8 @@ static int sanboot_core_exec ( int argc, char **argv,
130134
flags |= no_root_path_flags;
131135

132136
/* Boot from root path */
133-
if ( ( rc = uriboot ( NULL, uris, count, opts.drive, flags ) ) != 0 )
137+
if ( ( rc = uriboot ( NULL, uris, count, opts.drive, opts.filename,
138+
flags ) ) != 0 )
134139
goto err_uriboot;
135140

136141
err_uriboot:

src/include/ipxe/dhcp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,12 @@ struct dhcp_netdev_desc {
440440
*/
441441
#define DHCP_EB_SAN_RETRY DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbb )
442442

443+
/** SAN filename
444+
*
445+
* This is the path of the bootloader within the SAN device.
446+
*/
447+
#define DHCP_EB_SAN_FILENAME DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xbc )
448+
443449
/** SAN drive number
444450
*
445451
* This is the drive number for a SAN-hooked drive. For BIOS, 0x80 is

src/include/ipxe/sanboot.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,10 @@ void san_unhook ( unsigned int drive );
155155
* Attempt to boot from a SAN device
156156
*
157157
* @v drive Drive number
158+
* @v filename Filename (or NULL to use default)
158159
* @ret rc Return status code
159160
*/
160-
int san_boot ( unsigned int drive );
161+
int san_boot ( unsigned int drive, const char *filename );
161162

162163
/**
163164
* Describe SAN devices for SAN-booted operating system

src/include/ipxe/settings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ filename_setting __setting ( SETTING_BOOT, filename );
452452
extern const struct setting
453453
root_path_setting __setting ( SETTING_SANBOOT, root-path );
454454
extern const struct setting
455+
san_filename_setting __setting ( SETTING_SANBOOT, san-filename );
456+
extern const struct setting
455457
username_setting __setting ( SETTING_AUTH, username );
456458
extern const struct setting
457459
password_setting __setting ( SETTING_AUTH, password );

src/include/usr/autoboot.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern void set_autoboot_ll_addr ( const void *ll_addr, size_t len );
3232

3333
extern int uriboot ( struct uri *filename, struct uri **root_paths,
3434
unsigned int root_path_count, int drive,
35-
unsigned int flags );
35+
const char *san_filename, unsigned int flags );
3636
extern struct uri *
3737
fetch_next_server_and_filename ( struct settings *settings );
3838
extern int netboot ( struct net_device *netdev );

src/interface/efi/efi_block.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,12 @@ static int efi_block_describe ( void ) {
518518
*
519519
* @v sandev SAN device
520520
* @v handle EFI handle
521+
* @v filename Filename (or NULL to use default)
522+
* @v image Image handle to fill in
521523
* @ret rc Return status code
522524
*/
523525
static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
524-
EFI_HANDLE *image ) {
526+
const char *filename, EFI_HANDLE *image ) {
525527
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
526528
struct efi_block_data *block = sandev->priv;
527529
union {
@@ -563,7 +565,10 @@ static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
563565
end = efi_devpath_end ( path.path );
564566
prefix_len = ( ( ( void * ) end ) - ( ( void * ) path.path ) );
565567
filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
566-
sizeof ( efi_block_boot_filename ) );
568+
( filename ?
569+
( ( strlen ( filename ) + 1 /* NUL */ ) *
570+
sizeof ( filepath->PathName[0] ) ) :
571+
sizeof ( efi_block_boot_filename ) ) );
567572
boot_path_len = ( prefix_len + filepath_len + sizeof ( *end ) );
568573
boot_path = zalloc ( boot_path_len );
569574
if ( ! boot_path ) {
@@ -576,8 +581,12 @@ static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
576581
filepath->Header.SubType = MEDIA_FILEPATH_DP;
577582
filepath->Header.Length[0] = ( filepath_len & 0xff );
578583
filepath->Header.Length[1] = ( filepath_len >> 8 );
579-
memcpy ( filepath->PathName, efi_block_boot_filename,
580-
sizeof ( efi_block_boot_filename ) );
584+
if ( filename ) {
585+
efi_sprintf ( filepath->PathName, "%s", filename );
586+
} else {
587+
memcpy ( filepath->PathName, efi_block_boot_filename,
588+
sizeof ( efi_block_boot_filename ) );
589+
}
581590
end = ( ( ( void * ) filepath ) + filepath_len );
582591
end->Type = END_DEVICE_PATH_TYPE;
583592
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
@@ -609,9 +618,10 @@ static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
609618
* Boot from EFI block device
610619
*
611620
* @v drive Drive number
621+
* @v filename Filename (or NULL to use default)
612622
* @ret rc Return status code
613623
*/
614-
static int efi_block_boot ( unsigned int drive ) {
624+
static int efi_block_boot ( unsigned int drive, const char *filename ) {
615625
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
616626
struct san_device *sandev;
617627
EFI_HANDLE *handles;
@@ -649,7 +659,7 @@ static int efi_block_boot ( unsigned int drive ) {
649659
*/
650660
rc = -ENOENT;
651661
for ( i = 0 ; i < count ; i++ ) {
652-
if ( ( rc = efi_block_boot_image ( sandev, handles[i],
662+
if ( ( rc = efi_block_boot_image ( sandev, handles[i], filename,
653663
&image ) ) != 0 )
654664
continue;
655665
DBGC ( sandev, "EFIBLK %#02x found boot image\n",

0 commit comments

Comments
 (0)