assert(new_root);
assert(IN_SET(mount_flags, MS_MOVE, MS_BIND));
- if (path_equal(new_root, "/"))
- return 0;
-
/* Check if we shall remove the contents of the old root */
old_root_fd = open("/", O_DIRECTORY|O_CLOEXEC);
if (old_root_fd < 0)
return log_error_errno(errno, "Failed to open root directory: %m");
+ new_root_fd = open(new_root, O_DIRECTORY|O_CLOEXEC);
+ if (new_root_fd < 0)
+ return log_error_errno(errno, "Failed to open target directory '%s': %m", new_root);
+
+ r = files_same_at(old_root_fd, "", new_root_fd, "", AT_EMPTY_PATH);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine if old and new root directory are the same: %m");
+ if (r > 0) {
+ log_debug("Skipping switch root, as old and new root directory are the same.");
+ return 0;
+ }
+
istmp = fd_is_temporary_fs(old_root_fd);
if (istmp < 0)
return log_error_errno(istmp, "Failed to stat root directory: %m");
if (istmp > 0)
log_debug("Root directory is on tmpfs, will do cleanup later.");
- new_root_fd = open(new_root, O_DIRECTORY|O_CLOEXEC);
- if (new_root_fd < 0)
- return log_error_errno(errno, "Failed to open target directory '%s': %m", new_root);
-
if (old_root_after) {
/* Determine where we shall place the old root after the transition */
r = chase(old_root_after, new_root, CHASE_PREFIX_ROOT|CHASE_NONEXISTENT, &resolved_old_root_after, NULL);