diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c index d5b3d169bf..118eaac78e 100644 --- a/src/shared/switch-root.c +++ b/src/shared/switch-root.c @@ -36,24 +36,29 @@ int switch_root(const char *new_root, 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);