]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
execute: suppress credentials mount if empty
authorLennart Poettering <lennart@poettering.net>
Wed, 3 May 2023 20:45:05 +0000 (22:45 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 4 May 2023 10:10:01 +0000 (12:10 +0200)
Let's avoid creating another mount in the system if it's empty anyway.

This is mostl a cosmetic thing in one (pretty common) special case: if
creds settings are used in a unit but no creds actually available to be
passed.

(While we are at it this also does one more minor optimization: it
adjusts the MS_RDONLY/MS_NOSUID/… flags of the source mount we are about
to MS_MOVE into the right place only if we actually really move it, and
if we instead unmount it again we won't bother with the flags either)

src/core/execute.c

index b32e341b61df0fc0ae5c18c8621a8c9c0fdd3dab..b803edb1450b2cbc58297684835b83253e3fc88e 100644 (file)
@@ -3258,16 +3258,34 @@ static int setup_credentials_internal(
                 return r;
 
         if (workspace_mounted) {
-                /* Make workspace read-only now, so that any bind mount we make from it defaults to read-only too */
-                r = mount_nofollow_verbose(LOG_DEBUG, NULL, workspace, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL);
-                if (r < 0)
-                        return r;
+                bool install;
 
-                /* And mount it to the final place, read-only */
+                /* Determine if we should actually install the prepared mount in the final location by bind
+                 * mounting it there. We do so only if the mount is not established there already, and if the
+                 * mount is actually non-empty (i.e. carries at least one credential). Not that in the best
+                 * case we are doing all this in a mount namespace, thus noone else will see that we
+                 * allocated a file system we are getting rid of again here. */
                 if (final_mounted)
-                        r = umount_verbose(LOG_DEBUG, workspace, MNT_DETACH|UMOUNT_NOFOLLOW);
-                else
+                        install = false; /* already installed */
+                else {
+                        r = dir_is_empty(where, /* ignore_hidden_or_backup= */ false);
+                        if (r < 0)
+                                return r;
+
+                        install = r == 0; /* install only if non-empty */
+                }
+
+                if (install) {
+                        /* Make workspace read-only now, so that any bind mount we make from it defaults to read-only too */
+                        r = mount_nofollow_verbose(LOG_DEBUG, NULL, workspace, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NODEV|MS_NOEXEC|MS_NOSUID, NULL);
+                        if (r < 0)
+                                return r;
+
+                        /* And mount it to the final place, read-only */
                         r = mount_nofollow_verbose(LOG_DEBUG, workspace, final, NULL, MS_MOVE, NULL);
+                } else
+                        /* Otherwise get rid of it */
+                        r = umount_verbose(LOG_DEBUG, workspace, MNT_DETACH|UMOUNT_NOFOLLOW);
                 if (r < 0)
                         return r;
         } else {