summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-05-03 22:45:05 +0200
committerLennart Poettering <lennart@poettering.net>2023-05-04 12:10:01 +0200
commit21dd1de659935c829a3776b6772f803c2eb4eae3 (patch)
treeb15ef9ccb26b46d167544f22273db21431189287 /src/core
parent9107ef5637fe92d408ef231c748fe04ab04cca18 (diff)
downloadsystemd-21dd1de659935c829a3776b6772f803c2eb4eae3.tar.gz
execute: suppress credentials mount if empty
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)
Diffstat (limited to 'src/core')
-rw-r--r--src/core/execute.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/src/core/execute.c b/src/core/execute.c
index b32e341b61..b803edb145 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -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 {