diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-02-20 17:25:14 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-02-21 18:19:38 +0100 |
commit | c56be2c294f55545ea34417a2ec4f6ad2cd1df6f (patch) | |
tree | 93cee6bbda623c51da5ff8d4c9ea16cf776c6a90 /src/shared/blockdev-util.c | |
parent | Merge pull request #26265 from poettering/journal-refresh-fixes (diff) | |
download | systemd-c56be2c294f55545ea34417a2ec4f6ad2cd1df6f.tar.xz systemd-c56be2c294f55545ea34417a2ec4f6ad2cd1df6f.zip |
bootctl: add new --print-root-device option
We already have this nice code in system that determines the block
device backing the root file system, but it's only used internally in
systemd-gpt-generator. Let's make this more accessible and expose it
directly in bootctl.
It doesn't fit immediately into the topic of bootctl, but I think it's
close enough and behaves very similar to the existing "bootctl
--print-boot-path" and "--print-esp-path" tools.
If --print-root-device (or -R) is specified once, will show the block device
backing the root fs, and if specified twice (probably easier: -RR) it
will show the whole block device that block device belongs to in case it
is a partition block device.
Suggested use:
# cfdisk `bootctl -RR`
To get access to the partition table, behind the OS install, for
whatever it might be.
Diffstat (limited to 'src/shared/blockdev-util.c')
-rw-r--r-- | src/shared/blockdev-util.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index ee134146a1..3d03eedcf0 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -17,6 +17,7 @@ #include "errno-util.h" #include "fd-util.h" #include "fileio.h" +#include "fs-util.h" #include "missing_magic.h" #include "parse-util.h" @@ -777,3 +778,53 @@ int blockdev_get_sector_size(int fd, uint32_t *ret) { *ret = ssz; return 0; } + +int blockdev_get_root(int level, dev_t *ret) { + _cleanup_free_ char *p = NULL; + dev_t devno; + int r; + + /* Returns the device node backing the root file system. Traces through + * dm-crypt/dm-verity/... Returns > 0 and the devno of the device on success. If there's no block + * device (or multiple) returns 0 and a devno of 0. Failure otherwise. + * + * 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 read that here. */ + r = readlink_malloc("/run/systemd/volatile-root", &p); + if (r == -ENOENT) { /* volatile-root not found */ + r = get_block_device_harder("/", &devno); + if (r == -EUCLEAN) + return btrfs_log_dev_root(level, r, "root file system"); + if (r < 0) + return log_full_errno(level, r, "Failed to determine block device of root file system: %m"); + if (r == 0) { /* Not backed by a single block device. (Could be NFS or so, or could be multi-device RAID or so) */ + r = get_block_device_harder("/usr", &devno); + if (r == -EUCLEAN) + return btrfs_log_dev_root(level, r, "/usr"); + if (r < 0) + return log_full_errno(level, r, "Failed to determine block device of /usr/ file system: %m"); + if (r == 0) { /* /usr/ not backed by single block device, either. */ + log_debug("Neither root nor /usr/ file system are on a (single) block device."); + + if (ret) + *ret = 0; + + return 0; + } + } + } else if (r < 0) + return log_full_errno(level, r, "Failed to read symlink /run/systemd/volatile-root: %m"); + else { + mode_t m; + r = device_path_parse_major_minor(p, &m, &devno); + if (r < 0) + return log_full_errno(level, r, "Failed to parse major/minor device node: %m"); + if (!S_ISBLK(m)) + return log_full_errno(level, SYNTHETIC_ERRNO(ENOTBLK), "Volatile root device is of wrong type."); + } + + if (ret) + *ret = devno; + + return 1; +} |