diff --git a/src/basic/initrd-util.c b/src/basic/initrd-util.c index 3624dcca56..03ccfbe483 100644 --- a/src/basic/initrd-util.c +++ b/src/basic/initrd-util.c @@ -3,6 +3,7 @@ #include #include "env-util.h" +#include "errno-util.h" #include "initrd-util.h" #include "parse-util.h" #include "stat-util.h" @@ -16,14 +17,8 @@ bool in_initrd(void) { if (saved_in_initrd >= 0) return saved_in_initrd; - /* We make two checks here: - * - * 1. the flag file /etc/initrd-release must exist - * 2. the root file system must be a memory file system - * - * The second check is extra paranoia, since misdetecting an - * initrd can have bad consequences due the initrd - * emptying when transititioning to the main systemd. + /* If /etc/initrd-release exists, we're in an initrd. + * This can be overridden by setting SYSTEMD_IN_INITRD=0|1. */ r = getenv_bool_secure("SYSTEMD_IN_INITRD"); @@ -32,9 +27,12 @@ bool in_initrd(void) { if (r >= 0) saved_in_initrd = r > 0; - else - saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 && - path_is_temporary_fs("/") > 0; + else { + r = RET_NERRNO(access("/etc/initrd-release", F_OK)); + if (r < 0 && r != -ENOENT) + log_debug_errno(r, "Failed to check if /etc/initrd-release exists, assuming it does not: %m"); + saved_in_initrd = r >= 0; + } return saved_in_initrd; } diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c index 0b93312bbf..8d4c07150e 100644 --- a/src/shared/switch-root.c +++ b/src/shared/switch-root.c @@ -32,7 +32,6 @@ int switch_root(const char *new_root, _cleanup_free_ char *resolved_old_root_after = NULL; _cleanup_close_ int old_root_fd = -1; - bool old_root_remove; int r; assert(new_root); @@ -42,12 +41,16 @@ int switch_root(const char *new_root, return 0; /* Check if we shall remove the contents of the old root */ - old_root_remove = in_initrd(); - if (old_root_remove) { - old_root_fd = open("/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY|O_DIRECTORY); - if (old_root_fd < 0) - return log_error_errno(errno, "Failed to open root directory: %m"); - } + old_root_fd = open("/", O_RDONLY | O_CLOEXEC | O_DIRECTORY); + if (old_root_fd < 0) + return log_error_errno(errno, "Failed to open root directory: %m"); + r = fd_is_temporary_fs(old_root_fd); + if (r < 0) + return log_error_errno(r, "Failed to stat root directory: %m"); + if (r > 0) + log_debug("Root directory is on tmpfs, will do cleanup later."); + else + old_root_fd = safe_close(old_root_fd); /* Determine where we shall place the old root after the transition */ r = chase_symlinks(old_root_after, new_root, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &resolved_old_root_after, NULL); @@ -117,9 +120,8 @@ int switch_root(const char *new_root, struct stat rb; if (fstat(old_root_fd, &rb) < 0) - log_warning_errno(errno, "Failed to stat old root directory, leaving: %m"); - else - (void) rm_rf_children(TAKE_FD(old_root_fd), 0, &rb); /* takes possession of the dir fd, even on failure */ + return log_error_errno(errno, "Failed to stat old root directory: %m"); + (void) rm_rf_children(TAKE_FD(old_root_fd), 0, &rb); /* takes possession of the dir fd, even on failure */ } return 0;