#include <unistd.h>
#include "env-util.h"
+#include "errno-util.h"
#include "initrd-util.h"
#include "parse-util.h"
#include "stat-util.h"
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");
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;
}
_cleanup_free_ char *resolved_old_root_after = NULL;
_cleanup_close_ int old_root_fd = -1;
- bool old_root_remove;
int r;
assert(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);
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;