repart: Support volatile-root for finding the root partition
The automatic logic can't always find the original root partition (ex: if the rootfs is copied to a ext4 fs backed by zram in the initramfs), so we want to support "/run/systemd/volatile-root" which is a symlink to the original root partition. Fix #20610
This commit is contained in:
committed by
Lennart Poettering
parent
ce380c2f09
commit
54632d2ea4
+29
-12
@@ -4529,6 +4529,7 @@ static int acquire_root_devno(
|
||||
static int find_root(char **ret, int *ret_fd) {
|
||||
const char *p;
|
||||
int r;
|
||||
_cleanup_free_ char *device = NULL;
|
||||
|
||||
assert(ret);
|
||||
assert(ret_fd);
|
||||
@@ -4564,20 +4565,36 @@ static int find_root(char **ret, int *ret_fd) {
|
||||
|
||||
assert(IN_SET(arg_empty, EMPTY_REFUSE, EMPTY_ALLOW));
|
||||
|
||||
/* Let's search for the root device. We look for two cases here: first in /, and then in /usr. The
|
||||
* latter we check for cases where / is a tmpfs and only /usr is an actual persistent block device
|
||||
* (think: volatile setups) */
|
||||
/* 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", &device);
|
||||
if (r == -ENOENT) { /* volatile-root not found */
|
||||
/* Let's search for the root device. We look for two cases here: first in /, and then in /usr. The
|
||||
* latter we check for cases where / is a tmpfs and only /usr is an actual persistent block device
|
||||
* (think: volatile setups) */
|
||||
|
||||
FOREACH_STRING(p, "/", "/usr") {
|
||||
FOREACH_STRING(p, "/", "/usr") {
|
||||
|
||||
r = acquire_root_devno(p, arg_root, O_RDONLY|O_DIRECTORY|O_CLOEXEC, ret, ret_fd);
|
||||
if (r < 0) {
|
||||
if (r == -EUCLEAN)
|
||||
return btrfs_log_dev_root(LOG_ERR, r, p);
|
||||
if (r != -ENODEV)
|
||||
return log_error_errno(r, "Failed to determine backing device of %s: %m", p);
|
||||
} else
|
||||
return 0;
|
||||
r = acquire_root_devno(p, arg_root, O_RDONLY|O_DIRECTORY|O_CLOEXEC, ret, ret_fd);
|
||||
if (r < 0) {
|
||||
if (r == -EUCLEAN)
|
||||
return btrfs_log_dev_root(LOG_ERR, r, p);
|
||||
if (r != -ENODEV)
|
||||
return log_error_errno(r, "Failed to determine backing device of %s: %m", p);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
} else if (r < 0)
|
||||
return log_error_errno(r, "Failed to read symlink /run/systemd/volatile-root: %m");
|
||||
else {
|
||||
r = acquire_root_devno(device, NULL, O_RDONLY|O_CLOEXEC, ret, ret_fd);
|
||||
if (r == -EUCLEAN)
|
||||
return btrfs_log_dev_root(LOG_ERR, r, device);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to open file or determine backing device of %s: %m", device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "Failed to discover root block device.");
|
||||
|
||||
Reference in New Issue
Block a user