Fix exclusivearch for aarch64
Resolves: rhbz#1016791
This commit is contained in:
parent
d055ba2ac2
commit
15ba15c289
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
efibootmgr-0.5.4.tar.gz
|
||||
clog
|
||||
*.rpm
|
||||
*.tar.*
|
||||
|
@ -1,28 +0,0 @@
|
||||
From 2d8f962284f40b918c0fc8385e58fcba219ddc12 Mon Sep 17 00:00:00 2001
|
||||
From: Fedora Ninjas <pjones@fedoraproject.org>
|
||||
Date: Wed, 28 Nov 2012 17:13:24 -0500
|
||||
Subject: [PATCH 2/5] Remove device path padding on non-Itanium
|
||||
|
||||
This code predates EFI support on any x86 hardware, and it's a strict
|
||||
violation of the specification. Windows doesn't do it either.
|
||||
---
|
||||
src/include/efi.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/include/efi.h b/src/include/efi.h
|
||||
index be667ae..c2ac853 100644
|
||||
--- a/src/include/efi.h
|
||||
+++ b/src/include/efi.h
|
||||
@@ -294,7 +294,9 @@ typedef struct {
|
||||
uint8_t signature[16];
|
||||
uint8_t mbr_type;
|
||||
uint8_t signature_type;
|
||||
+#ifdef __ia64
|
||||
uint8_t padding[6]; /* Emperically needed */
|
||||
+#endif
|
||||
} __attribute__((packed)) HARDDRIVE_DEVICE_PATH;
|
||||
|
||||
typedef struct {
|
||||
--
|
||||
1.8.0
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 6edc3ed5479b575f87eb51e335957b05fdd04fe8 Mon Sep 17 00:00:00 2001
|
||||
From: Fedora Ninjas <pjones@fedoraproject.org>
|
||||
Date: Wed, 28 Nov 2012 16:49:18 -0500
|
||||
Subject: [PATCH 1/5] Work around broken Apple firmware
|
||||
|
||||
Alex Murray found that Apple's firmware sets an invalid EFI attribute on
|
||||
BootCurrent, which newer versions of the kernel then reject. This patch
|
||||
from him simply masks off the extraneous bit.
|
||||
---
|
||||
src/lib/efivars_sysfs.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/lib/efivars_sysfs.c b/src/lib/efivars_sysfs.c
|
||||
index 182c70f..ea87325 100644
|
||||
--- a/src/lib/efivars_sysfs.c
|
||||
+++ b/src/lib/efivars_sysfs.c
|
||||
@@ -55,6 +55,10 @@ sysfs_read_variable(const char *name, efi_variable_t *var)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
close(fd);
|
||||
+ /* latest apple firmware sets high bit which appears invalid
|
||||
+ to the linux kernel if we write it back so lets zero it out
|
||||
+ if it is set since it would be invalid to set it anyway */
|
||||
+ var->Attributes = var->Attributes & ~(1 << 31);
|
||||
return var->Status;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.0
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 836e58668167e82c5ffcb66f3f390d2c52217f6a Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 14 Apr 2010 16:06:48 -0400
|
||||
Subject: [PATCH] Make \EFI\redhat\grub.efi the default bootloader (#579665)
|
||||
|
||||
Make \EFI\redhat\grub.efi the default bootloader instead of \elilo.efi .
|
||||
---
|
||||
src/efibootmgr/efibootmgr.c | 6 +++---
|
||||
1 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/efibootmgr/efibootmgr.c b/src/efibootmgr/efibootmgr.c
|
||||
index 5db0d9e..b984143 100644
|
||||
--- a/src/efibootmgr/efibootmgr.c
|
||||
+++ b/src/efibootmgr/efibootmgr.c
|
||||
@@ -18,7 +18,7 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
- This must tie the EFI_DEVICE_PATH to /boot/efi/elilo.efi
|
||||
+ This must tie the EFI_DEVICE_PATH to /boot/efi/EFI/redhat/grub.efi
|
||||
The EFI_DEVICE_PATH will look something like:
|
||||
ACPI device path, length 12 bytes
|
||||
Hardware Device Path, PCI, length 6 bytes
|
||||
@@ -779,7 +779,7 @@ usage()
|
||||
printf("\t-g | --gpt force disk with invalid PMBR to be treated as GPT\n");
|
||||
printf("\t-H | --acpi_hid XXXX set the ACPI HID (used with -i)\n");
|
||||
printf("\t-i | --iface name create a netboot entry for the named interface\n");
|
||||
- printf("\t-l | --loader name (defaults to \\elilo.efi)\n");
|
||||
+ printf("\t-l | --loader name (defaults to \\EFI\\redhat\\grub.efi)\n");
|
||||
printf("\t-L | --label label Boot manager display label (defaults to \"Linux\")\n");
|
||||
printf("\t-n | --bootnext XXXX set BootNext to XXXX (hex)\n");
|
||||
printf("\t-N | --delete-bootnext delete BootNext\n");
|
||||
@@ -807,7 +807,7 @@ set_default_opts()
|
||||
opts.active = -1; /* Don't set it */
|
||||
opts.timeout = -1; /* Don't set it */
|
||||
opts.edd10_devicenum = 0x80;
|
||||
- opts.loader = "\\elilo.efi";
|
||||
+ opts.loader = "\\EFI\\redhat\\grub.efi";
|
||||
opts.label = "Linux";
|
||||
opts.disk = "/dev/sda";
|
||||
opts.iface = NULL;
|
||||
--
|
||||
1.7.0.1
|
||||
|
@ -1,620 +0,0 @@
|
||||
diff -up efibootmgr-0.5.4/src/lib/efi.c.driver efibootmgr-0.5.4/src/lib/efi.c
|
||||
--- efibootmgr-0.5.4/src/lib/efi.c.driver 2008-03-06 15:45:17.000000000 -0500
|
||||
+++ efibootmgr-0.5.4/src/lib/efi.c 2008-03-06 15:49:54.000000000 -0500
|
||||
@@ -170,6 +170,26 @@ create_or_edit_variable(efi_variable_t *
|
||||
}
|
||||
|
||||
static int
|
||||
+select_driver_var_names(const struct dirent *d)
|
||||
+{
|
||||
+ if (!strncmp(d->d_name, "Driver", 6) &&
|
||||
+ isxdigit(d->d_name[6]) && isxdigit(d->d_name[7]) &&
|
||||
+ isxdigit(d->d_name[8]) && isxdigit(d->d_name[9]) &&
|
||||
+ d->d_name[10] == '-')
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+read_driver_var_names(struct dirent ***namelist)
|
||||
+{
|
||||
+ if (!fs_kernel_calls || !namelist) return -1;
|
||||
+ return scandir(fs_kernel_calls->path,
|
||||
+ namelist, select_driver_var_names,
|
||||
+ alphasort);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
select_boot_var_names(const struct dirent *d)
|
||||
{
|
||||
if (!strncmp(d->d_name, "Boot", 4) &&
|
||||
@@ -189,7 +209,6 @@ read_boot_var_names(struct dirent ***nam
|
||||
alphasort);
|
||||
}
|
||||
|
||||
-
|
||||
static int
|
||||
get_edd_version()
|
||||
{
|
||||
@@ -763,7 +782,7 @@ append_extra_args(void *data, unsigned l
|
||||
|
||||
int
|
||||
make_linux_efi_variable(efi_variable_t *var,
|
||||
- unsigned int free_number)
|
||||
+ unsigned int free_number, int driver)
|
||||
{
|
||||
efi_guid_t guid = EFI_GLOBAL_VARIABLE;
|
||||
char buffer[16];
|
||||
@@ -773,7 +792,7 @@ make_linux_efi_variable(efi_variable_t *
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
/* VariableName needs to be BootXXXX */
|
||||
- sprintf(buffer, "Boot%04X", free_number);
|
||||
+ sprintf(buffer, driver ? "Driver%04X" : "Boot%04X", free_number);
|
||||
|
||||
efichar_from_char(var->VariableName, buffer, 1024);
|
||||
|
||||
diff -up efibootmgr-0.5.4/src/include/efi.h.driver efibootmgr-0.5.4/src/include/efi.h
|
||||
--- efibootmgr-0.5.4/src/include/efi.h.driver 2008-03-06 15:48:38.000000000 -0500
|
||||
+++ efibootmgr-0.5.4/src/include/efi.h 2008-03-06 15:50:18.000000000 -0500
|
||||
@@ -352,7 +352,7 @@ struct efivar_kernel_calls {
|
||||
/* Exported functions */
|
||||
|
||||
extern int make_linux_efi_variable(efi_variable_t *var,
|
||||
- unsigned int free_number);
|
||||
+ unsigned int free_number, int driver);
|
||||
extern char * efi_guid_unparse(efi_guid_t *guid, char *out);
|
||||
extern EFI_DEVICE_PATH *load_option_path(EFI_LOAD_OPTION *option);
|
||||
|
||||
@@ -363,6 +363,7 @@ extern efi_status_t delete_variable(efi_
|
||||
extern efi_status_t create_or_edit_variable(efi_variable_t *var);
|
||||
|
||||
extern void set_fs_kernel_calls();
|
||||
+extern int read_driver_var_names(struct dirent ***namelist);
|
||||
extern int read_boot_var_names(struct dirent ***namelist);
|
||||
extern int variable_to_name(efi_variable_t *var, char *name);
|
||||
extern int var_name_to_path(const char *name, char *path);
|
||||
diff -up efibootmgr-0.5.4/src/include/efibootmgr.h.driver efibootmgr-0.5.4/src/include/efibootmgr.h
|
||||
--- efibootmgr-0.5.4/src/include/efibootmgr.h.driver 2008-03-06 16:21:55.000000000 -0500
|
||||
+++ efibootmgr-0.5.4/src/include/efibootmgr.h 2008-03-06 16:22:17.000000000 -0500
|
||||
@@ -52,6 +52,7 @@ typedef struct {
|
||||
unsigned int forcegpt:1;
|
||||
unsigned int set_timeout:1;
|
||||
unsigned int delete_timeout:1;
|
||||
+ unsigned int driver:1;
|
||||
unsigned short int timeout;
|
||||
} efibootmgr_opt_t;
|
||||
|
||||
diff -up efibootmgr-0.5.4/src/man/man8/efibootmgr.8.driver efibootmgr-0.5.4/src/man/man8/efibootmgr.8
|
||||
--- efibootmgr-0.5.4/src/man/man8/efibootmgr.8.driver 2008-03-06 15:44:32.000000000 -0500
|
||||
+++ efibootmgr-0.5.4/src/man/man8/efibootmgr.8 2008-03-06 17:03:55.000000000 -0500
|
||||
@@ -53,6 +53,9 @@ Create new variable bootnum and add to b
|
||||
The disk containing the loader (defaults to
|
||||
\fI/dev/sda\fR)
|
||||
.TP
|
||||
+\fB-D | --driver\fR
|
||||
+Operate on Driver#### and DriverOrder instead of Boot#### and BootOrder
|
||||
+.TP
|
||||
\fB-e | --edd \fI1|3|-1\fB\fR
|
||||
Force EDD 1.0 or 3.0 creation variables, or guess.
|
||||
.TP
|
||||
diff -up efibootmgr-0.5.4/src/efibootmgr/efibootmgr.c.driver efibootmgr-0.5.4/src/efibootmgr/efibootmgr.c
|
||||
--- efibootmgr-0.5.4/src/efibootmgr/efibootmgr.c.driver 2008-03-06 15:44:14.000000000 -0500
|
||||
+++ efibootmgr-0.5.4/src/efibootmgr/efibootmgr.c 2008-03-06 16:59:04.000000000 -0500
|
||||
@@ -65,6 +65,7 @@ typedef struct _var_entry {
|
||||
|
||||
|
||||
/* global variables */
|
||||
+static LIST_HEAD(driver_entry_list);
|
||||
static LIST_HEAD(boot_entry_list);
|
||||
static LIST_HEAD(blk_list);
|
||||
efibootmgr_opt_t opts;
|
||||
@@ -216,7 +217,7 @@ find_free_boot_var(list_t *boot_list)
|
||||
|
||||
|
||||
static void
|
||||
-warn_duplicate_name(list_t *boot_list)
|
||||
+warn_duplicate_name(list_t *boot_list, int driver)
|
||||
{
|
||||
list_t *pos;
|
||||
var_entry_t *boot;
|
||||
@@ -228,7 +229,9 @@ warn_duplicate_name(list_t *boot_list)
|
||||
boot->var_data.Data;
|
||||
if (!efichar_char_strcmp(opts.label,
|
||||
load_option->description)) {
|
||||
- fprintf(stderr, "** Warning ** : %.8s has same label %s\n",
|
||||
+ fprintf(stderr, driver
|
||||
+ ? "** Warning ** : %.10s has same label %s\n"
|
||||
+ : "** Warning ** : %.8s has same label %s\n",
|
||||
boot->name->d_name,
|
||||
opts.label);
|
||||
}
|
||||
@@ -237,7 +240,7 @@ warn_duplicate_name(list_t *boot_list)
|
||||
|
||||
|
||||
static var_entry_t *
|
||||
-make_boot_var(list_t *boot_list)
|
||||
+make_var(list_t *boot_list, int driver)
|
||||
{
|
||||
var_entry_t *boot;
|
||||
int free_number;
|
||||
@@ -267,7 +270,7 @@ make_boot_var(list_t *boot_list)
|
||||
if (!boot) return NULL;
|
||||
memset(boot, 0, sizeof(*boot));
|
||||
boot->num = free_number;
|
||||
- if (!make_linux_efi_variable(&boot->var_data, free_number)) {
|
||||
+ if (!make_linux_efi_variable(&boot->var_data, free_number, driver)) {
|
||||
free(boot);
|
||||
return NULL;
|
||||
}
|
||||
@@ -289,30 +292,30 @@ read_boot(efi_variable_t *var, const cha
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
-read_boot_order(efi_variable_t *boot_order)
|
||||
+read_order(efi_variable_t *boot_order, int driver)
|
||||
{
|
||||
efi_status_t status;
|
||||
|
||||
- status = read_boot(boot_order, "BootOrder");
|
||||
+ status = read_boot(boot_order, driver ? "DriverOrder" : "BootOrder");
|
||||
if (status != EFI_SUCCESS && status != EFI_NOT_FOUND)
|
||||
return status;
|
||||
|
||||
if (status == EFI_NOT_FOUND) {
|
||||
- fill_var(boot_order, "BootOrder");
|
||||
+ fill_var(boot_order, driver ? "DriverOrder" : "BootOrder");
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static efi_status_t
|
||||
-add_to_boot_order(uint16_t num)
|
||||
+add_to_order(uint16_t num, int driver)
|
||||
{
|
||||
efi_status_t status;
|
||||
efi_variable_t boot_order;
|
||||
uint64_t new_data_size;
|
||||
uint16_t *new_data, *old_data;
|
||||
|
||||
- status = read_boot_order(&boot_order);
|
||||
+ status = read_order(&boot_order, driver);
|
||||
if (status != EFI_SUCCESS) return status;
|
||||
|
||||
/* We've now got an array (in boot_order.Data) of the
|
||||
@@ -333,7 +336,7 @@ add_to_boot_order(uint16_t num)
|
||||
|
||||
|
||||
static efi_status_t
|
||||
-remove_from_boot_order(uint16_t num)
|
||||
+remove_from_order(uint16_t num, int driver)
|
||||
{
|
||||
efi_status_t status;
|
||||
efi_variable_t boot_order;
|
||||
@@ -342,13 +345,13 @@ remove_from_boot_order(uint16_t num)
|
||||
int old_i,new_i;
|
||||
char boot_order_name[PATH_MAX];
|
||||
|
||||
- status = read_boot_order(&boot_order);
|
||||
+ status = read_order(&boot_order, driver);
|
||||
if (status != EFI_SUCCESS) return status;
|
||||
/* If it's empty, yea! */
|
||||
if (!boot_order.DataSize) return EFI_SUCCESS;
|
||||
|
||||
fill_bootvar_name(boot_order_name, sizeof(boot_order_name),
|
||||
- "BootOrder");
|
||||
+ driver ? "DriverOrder" : "BootOrder");
|
||||
|
||||
/* We've now got an array (in boot_order.Data) of the
|
||||
boot order. Simply copy the array, skipping the
|
||||
@@ -415,7 +418,7 @@ set_boot_u16(const char *name, uint16_t
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
-delete_boot_var(uint16_t num)
|
||||
+delete_boot_var(uint16_t num, int driver)
|
||||
{
|
||||
efi_status_t status;
|
||||
efi_variable_t var;
|
||||
@@ -423,28 +426,33 @@ delete_boot_var(uint16_t num)
|
||||
list_t *pos, *n;
|
||||
var_entry_t *boot;
|
||||
|
||||
- snprintf(name, sizeof(name), "Boot%04X", num);
|
||||
+ snprintf(name, sizeof(name), driver ? "Driver%04X" : "Boot%04X", num);
|
||||
memset(&var, 0, sizeof(var));
|
||||
fill_var(&var, name);
|
||||
status = delete_variable(&var);
|
||||
|
||||
/* For backwards compatibility, try to delete abcdef entries as well */
|
||||
if (status) {
|
||||
- snprintf(name, sizeof(name), "Boot%04x", num);
|
||||
+ snprintf(name, sizeof(name), driver ? "Driver%04X" : "Boot%04x",
|
||||
+ num);
|
||||
memset(&var, 0, sizeof(var));
|
||||
fill_var(&var, name);
|
||||
status = delete_variable(&var);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
- fprintf (stderr,"\nboot entry: %X not found\n\n",num);
|
||||
+ fprintf (stderr,"\n%s entry: %X not found\n\n",
|
||||
+ driver ? "driver" : "boot", num);
|
||||
return status;
|
||||
}
|
||||
- list_for_each_safe(pos, n, &boot_entry_list) {
|
||||
+ list_for_each_safe(pos, n, driver ? &driver_entry_list
|
||||
+ : &boot_entry_list) {
|
||||
boot = list_entry(pos, var_entry_t, list);
|
||||
if (boot->num == num) {
|
||||
- status = remove_from_boot_order(num);
|
||||
- if (status) return status;
|
||||
+ if (!driver) {
|
||||
+ status = remove_from_order(num, driver);
|
||||
+ if (status) return status;
|
||||
+ }
|
||||
list_del(&(boot->list));
|
||||
break; /* short-circuit since it was found */
|
||||
}
|
||||
@@ -468,13 +476,28 @@ set_var_nums(const char *pattern, list_t
|
||||
if (rc == 1) {
|
||||
var->num = num;
|
||||
name = var->name->d_name; /* shorter name */
|
||||
- if ((isalpha(name[4]) && islower(name[4])) ||
|
||||
- (isalpha(name[5]) && islower(name[5])) ||
|
||||
- (isalpha(name[6]) && islower(name[6])) ||
|
||||
- (isalpha(name[7]) && islower(name[7]))) {
|
||||
- fprintf(stderr, "** Warning ** : %.8s is not "
|
||||
- "EFI 1.10 compliant (lowercase hex in name)\n", name);
|
||||
- warn++;
|
||||
+ if (!strncmp(name, "Boot", 4)) {
|
||||
+ if ((isalpha(name[4]) && islower(name[4])) ||
|
||||
+ (isalpha(name[5]) && islower(name[5])) ||
|
||||
+ (isalpha(name[6]) && islower(name[6])) ||
|
||||
+ (isalpha(name[7]) && islower(name[7]))) {
|
||||
+ fprintf(stderr, "** Warning ** : %.8s "
|
||||
+ "is not EFI 1.10 compliant "
|
||||
+ "(lowercase hex in name)\n",
|
||||
+ name);
|
||||
+ warn++;
|
||||
+ }
|
||||
+ } else if (!strncmp(name, "Driver", 6)) {
|
||||
+ if ((isalpha(name[6]) && islower(name[6])) ||
|
||||
+ (isalpha(name[7]) && islower(name[7])) ||
|
||||
+ (isalpha(name[8]) && islower(name[8])) ||
|
||||
+ (isalpha(name[9]) && islower(name[9]))) {
|
||||
+ fprintf(stderr, "** Warning ** : %.10s "
|
||||
+ "is not EFI 1.10 compliant "
|
||||
+ "(lowercase hex in name)\n",
|
||||
+ name);
|
||||
+ warn++;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -574,10 +597,10 @@ find_disk_blk(char *disk_name, list_t *b
|
||||
#endif
|
||||
|
||||
static void
|
||||
-unparse_boot_order(uint16_t *order, int length)
|
||||
+unparse_order(uint16_t *order, int length, int driver)
|
||||
{
|
||||
int i;
|
||||
- printf("BootOrder: ");
|
||||
+ printf("%s: ", driver ? "DriverOrder" : "BootOrder");
|
||||
for (i=0; i<length; i++) {
|
||||
printf("%04X", order[i]);
|
||||
if (i < (length-1))
|
||||
@@ -587,12 +610,12 @@ unparse_boot_order(uint16_t *order, int
|
||||
}
|
||||
|
||||
static int
|
||||
-is_current_boot_entry(int b)
|
||||
+is_current_entry(int b, int driver)
|
||||
{
|
||||
list_t *pos;
|
||||
var_entry_t *boot;
|
||||
|
||||
- list_for_each(pos, &boot_entry_list) {
|
||||
+ list_for_each(pos, driver ? &driver_entry_list : &boot_entry_list) {
|
||||
boot = list_entry(pos, var_entry_t, list);
|
||||
if (boot->num == b)
|
||||
return 1;
|
||||
@@ -602,7 +625,7 @@ is_current_boot_entry(int b)
|
||||
|
||||
|
||||
static int
|
||||
-parse_boot_order(char *buffer, uint16_t *order, int length)
|
||||
+parse_order(char *buffer, uint16_t *order, int length, int driver)
|
||||
{
|
||||
int i;
|
||||
int num, rc;
|
||||
@@ -611,12 +634,13 @@ parse_boot_order(char *buffer, uint16_t
|
||||
rc = sscanf(buffer, "%x", &num);
|
||||
if (rc == 1) order[i] = num & 0xFFFF;
|
||||
else {
|
||||
- fprintf(stderr,"\nInvalid hex characters in boot order: %s\n\n",buffer);
|
||||
+ fprintf(stderr,"\nInvalid hex characters in %s order: %s\n\n",buffer, driver ? "driver" : "boot");
|
||||
return -1;
|
||||
}
|
||||
/* make sure this is an existing boot entry */
|
||||
- if (!is_current_boot_entry(order[i])) {
|
||||
- fprintf (stderr,"\nboot entry %X does not exist\n\n",order[i]);
|
||||
+ if (!is_current_entry(order[i], driver)) {
|
||||
+ fprintf (stderr,"\n%s entry %X does not exist\n\n",
|
||||
+ driver ? "driver" : "boot", order[i]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -629,7 +653,7 @@ parse_boot_order(char *buffer, uint16_t
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
-set_boot_order()
|
||||
+set_order(int driver)
|
||||
{
|
||||
efi_variable_t boot_order;
|
||||
uint16_t *n = (uint16_t *)boot_order.Data;
|
||||
@@ -637,9 +661,9 @@ set_boot_order()
|
||||
if (!opts.bootorder) return EFI_SUCCESS;
|
||||
|
||||
memset(&boot_order, 0, sizeof(boot_order));
|
||||
- fill_var(&boot_order, "BootOrder");
|
||||
+ fill_var(&boot_order, driver ? "DriverOrder" : "BootOrder");
|
||||
|
||||
- boot_order.DataSize = parse_boot_order(opts.bootorder, n, 1024/sizeof(uint16_t)) * sizeof(uint16_t);
|
||||
+ boot_order.DataSize = parse_order(opts.bootorder, n, 1024/sizeof(uint16_t), driver) * sizeof(uint16_t);
|
||||
if (boot_order.DataSize < 0)
|
||||
return 1;
|
||||
else
|
||||
@@ -647,7 +671,7 @@ set_boot_order()
|
||||
}
|
||||
|
||||
static void
|
||||
-show_boot_vars()
|
||||
+show_vars(list_t *list)
|
||||
{
|
||||
list_t *pos;
|
||||
var_entry_t *boot;
|
||||
@@ -657,7 +681,7 @@ show_boot_vars()
|
||||
char text_path[1024], *p;
|
||||
unsigned long optional_data_len=0;
|
||||
|
||||
- list_for_each(pos, &boot_entry_list) {
|
||||
+ list_for_each(pos, list) {
|
||||
boot = list_entry(pos, var_entry_t, list);
|
||||
load_option = (EFI_LOAD_OPTION *)
|
||||
boot->var_data.Data;
|
||||
@@ -665,10 +689,15 @@ show_boot_vars()
|
||||
load_option->description, sizeof(description));
|
||||
memset(text_path, 0, sizeof(text_path));
|
||||
path = load_option_path(load_option);
|
||||
- if (boot->name)
|
||||
- printf("%.8s", boot->name->d_name);
|
||||
- else
|
||||
- printf("Boot%04X", boot->num);
|
||||
+ if (boot->name) {
|
||||
+ if (boot->name->d_name[0] == 'B')
|
||||
+ printf("%.8s", boot->name->d_name);
|
||||
+ else
|
||||
+ printf("%.10s", boot->name->d_name);
|
||||
+ } else {
|
||||
+ printf(boot->name->d_name[0] == 'B' ?
|
||||
+ "Driver%04X" : "Boot%04X", boot->num);
|
||||
+ }
|
||||
|
||||
if (load_option->attributes & LOAD_OPTION_ACTIVE)
|
||||
printf("* ");
|
||||
@@ -700,16 +729,16 @@ show_boot_vars()
|
||||
|
||||
|
||||
static void
|
||||
-show_boot_order()
|
||||
+show_order(int driver)
|
||||
{
|
||||
efi_status_t status;
|
||||
efi_variable_t boot_order;
|
||||
uint16_t *data;
|
||||
|
||||
- status = read_boot_order(&boot_order);
|
||||
+ status = read_order(&boot_order, driver);
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
- perror("show_boot_order()");
|
||||
+ perror("show_order()");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -718,18 +747,19 @@ show_boot_order()
|
||||
*/
|
||||
data = (uint16_t *)&(boot_order.Data);
|
||||
if (boot_order.DataSize)
|
||||
- unparse_boot_order(data, boot_order.DataSize / sizeof(uint16_t));
|
||||
+ unparse_order(data, boot_order.DataSize / sizeof(uint16_t),
|
||||
+ driver);
|
||||
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
-set_active_state()
|
||||
+set_active_state(int driver)
|
||||
{
|
||||
list_t *pos;
|
||||
var_entry_t *boot;
|
||||
EFI_LOAD_OPTION *load_option;
|
||||
|
||||
- list_for_each(pos, &boot_entry_list) {
|
||||
+ list_for_each(pos, driver ? &driver_entry_list : &boot_entry_list) {
|
||||
boot = list_entry(pos, var_entry_t, list);
|
||||
load_option = (EFI_LOAD_OPTION *)
|
||||
boot->var_data.Data;
|
||||
@@ -756,7 +786,8 @@ set_active_state()
|
||||
}
|
||||
}
|
||||
/* if we reach here then the bootnumber supplied was not found */
|
||||
- fprintf(stderr,"\nboot entry %x not found\n\n",opts.bootnum);
|
||||
+ fprintf(stderr,"\n%s entry %x not found\n\n", driver ?"driver" :"boot",
|
||||
+ opts.bootnum);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -774,6 +805,7 @@ usage()
|
||||
printf("\t-B | --delete-bootnum delete bootnum (hex)\n");
|
||||
printf("\t-c | --create create new variable bootnum and add to bootorder\n");
|
||||
printf("\t-d | --disk disk (defaults to /dev/sda) containing loader\n");
|
||||
+ printf("\t-D | --driver modify driver entry instead of boot entry\n");
|
||||
printf("\t-e | --edd [1|3|-1] force EDD 1.0 or 3.0 creation variables, or guess\n");
|
||||
printf("\t-E | --device num EDD 1.0 device number (defaults to 0x80)\n");
|
||||
printf("\t-g | --gpt force disk with invalid PMBR to be treated as GPT\n");
|
||||
@@ -806,6 +838,7 @@ set_default_opts()
|
||||
opts.bootnext = -1; /* Don't set it */
|
||||
opts.active = -1; /* Don't set it */
|
||||
opts.timeout = -1; /* Don't set it */
|
||||
+ opts.driver = 0;
|
||||
opts.edd10_devicenum = 0x80;
|
||||
opts.loader = "\\elilo.efi";
|
||||
opts.label = "Linux";
|
||||
@@ -833,6 +866,7 @@ parse_opts(int argc, char **argv)
|
||||
{"delete-bootnum", no_argument, 0, 'B'},
|
||||
{"create", no_argument, 0, 'c'},
|
||||
{"disk", required_argument, 0, 'd'},
|
||||
+ {"driver", no_argument, 0, 'D'},
|
||||
{"iface", required_argument, 0, 'i'},
|
||||
{"acpi_hid", required_argument, 0, 'H'},
|
||||
{"edd-device", required_argument, 0, 'E'},
|
||||
@@ -860,7 +894,7 @@ parse_opts(int argc, char **argv)
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv,
|
||||
- "AaBb:cd:e:E:gH:i:l:L:n:No:Op:qt:TuU:v::Vw@:",
|
||||
+ "AaBb:cd:De:E:gH:i:l:L:n:No:Op:qt:TuU:v::Vw@:",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
@@ -893,6 +927,9 @@ parse_opts(int argc, char **argv)
|
||||
case 'd':
|
||||
opts.disk = optarg;
|
||||
break;
|
||||
+ case 'D':
|
||||
+ opts.driver = 1;
|
||||
+ break;
|
||||
case 'e':
|
||||
rc = sscanf(optarg, "%d", &num);
|
||||
if (rc == 1) opts.edd_version = num;
|
||||
@@ -1048,6 +1085,9 @@ main(int argc, char **argv)
|
||||
num_boot_names = read_boot_var_names(&boot_names);
|
||||
read_vars(boot_names, num_boot_names, &boot_entry_list);
|
||||
set_var_nums("Boot%04X-%*s", &boot_entry_list);
|
||||
+ num_boot_names = read_driver_var_names(&boot_names);
|
||||
+ read_vars(boot_names, num_boot_names, &driver_entry_list);
|
||||
+ set_var_nums("Driver%04X-%*s", &driver_entry_list);
|
||||
|
||||
if (opts.delete_boot) {
|
||||
if (opts.bootnum == -1) {
|
||||
@@ -1055,7 +1095,7 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
- ret = delete_boot_var(opts.bootnum);
|
||||
+ ret = delete_boot_var(opts.bootnum, opts.driver);
|
||||
}
|
||||
|
||||
if (opts.active >= 0) {
|
||||
@@ -1064,42 +1104,56 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
- ret=set_active_state();
|
||||
+ ret=set_active_state(opts.driver);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.create) {
|
||||
- warn_duplicate_name(&boot_entry_list);
|
||||
- new_boot = make_boot_var(&boot_entry_list);
|
||||
+ if (opts.driver) {
|
||||
+ warn_duplicate_name(&driver_entry_list, opts.driver);
|
||||
+ new_boot = make_var(&driver_entry_list, opts.driver);
|
||||
+ } else {
|
||||
+ warn_duplicate_name(&boot_entry_list, opts.driver);
|
||||
+ new_boot = make_var(&boot_entry_list, opts.driver);
|
||||
+ }
|
||||
+
|
||||
if (!new_boot)
|
||||
return 1;
|
||||
|
||||
/* Put this boot var in the right BootOrder */
|
||||
if (!opts.testfile && new_boot)
|
||||
- ret=add_to_boot_order(new_boot->num);
|
||||
+ ret=add_to_order(new_boot->num, opts.driver);
|
||||
}
|
||||
|
||||
if (!opts.testfile) {
|
||||
|
||||
if (opts.delete_bootorder) {
|
||||
- ret=delete_var("BootOrder");
|
||||
+ ret=delete_var(opts.driver ?"DriverOrder" :"BootOrder");
|
||||
}
|
||||
|
||||
if (opts.bootorder) {
|
||||
- ret=set_boot_order();
|
||||
+ ret=set_order(opts.driver);
|
||||
}
|
||||
|
||||
+ if (opts.driver) {
|
||||
+ if (opts.delete_timeout || opts.set_timeout) {
|
||||
+ fprintf(stderr, "\nTimeout is not compatible with -D.\n\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (opts.bootnext >= 0 || opts.delete_bootnext) {
|
||||
+ fprintf(stderr, "\nBootNext is not compatible with -D.\n\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (opts.delete_bootnext) {
|
||||
+ if (opts.delete_bootnext)
|
||||
ret=delete_var("BootNext");
|
||||
- }
|
||||
|
||||
- if (opts.delete_timeout) {
|
||||
+ if (opts.delete_timeout)
|
||||
ret=delete_var("Timeout");
|
||||
- }
|
||||
|
||||
if (opts.bootnext >= 0) {
|
||||
- if (!is_current_boot_entry(opts.bootnext & 0xFFFF)){
|
||||
+ if (!is_current_entry(opts.bootnext & 0xFFFF, 0)){
|
||||
fprintf (stderr,"\n\nboot entry %X does not exist\n\n",
|
||||
opts.bootnext);
|
||||
return 1;
|
||||
@@ -1107,9 +1161,8 @@ main(int argc, char **argv)
|
||||
ret=set_boot_u16("BootNext", opts.bootnext & 0xFFFF);
|
||||
}
|
||||
|
||||
- if (opts.set_timeout) {
|
||||
+ if (opts.set_timeout)
|
||||
ret=set_boot_u16("Timeout", opts.timeout);
|
||||
- }
|
||||
|
||||
if (!opts.quiet && ret == 0) {
|
||||
num = read_boot_u16("BootNext");
|
||||
@@ -1124,12 +1177,15 @@ main(int argc, char **argv)
|
||||
if (num != -1) {
|
||||
printf("Timeout: %u seconds\n", num);
|
||||
}
|
||||
- show_boot_order();
|
||||
- show_boot_vars();
|
||||
+ show_order(0);
|
||||
+ show_vars(&boot_entry_list);
|
||||
+ show_order(1);
|
||||
+ show_vars(&driver_entry_list);
|
||||
}
|
||||
}
|
||||
free_dirents(boot_names, num_boot_names);
|
||||
free_vars(&boot_entry_list);
|
||||
+ free_vars(&driver_entry_list);
|
||||
if (ret)
|
||||
return 1;
|
||||
return 0;
|
@ -1,29 +0,0 @@
|
||||
From f9f4ee75ad745637a47bf17ed968101b1ffbcc1d Mon Sep 17 00:00:00 2001
|
||||
From: Matt Domsch <Matt_Domsch@dell.com>
|
||||
Date: Thu, 23 Jul 2009 14:20:19 -0500
|
||||
Subject: [PATCH 4/5] fix disk minor number discovery
|
||||
|
||||
Raymund Will noted disk_info_from_fd() incorrectly used logical &&
|
||||
instead of bitwise & when obtaining the minor number.
|
||||
|
||||
Reported in https://bugzilla.novell.com/show_bug.cgi?id=524529#c1
|
||||
---
|
||||
src/lib/disk.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/disk.c b/src/lib/disk.c
|
||||
index ebfe619..8ad590b 100644
|
||||
--- a/src/lib/disk.c
|
||||
+++ b/src/lib/disk.c
|
||||
@@ -55,7 +55,7 @@ disk_info_from_fd(int fd,
|
||||
return 1;
|
||||
}
|
||||
major = buf.st_dev >> 8;
|
||||
- minor = buf.st_dev && 0xFF;
|
||||
+ minor = buf.st_dev & 0xFF;
|
||||
|
||||
/* IDE disks can have up to 64 partitions, or 6 bits worth,
|
||||
* and have one bit for the disk number.
|
||||
--
|
||||
1.8.0
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 36c3a19c62cc3b6841e363712c3c78ef5915122d Mon Sep 17 00:00:00 2001
|
||||
From: Matt Domsch <Matt_Domsch@dell.com>
|
||||
Date: Thu, 23 Jul 2009 14:18:11 -0500
|
||||
Subject: [PATCH 3/5] fix minor memory leak
|
||||
|
||||
David Binderman noted new_data was being allocated but not freed. Not
|
||||
a big deal as the program exits soon thereafter (and is thus freed),
|
||||
but worth fixing anyhow.
|
||||
|
||||
Fixes https://bugzilla.novell.com/show_bug.cgi?id=524529#c1
|
||||
---
|
||||
src/efibootmgr/efibootmgr.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/efibootmgr/efibootmgr.c b/src/efibootmgr/efibootmgr.c
|
||||
index b984143..de67af0 100644
|
||||
--- a/src/efibootmgr/efibootmgr.c
|
||||
+++ b/src/efibootmgr/efibootmgr.c
|
||||
@@ -328,6 +328,7 @@ add_to_boot_order(uint16_t num)
|
||||
/* Now new_data has what we need */
|
||||
memcpy(&(boot_order.Data), new_data, new_data_size);
|
||||
boot_order.DataSize = new_data_size;
|
||||
+ free(new_data);
|
||||
return create_or_edit_variable(&boot_order);
|
||||
}
|
||||
|
||||
--
|
||||
1.8.0
|
||||
|
@ -1,47 +0,0 @@
|
||||
From 5fcfccb39089febb89945b841f489b5acc7638ce Mon Sep 17 00:00:00 2001
|
||||
From: Lane Winner <lane.winner@oracle.com>
|
||||
Date: Tue, 24 Apr 2012 12:58:57 -0500
|
||||
Subject: [PATCH 5/5] make_boot_var does not check for failed status with
|
||||
create_variable. This can result in a memory leak.
|
||||
Additionally the user should be notified of the
|
||||
problem.
|
||||
|
||||
We encounter this issue on one system after filling up the UEFI boot list
|
||||
with dummy devices.
|
||||
|
||||
The patch fix the problem. It was verified on a Mensa system using RHEL 6.0
|
||||
|
||||
Signed-off-by: Yinghai Lu<yinghai@kernel.org>
|
||||
---
|
||||
src/efibootmgr/efibootmgr.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/efibootmgr/efibootmgr.c b/src/efibootmgr/efibootmgr.c
|
||||
index de67af0..236365a 100644
|
||||
--- a/src/efibootmgr/efibootmgr.c
|
||||
+++ b/src/efibootmgr/efibootmgr.c
|
||||
@@ -239,6 +239,7 @@ warn_duplicate_name(list_t *boot_list)
|
||||
static var_entry_t *
|
||||
make_boot_var(list_t *boot_list)
|
||||
{
|
||||
+ efi_status_t status;
|
||||
var_entry_t *boot;
|
||||
int free_number;
|
||||
list_t *pos;
|
||||
@@ -271,7 +272,12 @@ make_boot_var(list_t *boot_list)
|
||||
free(boot);
|
||||
return NULL;
|
||||
}
|
||||
- create_variable(&boot->var_data);
|
||||
+
|
||||
+ status = create_variable(&boot->var_data);
|
||||
+ if (status != EFI_SUCCESS) {
|
||||
+ free(boot);
|
||||
+ return NULL;
|
||||
+ }
|
||||
list_add_tail(&boot->list, boot_list);
|
||||
return boot;
|
||||
}
|
||||
--
|
||||
1.8.0
|
||||
|
@ -1,176 +0,0 @@
|
||||
Return-Path: pjones@redhat.com
|
||||
Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO
|
||||
zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by
|
||||
mail04.corp.redhat.com with LMTP; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
|
||||
Received: from localhost (localhost.localdomain [127.0.0.1])
|
||||
by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id B69C19F152
|
||||
for <pjones@redhat.com>; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
|
||||
Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1])
|
||||
by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024)
|
||||
with ESMTP id jCHcGZehMQ5J for <pjones@redhat.com>;
|
||||
Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
|
||||
Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21])
|
||||
by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id A601C9F14C
|
||||
for <pjones@mail.corp.redhat.com>; Wed, 14 Jul 2010 14:25:52 -0400 (EDT)
|
||||
Received: from pjones4.install.bos.redhat.com (pjones4.install.bos.redhat.com [10.16.52.154])
|
||||
by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6EIPpGh017771;
|
||||
Wed, 14 Jul 2010 14:25:52 -0400
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
To: Matt Domsch <Matt_Domsch@dell.com>
|
||||
Cc: Peter Jones <pjones@redhat.com>, Stuart Hayes <stuart_hayes@dell.com>
|
||||
Subject: [efibootmgr patch] Handle sector_size != 512.
|
||||
Date: Wed, 14 Jul 2010 14:26:49 -0400
|
||||
Message-Id: <1279132009-26635-1-git-send-email-pjones@redhat.com>
|
||||
In-Reply-To: <1279121617-17961-1-git-send-email-pjones@redhat.com>
|
||||
References: <1279121617-17961-1-git-send-email-pjones@redhat.com>
|
||||
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21
|
||||
|
||||
Disks can have 4kB sectors now, so don't just bail out when that's the
|
||||
case.
|
||||
---
|
||||
src/include/disk.h | 3 +++
|
||||
src/lib/disk.c | 43 +++++++++++++++++++++++++++++++++----------
|
||||
src/lib/gpt.c | 30 ++++++++++++++----------------
|
||||
3 files changed, 50 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/src/include/disk.h b/src/include/disk.h
|
||||
index eb93d10..8aa37d7 100644
|
||||
--- a/src/include/disk.h
|
||||
+++ b/src/include/disk.h
|
||||
@@ -65,6 +65,9 @@ enum _interface_type {interface_type_unknown,
|
||||
ata, atapi, scsi, usb,
|
||||
i1394, fibre, i2o, md};
|
||||
|
||||
+
|
||||
+unsigned int lcm(unsigned int x, unsigned int y);
|
||||
+
|
||||
int disk_get_pci(int fd,
|
||||
unsigned char *bus,
|
||||
unsigned char *device,
|
||||
diff --git a/src/lib/disk.c b/src/lib/disk.c
|
||||
index 883864f..9c3a878 100644
|
||||
--- a/src/lib/disk.c
|
||||
+++ b/src/lib/disk.c
|
||||
@@ -420,6 +420,27 @@ get_sector_size(int filedes)
|
||||
return sector_size;
|
||||
}
|
||||
|
||||
+/************************************************************
|
||||
+ * lcm
|
||||
+ * Requires:
|
||||
+ * - numbers of which to find the lowest common multiple
|
||||
+ * Modifies: nothing
|
||||
+ * Returns:
|
||||
+ * lowest common multiple of x and y
|
||||
+ ************************************************************/
|
||||
+unsigned int
|
||||
+lcm(unsigned int x, unsigned int y)
|
||||
+{
|
||||
+ unsigned int m = x, n = y, o;
|
||||
+
|
||||
+ while ((o = m % n)) {
|
||||
+ m = n;
|
||||
+ n = o;
|
||||
+ }
|
||||
+
|
||||
+ return (x / n) * y;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* disk_get_partition_info()
|
||||
* @fd - open file descriptor to disk
|
||||
@@ -442,26 +463,27 @@ disk_get_partition_info (int fd,
|
||||
uint8_t *mbr_type, uint8_t *signature_type)
|
||||
{
|
||||
legacy_mbr *mbr;
|
||||
- void *mbr_unaligned;
|
||||
+ void *mbr_sector;
|
||||
+ size_t mbr_size;
|
||||
off_t offset;
|
||||
int this_bytes_read = 0;
|
||||
int gpt_invalid=0, mbr_invalid=0;
|
||||
int rc=0;
|
||||
int sector_size = get_sector_size(fd);
|
||||
|
||||
- if (sizeof(*mbr) != sector_size)
|
||||
- return 1;
|
||||
- mbr_unaligned = malloc(sizeof(*mbr)+sector_size-1);
|
||||
- mbr = (legacy_mbr *)
|
||||
- (((unsigned long)mbr_unaligned + sector_size - 1) &
|
||||
- ~(unsigned long)(sector_size-1));
|
||||
- memset(mbr, 0, sizeof(*mbr));
|
||||
+
|
||||
+ mbr_size = lcm(sizeof(*mbr), sector_size);
|
||||
+ if ((rc = posix_memalign(&mbr_sector, sector_size, mbr_size)) != 0)
|
||||
+ goto error;
|
||||
+ memset(mbr_sector, '\0', mbr_size);
|
||||
+
|
||||
offset = lseek(fd, 0, SEEK_SET);
|
||||
- this_bytes_read = read(fd, mbr, sizeof(*mbr));
|
||||
+ this_bytes_read = read(fd, mbr_sector, mbr_size);
|
||||
if (this_bytes_read < sizeof(*mbr)) {
|
||||
rc=1;
|
||||
goto error_free_mbr;
|
||||
}
|
||||
+ mbr = (legacy_mbr *)mbr_sector;
|
||||
gpt_invalid = gpt_disk_get_partition_info(fd, num,
|
||||
start, size,
|
||||
signature,
|
||||
@@ -479,7 +501,8 @@ disk_get_partition_info (int fd,
|
||||
}
|
||||
}
|
||||
error_free_mbr:
|
||||
- free(mbr_unaligned);
|
||||
+ free(mbr_sector);
|
||||
+ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
diff --git a/src/lib/gpt.c b/src/lib/gpt.c
|
||||
index d90ddaf..83e7a94 100644
|
||||
--- a/src/lib/gpt.c
|
||||
+++ b/src/lib/gpt.c
|
||||
@@ -215,26 +215,24 @@ read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)
|
||||
static ssize_t
|
||||
read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
|
||||
{
|
||||
- int sector_size = get_sector_size(fd);
|
||||
- off_t offset = lba * sector_size;
|
||||
+ int sector_size = get_sector_size(fd);
|
||||
+ off_t offset = lba * sector_size;
|
||||
ssize_t bytesread;
|
||||
- void *aligned;
|
||||
- void *unaligned;
|
||||
-
|
||||
- if (bytes % sector_size)
|
||||
- return EINVAL;
|
||||
+ void *iobuf;
|
||||
+ size_t iobuf_size;
|
||||
+ int rc;
|
||||
|
||||
- unaligned = malloc(bytes+sector_size-1);
|
||||
- aligned = (void *)
|
||||
- (((unsigned long)unaligned + sector_size - 1) &
|
||||
- ~(unsigned long)(sector_size-1));
|
||||
- memset(aligned, 0, bytes);
|
||||
+ iobuf_size = lcm(bytes, sector_size);
|
||||
+ rc = posix_memalign(&iobuf, sector_size, iobuf_size);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ memset(iobuf, 0, bytes);
|
||||
|
||||
|
||||
- lseek(fd, offset, SEEK_SET);
|
||||
- bytesread = read(fd, aligned, bytes);
|
||||
- memcpy(buffer, aligned, bytesread);
|
||||
- free(unaligned);
|
||||
+ lseek(fd, offset, SEEK_SET);
|
||||
+ bytesread = read(fd, iobuf, iobuf_size);
|
||||
+ memcpy(buffer, iobuf, bytes);
|
||||
+ free(iobuf);
|
||||
|
||||
/* Kludge. This is necessary to read/write the last
|
||||
block of an odd-sized disk, until Linux 2.5.x kernel fixes.
|
||||
--
|
||||
1.7.1.1
|
||||
|
Loading…
Reference in New Issue
Block a user