mirror of https://github.com/ipxe/ipxe.git
[block] Allow SAN boot device to be identified by filesystem label
Add a "--label" option that can be used to specify a filesystem label, to be matched against the FAT volume label. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/1174/head
parent
62b6d36335
commit
24a855f1fc
|
@ -51,6 +51,8 @@ struct sanboot_options {
|
|||
char *filename;
|
||||
/** Required extra filename */
|
||||
char *extra;
|
||||
/** Volume label */
|
||||
char *label;
|
||||
/** UUID */
|
||||
struct uuid_option uuid;
|
||||
};
|
||||
|
@ -58,7 +60,7 @@ struct sanboot_options {
|
|||
/** "sanboot" option list */
|
||||
static union {
|
||||
/* "sanboot" takes all options */
|
||||
struct option_descriptor sanboot[6];
|
||||
struct option_descriptor sanboot[7];
|
||||
/* "sanhook" takes only --drive and --no-describe */
|
||||
struct option_descriptor sanhook[2];
|
||||
/* "sanunhook" takes only --drive */
|
||||
|
@ -75,6 +77,8 @@ static union {
|
|||
struct sanboot_options, filename, parse_string ),
|
||||
OPTION_DESC ( "extra", 'e', required_argument,
|
||||
struct sanboot_options, extra, parse_string ),
|
||||
OPTION_DESC ( "label", 'l', required_argument,
|
||||
struct sanboot_options, label, parse_string ),
|
||||
OPTION_DESC ( "uuid", 'u', required_argument,
|
||||
struct sanboot_options, uuid, parse_uuid ),
|
||||
},
|
||||
|
@ -135,6 +139,7 @@ static int sanboot_core_exec ( int argc, char **argv,
|
|||
/* Construct configuration parameters */
|
||||
config.filename = opts.filename;
|
||||
config.extra = opts.extra;
|
||||
config.label = opts.label;
|
||||
config.uuid = opts.uuid.value;
|
||||
|
||||
/* Construct flags */
|
||||
|
|
|
@ -112,6 +112,8 @@ struct san_boot_config {
|
|||
const char *filename;
|
||||
/** Required extra filename (or NULL to ignore) */
|
||||
const char *extra;
|
||||
/** Filesystem label (or NULL to ignore volume label) */
|
||||
const char *label;
|
||||
/** UUID (or NULL to ignore UUID) */
|
||||
union uuid *uuid;
|
||||
};
|
||||
|
|
|
@ -32,7 +32,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/refcnt.h>
|
||||
#include <ipxe/list.h>
|
||||
|
@ -51,6 +53,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/efi/Protocol/BlockIo.h>
|
||||
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
|
||||
#include <ipxe/efi/Protocol/AcpiTable.h>
|
||||
#include <ipxe/efi/Guid/FileSystemInfo.h>
|
||||
#include <ipxe/efi/efi_driver.h>
|
||||
#include <ipxe/efi/efi_strings.h>
|
||||
#include <ipxe/efi/efi_snp.h>
|
||||
|
@ -595,6 +598,68 @@ static int efi_block_filename ( unsigned int drive, EFI_HANDLE handle,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for EFI block device filesystem label
|
||||
*
|
||||
* @v drive Drive number
|
||||
* @v root Root directory
|
||||
* @v label Volume label
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int efi_block_label ( unsigned int drive, EFI_FILE_PROTOCOL *root,
|
||||
const char *label ) {
|
||||
EFI_FILE_SYSTEM_INFO *info;
|
||||
UINTN size;
|
||||
char *actual;
|
||||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
||||
/* Get length of file system information */
|
||||
size = 0;
|
||||
root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
|
||||
|
||||
/* Allocate file system information */
|
||||
info = malloc ( size );
|
||||
if ( ! info ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_info;
|
||||
}
|
||||
|
||||
/* Get file system information */
|
||||
if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
|
||||
info ) ) != 0 ) {
|
||||
rc = -EEFI ( efirc );
|
||||
DBGC ( drive, "EFIBLK %#02x could not get filesystem info: "
|
||||
"%s\n", drive, strerror ( rc ) );
|
||||
goto err_get_info;
|
||||
}
|
||||
|
||||
/* Construct volume label for comparison */
|
||||
if ( asprintf ( &actual, "%ls", info->VolumeLabel ) < 0 ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_label;
|
||||
}
|
||||
|
||||
/* Compare volume label */
|
||||
if ( strcasecmp ( label, actual ) != 0 ) {
|
||||
DBGC ( drive, "EFIBLK %#02x has wrong label \"%s\"\n",
|
||||
drive, actual );
|
||||
rc = -ENOENT;
|
||||
goto err_compare;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
rc = 0;
|
||||
|
||||
err_compare:
|
||||
free ( actual );
|
||||
err_alloc_label:
|
||||
err_get_info:
|
||||
free ( info );
|
||||
err_alloc_info:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check EFI block device filesystem match
|
||||
*
|
||||
|
@ -675,9 +740,17 @@ static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
|
|||
goto err_extra;
|
||||
}
|
||||
|
||||
/* Check volume label, if applicable */
|
||||
if ( config->label &&
|
||||
( ( rc = efi_block_label ( drive, root,
|
||||
config->label ) ) != 0 ) ) {
|
||||
goto err_label;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
rc = 0;
|
||||
|
||||
err_label:
|
||||
err_extra:
|
||||
err_filename:
|
||||
root->Close ( root );
|
||||
|
|
Loading…
Reference in New Issue