From 5e81ce42e77a9b989f3186765a13d0d52c371981 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 12 Sep 2024 20:28:01 +0200 Subject: [PATCH] sysext: Run unmerge in a subprocess Preparation for later commit where we need a private mount namespace for unmerge. --- src/sysext/sysext.c | 58 +++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index f6b38d66152..94669dbd528 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -354,38 +354,60 @@ static int unmerge_hierarchy( return 0; } +static int unmerge_subprocess( + ImageClass image_class, + char **hierarchies) { + + int r, ret = 0; + + STRV_FOREACH(h, hierarchies) { + _cleanup_free_ char *resolved = NULL; + + r = chase(*h, arg_root, CHASE_PREFIX_ROOT, &resolved, NULL); + if (r == -ENOENT) { + log_debug_errno(r, "Hierarchy '%s%s' does not exist, ignoring.", strempty(arg_root), *h); + continue; + } + if (r < 0) { + RET_GATHER(ret, log_error_errno(r, "Failed to resolve path to hierarchy '%s%s': %m", strempty(arg_root), *h)); + continue; + } + + r = unmerge_hierarchy(image_class, resolved); + if (r < 0) { + RET_GATHER(ret, r); + continue; + } + } + + return ret; +} + static int unmerge( ImageClass image_class, char **hierarchies, bool no_reload) { - int r, ret = 0; bool need_to_reload; + int r; r = need_reload(image_class, hierarchies, no_reload); if (r < 0) return r; need_to_reload = r > 0; - STRV_FOREACH(p, hierarchies) { - _cleanup_free_ char *resolved = NULL; + r = safe_fork("(sd-unmerge)", FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, /* ret_pid= */ NULL); + if (r < 0) + return r; + if (r == 0) { + /* Child with its own mount namespace */ - r = chase(*p, arg_root, CHASE_PREFIX_ROOT, &resolved, NULL); - if (r == -ENOENT) { - log_debug_errno(r, "Hierarchy '%s%s' does not exist, ignoring.", strempty(arg_root), *p); - continue; - } - if (r < 0) { - log_error_errno(r, "Failed to resolve path to hierarchy '%s%s': %m", strempty(arg_root), *p); - if (ret == 0) - ret = r; + r = unmerge_subprocess(image_class, hierarchies); - continue; - } + /* Our namespace ceases to exist here, also implicitly detaching all temporary mounts we + * created below /run. Nice! */ - r = unmerge_hierarchy(image_class, resolved); - if (r < 0 && ret == 0) - ret = r; + _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); } if (need_to_reload) { @@ -394,7 +416,7 @@ static int unmerge( return r; } - return ret; + return 0; } static int verb_unmerge(int argc, char **argv, void *userdata) { -- 2.47.3