mirror of https://github.com/ipxe/ipxe.git
[block] Allow SAN boot device to be identified by UUID
Add a "--uuid" option which may be used to specify a boot device UUID, to be matched against the GPT partition GUID. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/1174/head
parent
c4471e3408
commit
cea22d76e4
|
@ -129,20 +129,21 @@ int parse_timeout ( char *text, unsigned long *value ) {
|
||||||
* Parse UUID
|
* Parse UUID
|
||||||
*
|
*
|
||||||
* @v text Text
|
* @v text Text
|
||||||
* @ret value UUID value
|
* @ret uuid UUID value
|
||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int parse_uuid ( char *text, union uuid *value ) {
|
int parse_uuid ( char *text, struct uuid_option *uuid ) {
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
assert ( text != NULL );
|
assert ( text != NULL );
|
||||||
|
|
||||||
/* Parse UUID */
|
/* Parse UUID */
|
||||||
if ( ( rc = uuid_aton ( text, value ) ) != 0 ) {
|
if ( ( rc = uuid_aton ( text, &uuid->buf ) ) != 0 ) {
|
||||||
printf ( "\"%s\": invalid UUID\n", text );
|
printf ( "\"%s\": invalid UUID\n", text );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
uuid->value = &uuid->buf;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,14 @@ struct sanboot_options {
|
||||||
int keep;
|
int keep;
|
||||||
/** Filename */
|
/** Filename */
|
||||||
char *filename;
|
char *filename;
|
||||||
|
/** UUID */
|
||||||
|
struct uuid_option uuid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** "sanboot" option list */
|
/** "sanboot" option list */
|
||||||
static union {
|
static union {
|
||||||
/* "sanboot" takes all four options */
|
/* "sanboot" takes all options */
|
||||||
struct option_descriptor sanboot[4];
|
struct option_descriptor sanboot[5];
|
||||||
/* "sanhook" takes only --drive and --no-describe */
|
/* "sanhook" takes only --drive and --no-describe */
|
||||||
struct option_descriptor sanhook[2];
|
struct option_descriptor sanhook[2];
|
||||||
/* "sanunhook" takes only --drive */
|
/* "sanunhook" takes only --drive */
|
||||||
|
@ -69,10 +71,11 @@ static union {
|
||||||
struct sanboot_options, keep, parse_flag ),
|
struct sanboot_options, keep, parse_flag ),
|
||||||
OPTION_DESC ( "filename", 'f', required_argument,
|
OPTION_DESC ( "filename", 'f', required_argument,
|
||||||
struct sanboot_options, filename, parse_string ),
|
struct sanboot_options, filename, parse_string ),
|
||||||
|
OPTION_DESC ( "uuid", 'u', required_argument,
|
||||||
|
struct sanboot_options, uuid, parse_uuid ),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** "sanhook" command descriptor */
|
/** "sanhook" command descriptor */
|
||||||
static struct command_descriptor sanhook_cmd =
|
static struct command_descriptor sanhook_cmd =
|
||||||
COMMAND_DESC ( struct sanboot_options, opts.sanhook, 1, MAX_ARGUMENTS,
|
COMMAND_DESC ( struct sanboot_options, opts.sanhook, 1, MAX_ARGUMENTS,
|
||||||
|
@ -127,6 +130,7 @@ static int sanboot_core_exec ( int argc, char **argv,
|
||||||
|
|
||||||
/* Construct configuration parameters */
|
/* Construct configuration parameters */
|
||||||
config.filename = opts.filename;
|
config.filename = opts.filename;
|
||||||
|
config.uuid = opts.uuid.value;
|
||||||
|
|
||||||
/* Construct flags */
|
/* Construct flags */
|
||||||
flags = default_flags;
|
flags = default_flags;
|
||||||
|
|
|
@ -126,10 +126,18 @@ struct named_setting {
|
||||||
struct setting setting;
|
struct setting setting;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** A UUID command-line option */
|
||||||
|
struct uuid_option {
|
||||||
|
/** UUID */
|
||||||
|
union uuid *value;
|
||||||
|
/** Storage buffer */
|
||||||
|
union uuid buf;
|
||||||
|
};
|
||||||
|
|
||||||
extern int parse_string ( char *text, char **value );
|
extern int parse_string ( char *text, char **value );
|
||||||
extern int parse_integer ( char *text, unsigned int *value );
|
extern int parse_integer ( char *text, unsigned int *value );
|
||||||
extern int parse_timeout ( char *text, unsigned long *value );
|
extern int parse_timeout ( char *text, unsigned long *value );
|
||||||
extern int parse_uuid ( char *text, union uuid *value );
|
extern int parse_uuid ( char *text, struct uuid_option *uuid );
|
||||||
extern int parse_netdev ( char *text, struct net_device **netdev );
|
extern int parse_netdev ( char *text, struct net_device **netdev );
|
||||||
extern int
|
extern int
|
||||||
parse_netdev_configurator ( char *text,
|
parse_netdev_configurator ( char *text,
|
||||||
|
|
|
@ -19,6 +19,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
#include <ipxe/process.h>
|
#include <ipxe/process.h>
|
||||||
#include <ipxe/blockdev.h>
|
#include <ipxe/blockdev.h>
|
||||||
#include <ipxe/acpi.h>
|
#include <ipxe/acpi.h>
|
||||||
|
#include <ipxe/uuid.h>
|
||||||
#include <config/sanboot.h>
|
#include <config/sanboot.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -109,6 +110,8 @@ enum san_device_flags {
|
||||||
struct san_boot_config {
|
struct san_boot_config {
|
||||||
/** Boot filename (or NULL to use default) */
|
/** Boot filename (or NULL to use default) */
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
/** UUID (or NULL to ignore UUID) */
|
||||||
|
union uuid *uuid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -597,6 +597,7 @@ static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
|
||||||
EFI_DEVICE_PATH_PROTOCOL *path;
|
EFI_DEVICE_PATH_PROTOCOL *path;
|
||||||
void *interface;
|
void *interface;
|
||||||
} u;
|
} u;
|
||||||
|
union uuid guid;
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -623,6 +624,21 @@ static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
|
||||||
DBGC ( drive, "EFIBLK %#02x contains filesystem %s\n",
|
DBGC ( drive, "EFIBLK %#02x contains filesystem %s\n",
|
||||||
drive, efi_devpath_text ( u.path ) );
|
drive, efi_devpath_text ( u.path ) );
|
||||||
|
|
||||||
|
/* Check if filesystem matches GUID, if applicable */
|
||||||
|
if ( config->uuid ) {
|
||||||
|
if ( ( rc = efi_path_guid ( u.path, &guid ) ) != 0 ) {
|
||||||
|
DBGC ( drive, "EFIBLK %#02x could not determine GUID: "
|
||||||
|
"%s\n", drive, strerror ( rc ) );
|
||||||
|
goto err_no_guid;
|
||||||
|
}
|
||||||
|
if ( memcmp ( config->uuid, &guid, sizeof ( guid ) ) != 0 ) {
|
||||||
|
DBGC ( drive, "EFIBLK %#02x has wrong GUID %s\n",
|
||||||
|
drive, uuid_ntoa ( &guid ) );
|
||||||
|
rc = -ENOENT;
|
||||||
|
goto err_wrong_guid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if filesystem contains boot filename */
|
/* Check if filesystem contains boot filename */
|
||||||
if ( ( rc = efi_block_filename ( drive, handle,
|
if ( ( rc = efi_block_filename ( drive, handle,
|
||||||
config->filename ) ) != 0 ) {
|
config->filename ) ) != 0 ) {
|
||||||
|
@ -633,6 +649,8 @@ static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
|
||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
err_filename:
|
err_filename:
|
||||||
|
err_wrong_guid:
|
||||||
|
err_no_guid:
|
||||||
err_not_child:
|
err_not_child:
|
||||||
bs->CloseProtocol ( handle, protocol, efi_image_handle, handle );
|
bs->CloseProtocol ( handle, protocol, efi_image_handle, handle );
|
||||||
err_open:
|
err_open:
|
||||||
|
|
Loading…
Reference in New Issue