Irritatingly, BLS defines paths relatives to the mountpoint of the
filesystem which contains its snippets, not / or any other fixed
location. So grub2-emu needs to know whether /boot is a separate
filesysem from / and conditionally prepend a path.
Signed-off-by: Robbie Harwood <rharw...@redhat.com>
Signed-off-by: Alec Brown <alec.r.br...@oracle.com>
---
grub-core/Makefile.core.def | 4 +++
grub-core/commands/blsuki.c | 50 +++++++++++++++++++++++++++++----
grub-core/osdep/linux/getroot.c | 8 ++++++
grub-core/osdep/unix/getroot.c | 10 +++++++
include/grub/emu/misc.h | 2 +-
5 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 2cf4e9708..1f86111ad 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -367,6 +367,10 @@ kernel = {
emu = kern/emu/cache_s.S;
emu = kern/emu/hostdisk.c;
emu = osdep/unix/hostdisk.c;
+ emu = osdep/relpath.c;
+ emu = osdep/getroot.c;
+ emu = osdep/unix/getroot.c;
+ emu = osdep/devmapper/getroot.c;
emu = osdep/exec.c;
extra_dist = osdep/unix/exec.c;
emu = osdep/devmapper/hostdisk.c;
diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index 5203e4707..8a3c5818f 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -32,10 +32,16 @@
#include <grub/lib/envblk.h>
#include <grub/lib/vercmp.h>
+#ifdef GRUB_MACHINE_EMU
+#include <grub/emu/misc.h>
+#define GRUB_BOOT_DEVICE "/boot"
+#else
+#define GRUB_BOOT_DEVICE "/"
+#endif
+
GRUB_MOD_LICENSE ("GPLv3+");
#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
-#define GRUB_BOOT_DEVICE "/"
static const struct grub_arg_option opt[] =
{
@@ -54,8 +60,41 @@ struct keyval
static grub_blsuki_entry_t *entries = NULL;
+/*
+ * Cache probing in frob_boot_device(). Used for linux entry also.
+ * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE.
+ */
+static int separate_boot = -1;
+
#define FOR_BLSUKI_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
+/*
+ * BLS appears to make paths relative to the filesystem that snippets are
+ * on, not /. Attempt to cope.
+ */
+static char *frob_boot_device (char *tmp)
+{
+#ifdef GRUB_MACHINE_EMU
+ char *ret;
+
+ if (separate_boot != -1)
+ goto probed;
+
+ separate_boot = 0;
+
+ ret = grub_make_system_path_relative_to_its_root (GRUB_BOOT_DEVICE);
+
+ if (ret != NULL)
+ separate_boot = 1;
+
+ probed:
+ if (!separate_boot)
+ return grub_stpcpy (tmp, " ");
+#endif
+
+ return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+}
+
static int
blsuki_add_keyval (grub_blsuki_entry_t *entry, char *key, char *val)
{
@@ -682,7 +721,7 @@ create_entry (grub_blsuki_entry_t *entry)
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
{
grub_dprintf ("blsuki", "adding early initrd %s\n", early_initrds[i]);
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+ tmp = frob_boot_device (tmp);
tmp = grub_stpcpy (tmp, initrd_prefix);
tmp = grub_stpcpy (tmp, early_initrds[i]);
grub_free (early_initrds[i]);
@@ -691,7 +730,7 @@ create_entry (grub_blsuki_entry_t *entry)
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
{
grub_dprintf ("blsuki", "adding initrd %s\n", initrds[i]);
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+ tmp = frob_boot_device (tmp);
tmp = grub_stpcpy (tmp, initrds[i]);
}
tmp = grub_stpcpy (tmp, "\n");
@@ -734,7 +773,7 @@ create_entry (grub_blsuki_entry_t *entry)
}
tmp = dt;
tmp = grub_stpcpy (dt, "devicetree");
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+ tmp = frob_boot_device (tmp);
if (add_dt_prefix == true)
tmp = grub_stpcpy (tmp, prefix);
tmp = grub_stpcpy (tmp, devicetree);
@@ -753,7 +792,8 @@ create_entry (grub_blsuki_entry_t *entry)
"linux %s%s%s%s\n"
"%s%s",
savedefault ? "savedefault\n" : "",
- GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options :
"",
+ separate_boot ? GRUB_BOOT_DEVICE : "",
+ clinux, options ? " " : "", options ? options : "",
initrd ? initrd : "", dt ? dt : "");
grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, entry);
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
index 7dd775d2a..37f715469 100644
--- a/grub-core/osdep/linux/getroot.c
+++ b/grub-core/osdep/linux/getroot.c
@@ -131,6 +131,7 @@ struct mountinfo_entry
char fstype[ESCAPED_PATH_MAX + 1], device[ESCAPED_PATH_MAX + 1];
};
+#ifdef GRUB_UTIL
static char **
grub_util_raid_getmembers (const char *name, int bootable)
{
@@ -191,6 +192,7 @@ grub_util_raid_getmembers (const char *name, int bootable)
return devicelist;
}
+#endif
/* Statting something on a btrfs filesystem always returns a virtual device
major/minor pair rather than the real underlying device, because btrfs
@@ -576,6 +578,7 @@ out:
return ret;
}
+#ifdef GRUB_UTIL
static char *
get_mdadm_uuid (const char *os_dev)
{
@@ -633,6 +636,7 @@ out:
return name;
}
+#endif
static int
grub_util_is_imsm (const char *os_dev)
@@ -965,6 +969,7 @@ grub_util_part_to_disk (const char *os_dev, struct stat *st,
return path;
}
+#ifdef GRUB_UTIL
static char *
grub_util_get_raid_grub_dev (const char *os_dev)
{
@@ -1067,6 +1072,7 @@ grub_util_get_raid_grub_dev (const char *os_dev)
}
return grub_dev;
}
+#endif
enum grub_dev_abstraction_types
grub_util_get_dev_abstraction_os (const char *os_dev)
@@ -1083,6 +1089,7 @@ grub_util_get_dev_abstraction_os (const char *os_dev)
return GRUB_DEV_ABSTRACTION_NONE;
}
+#ifdef GRUB_UTIL
int
grub_util_pull_device_os (const char *os_dev,
enum grub_dev_abstraction_types ab)
@@ -1139,6 +1146,7 @@ grub_util_get_grub_dev_os (const char *os_dev)
return grub_dev;
}
+#endif
char *
grub_make_system_path_relative_to_its_root_os (const char *path)
diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c
index cde821eb9..ce3f8e505 100644
--- a/grub-core/osdep/unix/getroot.c
+++ b/grub-core/osdep/unix/getroot.c
@@ -17,6 +17,14 @@
*/
#include <config.h>
+#undef _GL_INLINE_HEADER_BEGIN
+#undef _GL_INLINE_HEADER_END
+#undef _GL_GNUC_PREREQ
+#undef _GL_ATTRIBUTE_COLD
+#undef _GL_ATTRIBUTE_CONST
+#undef _GL_ATTRIBUTE_DEALLOC
+#undef _GL_ATTRIBUTE_FALLTHROUGH
+#undef _GL_ATTRIBUTE_MALLOC
#include <config-util.h>
#include <sys/stat.h>
@@ -567,6 +575,7 @@ grub_guess_root_devices (const char *dir_in)
#endif
+#ifdef GRUB_UTIL
void
grub_util_pull_lvm_by_command (const char *os_dev)
{
@@ -663,6 +672,7 @@ out:
free (buf);
free (vgid);
}
+#endif
/* ZFS has similar problems to those of btrfs (see above). */
void
diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h
index 01056954b..bfc1ca58b 100644
--- a/include/grub/emu/misc.h
+++ b/include/grub/emu/misc.h
@@ -39,7 +39,7 @@ void grub_fini_all (void);
void grub_find_zpool_from_dir (const char *dir,
char **poolname, char **poolfs);
-char *grub_make_system_path_relative_to_its_root (const char *path)
+char * EXPORT_FUNC(grub_make_system_path_relative_to_its_root) (const char
*path)
WARN_UNUSED_RESULT;
int
grub_util_device_is_mapped (const char *dev);