]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
switch-root: check if old and new root fs is same via files_same_at()
authorLennart Poettering <lennart@poettering.net>
Tue, 16 May 2023 12:57:20 +0000 (14:57 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 May 2023 15:42:31 +0000 (17:42 +0200)
src/shared/switch-root.c

index d5b3d169bf87194bbec130ee5cebe159b494f6ec..118eaac78efa455f4079dae6a4347357f4fa1a97 100644 (file)
@@ -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);