From f8a7112c4728222c1ca1fe746c1c93382d2e90cd Mon Sep 17 00:00:00 2001 From: reuben olinsky Date: Mon, 31 Oct 2022 22:58:52 -0700 Subject: [PATCH] sysupdate: Support volatile-root for finding the root partition The existing logic can't find the root device in scenarios where the root has been replaced with an overlay. We support looking at "/run/systemd/volatile-root" to find the original root, similar to what systemd-repart and gpt-auto-generator do. --- src/sysupdate/sysupdate-resource.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/sysupdate/sysupdate-resource.c b/src/sysupdate/sysupdate-resource.c index bf521980e2..2814fdb6fa 100644 --- a/src/sysupdate/sysupdate-resource.c +++ b/src/sysupdate/sysupdate-resource.c @@ -8,6 +8,7 @@ #include "blockdev-util.h" #include "chase-symlinks.h" #include "device-util.h" +#include "devnum-util.h" #include "dirent-util.h" #include "env-util.h" #include "fd-util.h" @@ -525,10 +526,14 @@ int resource_resolve_path( assert(rr); if (rr->path_auto) { + struct stat orig_root_stats; - /* NB: we don't actually check the backing device of the root fs "/", but of "/usr", in order - * to support environments where the root fs is a tmpfs, and the OS itself placed exclusively - * in /usr/. */ + /* NB: If the root mount has been replaced by some form of volatile file system (overlayfs), + * the original root block device node is symlinked in /run/systemd/volatile-root. Let's + * follow that link here. If that doesn't exist, we check the backing device of "/usr". We + * don't actually check the backing device of the root fs "/", in order to support + * environments where the root fs is a tmpfs, and the OS itself placed exclusively in + * /usr/. */ if (rr->type != RESOURCE_PARTITION) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), @@ -546,7 +551,16 @@ int resource_resolve_path( return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Block device is not allowed when using --root= mode."); - r = get_block_device_harder("/usr/", &d); + r = stat("/run/systemd/volatile-root", &orig_root_stats); + if (r < 0) { + if (errno == -ENOENT) /* volatile-root not found */ + r = get_block_device_harder("/usr/", &d); + else + return log_error_errno(r, "Failed to stat /run/systemd/volatile-root: %m"); + } else if (!S_ISBLK(orig_root_stats.st_mode)) /* symlink was present but not block device */ + return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "/run/systemd/volatile-root is not linked to a block device."); + else /* symlink was present and a block device */ + d = orig_root_stats.st_rdev; } else if (rr->type == RESOURCE_PARTITION) { _cleanup_close_ int fd = -1, real_fd = -1; -- 2.25.1