forked from pool/grub2
* grub2-bls-loader-entry-oneshot.patch OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=550
104 lines
3.1 KiB
Diff
104 lines
3.1 KiB
Diff
From a1fbb752dd800c0aaaacc60bce33bf696f45d1a4 Mon Sep 17 00:00:00 2001
|
|
From: Gary Lin <glin@suse.com>
|
|
Date: Thu, 20 Mar 2025 15:08:14 +0800
|
|
Subject: [PATCH] osdep/linux: skip non-subvolume btrfs mount points
|
|
|
|
To apply the new btrfs snapshot to '/boot', 'transactional-update apply'
|
|
mounts '/boot' to the snapshot with 'mount --rbind'. For example, a new
|
|
snapshot 9 is created in '/@/.snapshots/9/snapshot', and 't-u apply'
|
|
bind-mounts '/boot' to '/@/.snapshots/9/snapshot/boot'. Then such entry
|
|
will be created in /proc/self/mountinfo:
|
|
|
|
537 62 0:64 /@/.snapshots/9/snapshot/boot /boot rw,relatime shared:486 - btrfs /dev/mapper/luks rw,seclabel,space_cache=v2,subvolid=276,subvol=/@/.snapshots/9/snapshot
|
|
|
|
This mount point is only temporary and will be gone after reboot.
|
|
However, this made 'grub2-mkrelpath -r /boot/grub2' to treat '/boot' as
|
|
a legit btrfs subvolume and return '/grub2' rather than '/boot/grub2'.
|
|
|
|
To filter out the bind-mount entries, the btrfs subvolume check is
|
|
introduced to check if the given mount point is a real subvolume or not.
|
|
If it's a btrfs subvolume, we should take it into consideration when
|
|
producing the relative path. Otherwise, skip the mount point.
|
|
|
|
Signed-off-by: Gary Lin <glin@suse.com>
|
|
---
|
|
grub-core/osdep/linux/getroot.c | 39 ++++++++++++++++++++++++++++++++-
|
|
1 file changed, 38 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c
|
|
index d63f19f18..b6c2ff9c3 100644
|
|
--- a/grub-core/osdep/linux/getroot.c
|
|
+++ b/grub-core/osdep/linux/getroot.c
|
|
@@ -20,6 +20,7 @@
|
|
#include <config.h>
|
|
|
|
#include <sys/stat.h>
|
|
+#include <sys/statfs.h>
|
|
#include <sys/types.h>
|
|
#include <assert.h>
|
|
#include <fcntl.h>
|
|
@@ -484,6 +485,33 @@ error:
|
|
return NULL;
|
|
}
|
|
|
|
+#define BTRFS_SUPER_MAGIC 0x9123683e
|
|
+#define BTRFS_FIRST_FREE_OBJECTID 256ULL
|
|
+
|
|
+static bool
|
|
+is_btrfs_subvolume (char *mnt_path)
|
|
+{
|
|
+ struct statfs sfs;
|
|
+ struct stat st;
|
|
+ int ret;
|
|
+
|
|
+ ret = statfs (mnt_path, &sfs);
|
|
+ if (ret != 0)
|
|
+ return false;
|
|
+
|
|
+ if (sfs.f_type != BTRFS_SUPER_MAGIC)
|
|
+ return false;
|
|
+
|
|
+ ret = stat(mnt_path, &st);
|
|
+ if (ret != 0)
|
|
+ return false;
|
|
+
|
|
+ if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode))
|
|
+ return false;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static char *grub_btrfs_mount_path;
|
|
|
|
char **
|
|
@@ -626,9 +654,17 @@ again:
|
|
}
|
|
else if (grub_strcmp (entries[i].fstype, "btrfs") == 0)
|
|
{
|
|
- ret = grub_find_root_devices_from_btrfs (dir);
|
|
if (use_relative_path_on_btrfs)
|
|
{
|
|
+ /* 'transactional-update apply' mounts '/boot' to the newly
|
|
+ created snapshot with 'mount --rbind', and this creates a
|
|
+ non-subvolume btrfs mount point. Such mount point will be
|
|
+ gone after reboot. Skip those mount points to produce the
|
|
+ correct relative path. (bsc#1239674) */
|
|
+ if (!is_btrfs_subvolume (entries[i].enc_path))
|
|
+ continue;
|
|
+
|
|
+ ret = grub_find_root_devices_from_btrfs (dir);
|
|
fs_prefix = xstrdup ("/");
|
|
|
|
if (grub_btrfs_mount_path)
|
|
@@ -637,6 +673,7 @@ again:
|
|
}
|
|
else
|
|
{
|
|
+ ret = grub_find_root_devices_from_btrfs (dir);
|
|
fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path);
|
|
}
|
|
}
|
|
--
|
|
2.43.0
|
|
|