mirror of
https://github.com/systemd/systemd.git
synced 2025-02-11 21:57:53 +03:00
Merge pull request #28971 from YHNdnzj/soft-reboot-is-better-switch-root
core,systemctl: use path_is_root & limit switch-root to initrd transitions
This commit is contained in:
commit
698287d7dc
4
NEWS
4
NEWS
@ -33,6 +33,10 @@ CHANGES WITH 255 in spe:
|
||||
by default when combined with --scope, will be changed in a future
|
||||
release to be enabled by default.
|
||||
|
||||
* "systemctl switch-root" is now restricted to initrd transtions only.
|
||||
Transitions between real systems should be done with "systemctl soft-reboot"
|
||||
instead.
|
||||
|
||||
Device Management:
|
||||
|
||||
* udev will now create symlinks to loopback block devices in the
|
||||
|
5
TODO
5
TODO
@ -274,11 +274,6 @@ Features:
|
||||
idea, and specifically works around the fact the autofs ignores busy by mount
|
||||
namespaces)
|
||||
|
||||
* refuse using the switch-root operation without /etc/initrd-release. Now
|
||||
that we have a concept of userspace reboot, we can clearly say: switch-root
|
||||
is for transitioning from initrd to host (or initrd to next initrd), while
|
||||
userspace reboot is for switching host to next version of the host.
|
||||
|
||||
* mount most file systems with a restrictive uidmap. e.g. mount /usr/ with a
|
||||
uidmap that blocks out anything outside 0…1000 (i.e. system users) and similar.
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "install.h"
|
||||
#include "log.h"
|
||||
#include "manager-dump.h"
|
||||
@ -1864,26 +1865,37 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
|
||||
if (!path_is_valid(root))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"New root directory must be a valid path.");
|
||||
|
||||
if (!path_is_absolute(root))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"New root path '%s' is not absolute.", root);
|
||||
if (path_equal(root, "/"))
|
||||
|
||||
r = path_is_root(root);
|
||||
if (r < 0)
|
||||
return sd_bus_error_set_errnof(error, r,
|
||||
"Failed to check if new root directory '%s' is the same as old root: %m",
|
||||
root);
|
||||
if (r > 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"New root directory cannot be the old root directory.");
|
||||
}
|
||||
|
||||
/* Safety check */
|
||||
if (isempty(init)) {
|
||||
r = path_is_os_tree(root);
|
||||
if (r < 0)
|
||||
return sd_bus_error_set_errnof(error, r,
|
||||
"Failed to determine whether root path '%s' contains an OS tree: %m",
|
||||
root);
|
||||
if (r == 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.",
|
||||
root);
|
||||
} else {
|
||||
if (!in_initrd())
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Not in initrd, refusing switch-root operation.");
|
||||
|
||||
r = path_is_os_tree(root);
|
||||
if (r < 0)
|
||||
return sd_bus_error_set_errnof(error, r,
|
||||
"Failed to determine whether root path '%s' contains an OS tree: %m",
|
||||
root);
|
||||
if (r == 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.",
|
||||
root);
|
||||
|
||||
if (!isempty(init)) {
|
||||
if (!path_is_valid(init))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||
"Path to init binary '%s' is not a valid path.", init);
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "chase.h"
|
||||
#include "fd-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "proc-cmdline.h"
|
||||
@ -47,15 +49,24 @@ int verb_switch_root(int argc, char *argv[], void *userdata) {
|
||||
|
||||
if (argc >= 2) {
|
||||
root = argv[1];
|
||||
|
||||
if (!path_is_valid(root))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid root path: %s", root);
|
||||
|
||||
if (!path_is_absolute(root))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Root path is not absolute: %s", root);
|
||||
if (path_equal(root, "/"))
|
||||
|
||||
r = path_is_root(root);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if switch-root directory '%s' is current root: %m", root);
|
||||
if (r > 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot switch to current root directory: %s", root);
|
||||
} else
|
||||
root = "/sysroot";
|
||||
|
||||
if (!in_initrd())
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not in initrd, refusing switch-root operation.");
|
||||
|
||||
if (argc >= 3)
|
||||
init = argv[2];
|
||||
else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user