5 Star 0 Fork 16

OpenCloudOS Stream/grub2

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0124-install-fix-software-raid1-on-esp.patch 14.79 KB
一键复制 编辑 原始数据 按行查看 历史
nilusyi 提交于 2024-04-07 16:45 . update patches
From 2143dab8db3b0ada0d3f1744c5e472716f6e1459 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Thu, 31 Dec 2020 21:54:07 +0800
Subject: [PATCH 124/272] install: fix software raid1 on esp
While running grub-install on an efi system where efi system partition
is configured as mdadm software raid1, it fails with errors like this:
grub2-install: info: copying `/boot/grub2/x86_64-efi/core.efi' -> `/boot/efi/EFI/opensuse/grubx64.efi'.
grub2-install: info: Registering with EFI: distributor = `opensuse', path = `\EFI\opensuse\grubx64.efi', ESP at mduuid/9182c46b9d469f79b48850b68f3371a5.
grub2-install: info: executing efibootmgr --version </dev/null >/dev/null.
grub2-install: info: executing modprobe -q efivars.
grub2-install: info: executing efibootmgr -c -d.
efibootmgr: option requires an argument -- 'd'
efibootmgr version 14
usage: efibootmgr [options]
This should work with mdadm raid1 with metadata 0.9 and 1.0 whose
superblocks are at the end of device. However
grub_install_register_efi() doesn't seem to work if the target is
multiple devices so that it errors out.
The patch changes grub_install_register_efi() to accept multiple devices
that can be used to creating efi boot entries for probed raid1 member
devices on mounted efi system partition.
This patch also adds check for metadata 0.9 or 1.0 or the validation
will fail to continue the install.
Signed-off-by: Michael Chang <mchang@suse.com>
---
grub-core/disk/diskfilter.c | 27 +++----
grub-core/disk/mdraid1x_linux.c | 3 +
grub-core/osdep/basic/no_platform.c | 3 +-
grub-core/osdep/unix/platform.c | 57 +++++++++++----
grub-core/osdep/windows/platform.c | 3 +-
include/grub/diskfilter.h | 3 +-
include/grub/util/install.h | 5 +-
util/grub-install.c | 107 ++++++++++++++++++++++++++--
8 files changed, 171 insertions(+), 37 deletions(-)
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
index b74d2fd48..41e177549 100644
--- a/grub-core/disk/diskfilter.c
+++ b/grub-core/disk/diskfilter.c
@@ -159,8 +159,8 @@ scan_disk_partition_iter (grub_disk_t disk, grub_partition_t p, void *data)
for (m = arr->pvs; m; m = m->next)
if (m->disk && m->disk->id == disk->id
&& m->disk->dev->id == disk->dev->id
- && m->part_start == grub_partition_get_start (disk->partition)
- && m->part_size == grub_disk_native_sectors (disk))
+ && grub_partition_get_start (m->disk->partition) == grub_partition_get_start (disk->partition)
+ && grub_disk_native_sectors (m->disk) == grub_disk_native_sectors (disk))
return 0;
}
@@ -1338,19 +1338,23 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
? (grub_memcmp (pv->id.uuid, id->uuid, id->uuidlen) == 0)
: (pv->id.id == id->id))
{
+ char *part_name = NULL;
struct grub_diskfilter_lv *lv;
/* FIXME: Check whether the update time of the superblocks are
the same. */
- if (pv->disk && grub_disk_native_sectors (disk) >= pv->part_size)
+ if (pv->disk && grub_disk_native_sectors (disk) >= grub_disk_native_sectors (pv->disk))
return GRUB_ERR_NONE;
- pv->disk = grub_disk_open (disk->name);
+ if (disk->partition)
+ {
+ char *p = grub_partition_get_name (disk->partition);
+ if (p)
+ part_name = grub_xasprintf ("%s,%s", disk->name, p);
+ grub_free (p);
+ }
+ pv->disk = grub_disk_open (part_name ? : disk->name);
+ grub_free (part_name);
if (!pv->disk)
return grub_errno;
- /* This could happen to LVM on RAID, pv->disk points to the
- raid device, we shouldn't change it. */
- pv->start_sector -= pv->part_start;
- pv->part_start = grub_partition_get_start (disk->partition);
- pv->part_size = grub_disk_native_sectors (disk);
#ifdef GRUB_UTIL
{
@@ -1367,7 +1371,6 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id,
#endif
if (start_sector != (grub_uint64_t)-1)
pv->start_sector = start_sector;
- pv->start_sector += pv->part_start;
/* Add the device to the array. */
for (lv = array->lvs; lv; lv = lv->next)
if (!lv->became_readable_at && lv->fullname && is_lv_readable (lv, 0))
@@ -1455,8 +1458,8 @@ grub_diskfilter_get_pv_from_disk (grub_disk_t disk,
{
if (pv->disk && pv->disk->id == disk->id
&& pv->disk->dev->id == disk->dev->id
- && pv->part_start == grub_partition_get_start (disk->partition)
- && pv->part_size == grub_disk_native_sectors (disk))
+ && grub_partition_get_start (pv->disk->partition) == grub_partition_get_start (disk->partition)
+ && grub_disk_native_sectors (pv->disk) == grub_disk_native_sectors (disk))
{
if (vg_out)
*vg_out = vg;
diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c
index 72e5cb6f4..d33b98b96 100644
--- a/grub-core/disk/mdraid1x_linux.c
+++ b/grub-core/disk/mdraid1x_linux.c
@@ -208,6 +208,9 @@ grub_mdraid_detect (grub_disk_t disk,
grub_le_to_cpu32 (sb.chunksize),
grub_le_to_cpu32 (sb.layout),
grub_le_to_cpu32 (sb.level));
+#ifdef GRUB_UTIL
+ array->mdraid1x_minor_version = minor_version;
+#endif
return array;
}
diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c
index a9de0597d..bcb5ab0ff 100644
--- a/grub-core/osdep/basic/no_platform.c
+++ b/grub-core/osdep/basic/no_platform.c
@@ -33,7 +33,8 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
void
grub_install_register_efi (grub_device_t efidir_grub_dev,
const char *efifile_path,
- const char *efi_distributor)
+ const char *efi_distributor,
+ const char *force_disk)
{
grub_util_error ("%s", _("no EFI routines are available for your platform"));
}
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
index 1edca359a..0a16ac293 100644
--- a/grub-core/osdep/unix/platform.c
+++ b/grub-core/osdep/unix/platform.c
@@ -132,15 +132,14 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
}
int
-grub_install_register_efi (grub_device_t efidir_grub_dev,
+grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
const char *efifile_path,
- const char *efi_distributor)
+ const char *efi_distributor,
+ const char *force_disk)
{
- const char * efidir_disk;
- int efidir_part;
int ret;
- efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
- efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
+ const grub_disk_t *curdisk;
+ int ndev = 0;
if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL }))
{
@@ -158,22 +157,50 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
if (ret)
return ret;
- char *efidir_part_str = xasprintf ("%d", efidir_part);
+ for (curdisk = efidir_grub_disk; *curdisk; curdisk++)
+ ndev++;
- if (!verbosity)
- ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
+ for (curdisk = efidir_grub_disk; *curdisk; curdisk++)
+ {
+ const char * efidir_disk;
+ int efidir_part;
+ char *efidir_part_str;
+ char *new_efi_distributor = NULL;
+ grub_disk_t disk = *curdisk;
+
+ efidir_disk = force_disk ? : grub_util_biosdisk_get_osdev (disk);
+ if (!efidir_disk)
+ grub_util_error (_("%s: no device for efi"), disk->name);
+
+ efidir_part = disk->partition ? disk->partition->number + 1 : 1;
+ efidir_part_str = xasprintf ("%d", efidir_part);
+ if (ndev > 1)
+ {
+ const char *p = grub_strrchr (efidir_disk, '/');
+ new_efi_distributor = xasprintf ("%s (%s%d)\n",
+ efi_distributor,
+ p ? p + 1: efidir_disk,
+ efidir_part);
+ }
+
+ if (!verbosity)
+ ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
"-c", "-d", efidir_disk,
"-p", efidir_part_str, "-w",
- "-L", efi_distributor, "-l",
+ "-L", new_efi_distributor ? : efi_distributor, "-l",
efifile_path, NULL });
- else
- ret = grub_util_exec ((const char * []){ "efibootmgr",
+ else
+ ret = grub_util_exec ((const char * []){ "efibootmgr",
"-c", "-d", efidir_disk,
"-p", efidir_part_str, "-w",
- "-L", efi_distributor, "-l",
+ "-L", new_efi_distributor ? : efi_distributor, "-l",
efifile_path, NULL });
- free (efidir_part_str);
- return ret;
+ free (efidir_part_str);
+ free (new_efi_distributor);
+ if (ret)
+ return ret;
+ }
+ return 0;
}
void
diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c
index e84c4d897..29c9bf81d 100644
--- a/grub-core/osdep/windows/platform.c
+++ b/grub-core/osdep/windows/platform.c
@@ -204,7 +204,8 @@ set_efi_variable_bootn (grub_uint16_t n, void *in, grub_size_t len)
int
grub_install_register_efi (grub_device_t efidir_grub_dev,
const char *efifile_path,
- const char *efi_distributor)
+ const char *efi_distributor,
+ const char *force_disk)
{
grub_uint16_t *boot_order, *new_boot_order;
grub_uint16_t *distributor16;
diff --git a/include/grub/diskfilter.h b/include/grub/diskfilter.h
index f020d025b..dc1bd4db0 100644
--- a/include/grub/diskfilter.h
+++ b/include/grub/diskfilter.h
@@ -49,6 +49,7 @@ struct grub_diskfilter_vg {
#ifdef GRUB_UTIL
struct grub_diskfilter *driver;
+ grub_uint8_t mdraid1x_minor_version;
#endif
};
@@ -66,8 +67,6 @@ struct grub_diskfilter_pv {
/* Optional. */
char *name;
grub_disk_t disk;
- grub_disk_addr_t part_start;
- grub_disk_addr_t part_size;
grub_disk_addr_t start_sector; /* Sector number where the data area starts. */
struct grub_diskfilter_pv *next;
/* Optional. */
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 8732a2494..fe11a0411 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -235,9 +235,10 @@ int
grub_install_get_powerpc_secure_boot (void);
int
-grub_install_register_efi (grub_device_t efidir_grub_dev,
+grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
const char *efifile_path,
- const char *efi_distributor);
+ const char *efi_distributor,
+ const char *force_disk);
void
grub_install_register_ieee1275 (int is_prep, const char *install_device,
diff --git a/util/grub-install.c b/util/grub-install.c
index 397592be9..62012d055 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -1727,6 +1727,40 @@ main (int argc, char *argv[])
}
}
prefix_drive = xasprintf ("(%s)", grub_drives[0]);
+
+ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI
+ && grub_dev->disk
+ && grub_dev->disk->partition
+ && grub_fs->fs_uuid)
+ {
+ int raid_level;
+ char *uuid = NULL;
+ char *escaped_relpath = NULL;
+
+ raid_level = probe_raid_level (grub_dev->disk);
+ if (raid_level != 1)
+ goto out;
+
+ escaped_relpath = escape (relative_grubdir);
+ if (!escaped_relpath)
+ goto out;
+
+ if (grub_fs->fs_uuid (grub_dev, &uuid) || !uuid)
+ {
+ grub_print_error ();
+ grub_errno = 0;
+ goto out;
+ }
+
+ if (!load_cfg_f)
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
+ have_load_cfg = 1;
+ fprintf (load_cfg_f, "search --no-floppy --fs-uuid --set=root --hint='%s' %s\n", grub_drives[0], uuid);
+ fprintf (load_cfg_f, "set prefix=($root)'%s'\n", escaped_relpath);
+ grub_install_push_module ("search");
+ out:
+ grub_free (escaped_relpath);
+ }
}
#ifdef __linux__
@@ -2255,9 +2289,13 @@ main (int argc, char *argv[])
{
/* Try to make this image bootable using the EFI Boot Manager, if available. */
int ret;
- ret = grub_install_register_efi (efidir_grub_dev,
+ grub_disk_t efidir_grub_disk[2];
+ efidir_grub_disk[0] = efidir_grub_dev->disk;
+ efidir_grub_disk[1] = NULL;
+ ret = grub_install_register_efi (efidir_grub_disk,
"\\System\\Library\\CoreServices",
- efi_distributor);
+ efi_distributor,
+ NULL);
if (ret)
grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
strerror (ret));
@@ -2311,7 +2349,11 @@ main (int argc, char *argv[])
{
char * efifile_path;
char * part;
+ int raid_level;
int ret;
+ grub_disk_t *efidir_grub_disk;
+ grub_disk_memberlist_t list = NULL, cur;
+ char * force_disk = NULL;
/* Try to make this image bootable using the EFI Boot Manager, if available. */
if (!efi_distributor || efi_distributor[0] == '\0')
@@ -2328,8 +2370,65 @@ main (int argc, char *argv[])
efidir_grub_dev->disk->name,
(part ? ",": ""), (part ? : ""));
grub_free (part);
- ret = grub_install_register_efi (efidir_grub_dev,
- efifile_path, efi_distributor);
+
+ raid_level = probe_raid_level (efidir_grub_dev->disk);
+ if (raid_level >= 0 && raid_level != 1)
+ grub_util_warn (_("unsupported raid level %d detected for efi system partition"), raid_level);
+ if (raid_level == 1 && !efidir_grub_dev->disk->partition)
+ {
+ const char *raidname = NULL;
+
+ if (efidir_grub_dev->disk->dev->disk_raidname)
+ raidname = efidir_grub_dev->disk->dev->disk_raidname (efidir_grub_dev->disk);
+ if (raidname
+ && (grub_strncmp (raidname, "mdraid09", sizeof ("mdraid09")) == 0
+ || (grub_strcmp (raidname, "mdraid1x") == 0
+ && ((struct grub_diskfilter_lv *) efidir_grub_dev->disk->data)->vg->mdraid1x_minor_version == 0)))
+ {
+ if (efidir_grub_dev->disk->dev->disk_memberlist)
+ list = efidir_grub_dev->disk->dev->disk_memberlist (efidir_grub_dev->disk);
+ }
+ else
+ {
+ grub_util_warn (_("this array has metadata at the start and may not be suitable as a efi system partition."
+ " please ensure that your firmware understands md/v1.x metadata, or use --metadata=0.90"
+ " to create the array."));
+ /* Try to continue regardless metadata, nothing to lose here */
+ if (efidir_grub_dev->disk->dev->disk_memberlist)
+ list = efidir_grub_dev->disk->dev->disk_memberlist (efidir_grub_dev->disk);
+ }
+ }
+ else if (raid_level == 1)
+ force_disk = grub_util_get_os_disk (install_device);
+ if (list)
+ {
+ int i;
+ int ndisk = 0;
+
+ for (cur = list; cur; cur = cur->next)
+ ++ndisk;
+ efidir_grub_disk = xcalloc (ndisk + 1, sizeof (*efidir_grub_disk));
+ for (cur = list, i = 0; i < ndisk; cur = cur->next, i++)
+ efidir_grub_disk[i] = cur->disk;
+ efidir_grub_disk[ndisk] = NULL;
+ }
+ else
+ {
+ efidir_grub_disk = xcalloc (2, sizeof (*efidir_grub_disk));
+ efidir_grub_disk[0] = efidir_grub_dev->disk;
+ efidir_grub_disk[1] = NULL;
+ }
+ ret = grub_install_register_efi (efidir_grub_disk,
+ efifile_path, efi_distributor,
+ force_disk);
+ while (list)
+ {
+ cur = list;
+ list = list->next;
+ grub_free (cur);
+ }
+ grub_free (force_disk);
+ grub_free (efidir_grub_disk);
if (ret)
grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
strerror (ret));
--
2.41.0
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/opencloudos-stream/grub2.git
git@gitee.com:opencloudos-stream/grub2.git
opencloudos-stream
grub2
grub2
master

搜索帮助