加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0001-Workaround-volatile-efi-boot-variable.patch 8.12 KB
一键复制 编辑 原始数据 按行查看 历史
zhangqiumiao 提交于 2024-03-04 03:17 . update to 2.12
From 71575829c303fe8522b46fc96b1f99f1aa4178e7 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Fri, 19 Mar 2021 22:58:45 +0800
Subject: [PATCH] Workaround volatile efi boot variable
The efi variable in Microsoft Azure virtual machine is volatile that it cannot
persist across power cycling. If we use efi variable to communicate with efi
boot manager for booting a distribution, the process would silently fail as the
default loader in the efi system partition will start to take over the process
whenever the efi variable evaporated.
That will lead to undefined symbol error one day as the default path didn't
receive any grub update so it cannot keep up with new ABI requirement by
updated grub modules.
The patch will try to workaround the problem by providing grub update to the
default path along with the distribution specific one. To avoid negative side
effects of inadvertently overwritting other loader intended in default path,
care must be taken to ensure that:
1. The workaround only takes place on detected Azure virtual machine
2. The default path is not in use by shim for the secure boot
---
Makefile.util.def | 1 +
.../osdep/basic/efi_removable_fallback.c | 26 +++
grub-core/osdep/efi_removable_fallback.c | 5 +
.../osdep/linux/efi_removable_fallback.c | 151 ++++++++++++++++++
include/grub/util/install.h | 3 +
util/grub-install.c | 19 +++
6 files changed, 205 insertions(+)
create mode 100644 grub-core/osdep/basic/efi_removable_fallback.c
create mode 100644 grub-core/osdep/efi_removable_fallback.c
create mode 100644 grub-core/osdep/linux/efi_removable_fallback.c
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -681,6 +681,9 @@
common = grub-core/osdep/journaled_fs.c;
extra_dist = grub-core/osdep/basic/journaled_fs.c;
extra_dist = grub-core/osdep/linux/journaled_fs.c;
+ common = grub-core/osdep/efi_removable_fallback.c;
+ extra_dist = grub-core/osdep/basic/efi_removable_fallback.c;
+ extra_dist = grub-core/osdep/linux/efi_removable_fallback.c;
ldadd = '$(LIBLZMA)';
ldadd = libgrubmods.a;
--- /dev/null
+++ b/grub-core/osdep/basic/efi_removable_fallback.c
@@ -0,0 +1,26 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/util/install.h>
+
+const char *
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform)
+{
+ return NULL;
+}
+
--- /dev/null
+++ b/grub-core/osdep/efi_removable_fallback.c
@@ -0,0 +1,5 @@
+#ifdef __linux__
+#include "linux/efi_removable_fallback.c"
+#else
+#include "basic/efi_removable_fallback.c"
+#endif
--- /dev/null
+++ b/grub-core/osdep/linux/efi_removable_fallback.c
@@ -0,0 +1,151 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <grub/util/install.h>
+#include <grub/emu/exec.h>
+#include <grub/emu/misc.h>
+#include <string.h>
+
+static char *
+get_dmi_id (const char *id)
+{
+ FILE *fp;
+ char *buf = NULL;
+ size_t len = 0;
+
+ char *dmi_entry;
+
+ dmi_entry = grub_util_path_concat (2, "/sys/class/dmi/id", id);
+
+ fp = grub_util_fopen (dmi_entry, "r");
+ if (!fp)
+ {
+ free (dmi_entry);
+ return NULL;
+ }
+
+ if (getline (&buf, &len, fp) == -1)
+ {
+ fclose (fp);
+ free (dmi_entry);
+ return NULL;
+ }
+
+ fclose (fp);
+ free (dmi_entry);
+ return buf;
+}
+
+
+static struct dmi {
+ const char *id;
+ const char *val;
+} azure_dmi [3] = {
+ {"bios_vendor", "Microsoft Corporation"},
+ {"product_name", "Virtual Machine"},
+ {"sys_vendor", "Microsoft Corporation"},
+};
+
+static int
+is_azure (void)
+{
+ int i;
+ int n = sizeof (azure_dmi) / sizeof (struct dmi);
+
+ for (i = 0; i < n; ++i)
+ {
+ char *val;
+
+ val = get_dmi_id (azure_dmi[i].id);
+ if (!val)
+ break;
+ if (strncmp (val, azure_dmi[i].val, strlen (azure_dmi[i].val)) != 0)
+ {
+ free (val);
+ break;
+ }
+ free (val);
+ }
+
+ return (i == n) ? 1 : 0;
+}
+
+static int
+guess_shim_installed (const char *instdir)
+{
+ const char *shim[] = {"fallback.efi", "MokManager.efi", NULL};
+ const char **s;
+
+ for (s = shim; *s ; ++s)
+ {
+ char *p = grub_util_path_concat (2, instdir, *s);
+
+ if (access (p, F_OK) == 0)
+ {
+ free (p);
+ return 1;
+ }
+ free (p);
+ }
+
+ return 0;
+}
+
+const char *
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform)
+{
+ char *instdir;
+
+ if (!is_azure ())
+ return NULL;
+
+ instdir = grub_util_path_concat (3, efidir, "EFI", "BOOT");
+
+ if (guess_shim_installed (instdir))
+ {
+ grub_util_info ("skip removable fallback occupied by shim");
+ return NULL;
+ }
+
+ free (instdir);
+
+ switch (platform)
+ {
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
+ return "BOOTIA32.EFI";
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
+ return "BOOTX64.EFI";
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
+ return "BOOTIA64.EFI";
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
+ return "BOOTARM.EFI";
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
+ return "BOOTAA64.EFI";
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
+ return "BOOTRISCV32.EFI";
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
+ return "BOOTRISCV64.EFI";
+ default:
+ grub_util_error ("%s", _("You've found a bug"));
+ break;
+ }
+ return NULL;
+}
+
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -303,4 +303,7 @@
int
grub_install_sync_fs_journal (const char *path);
+
+const char *
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform);
#endif
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -901,6 +901,7 @@
const char *pkgdatadir;
char *rootdir_path;
char **rootdir_devices;
+ char *efidir_root;
grub_util_host_init (&argc, &argv);
product_version = xstrdup (PACKAGE_VERSION);
@@ -1175,6 +1176,7 @@
}
if (!efidir)
grub_util_error ("%s", _("cannot find EFI directory"));
+ efidir_root = grub_strdup (efidir);
efidir_device_names = grub_guess_root_devices (efidir);
if (!efidir_device_names || !efidir_device_names[0])
grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
@@ -2217,6 +2219,23 @@
free (grub_efi_cfg);
}
}
+ if (!removable)
+ {
+ const char *f;
+
+ f = grub_install_efi_removable_fallback (efidir_root, platform);
+ if (f)
+ {
+ char *t = grub_util_path_concat (3, efidir_root, "EFI", "BOOT");
+ char *dst = grub_util_path_concat (2, t, f);
+
+ grub_install_mkdir_p (t);
+ fprintf (stderr, _("Install to %s as fallback.\n"), dst);
+ grub_install_copy_file (imgfile, dst, 1);
+ grub_free (t);
+ grub_free (dst);
+ }
+ }
if (!removable && update_nvram)
{
char * efifile_path;
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化