You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.6 KiB
87 lines
2.6 KiB
9 months ago
|
From 304c61a24f909168c16793ccf7c686237e53d003 Mon Sep 17 00:00:00 2001
|
||
|
From: DJ Delorie <dj@redhat.com>
|
||
|
Date: Wed, 5 Dec 2018 12:39:47 -0500
|
||
|
Subject: test-container: move postclean outside of namespace changes
|
||
|
|
||
|
During postclean.req testing it was found that the fork in the
|
||
|
parent process (after the unshare syscall) would fail with ENOMEM
|
||
|
(see recursive_remove() in test-container.c). While failing with
|
||
|
ENOMEM is certainly unexpected, it is simply easier to refactor
|
||
|
the design and have the parent remain outside of the namespace.
|
||
|
This change moves the postclean.req processing to a distinct
|
||
|
process (the parent) that then forks the test process (which will
|
||
|
have to fork once more to complete uid/gid transitions). When the
|
||
|
test process exists the cleanup process will ensure all files are
|
||
|
deleted when a post clean is requested.
|
||
|
|
||
|
Signed-off-by: DJ Delorie <dj@redhat.com>
|
||
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||
|
|
||
|
[BZ #23948]
|
||
|
* support/test-container.c: Move postclean step to before we
|
||
|
change namespaces.
|
||
|
|
||
|
diff --git a/support/test-container.c b/support/test-container.c
|
||
|
index df450adfdb..1d1aebeaf3 100644
|
||
|
--- a/support/test-container.c
|
||
|
+++ b/support/test-container.c
|
||
|
@@ -921,6 +921,43 @@ main (int argc, char **argv)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ if (do_postclean)
|
||
|
+ {
|
||
|
+ pid_t pc_pid = fork ();
|
||
|
+
|
||
|
+ if (pc_pid < 0)
|
||
|
+ {
|
||
|
+ FAIL_EXIT1 ("Can't fork for post-clean");
|
||
|
+ }
|
||
|
+ else if (pc_pid > 0)
|
||
|
+ {
|
||
|
+ /* Parent. */
|
||
|
+ int status;
|
||
|
+ waitpid (pc_pid, &status, 0);
|
||
|
+
|
||
|
+ /* Child has exited, we can post-clean the test root. */
|
||
|
+ printf("running post-clean rsync\n");
|
||
|
+ rsync (pristine_root_path, new_root_path, 1);
|
||
|
+
|
||
|
+ if (WIFEXITED (status))
|
||
|
+ exit (WEXITSTATUS (status));
|
||
|
+
|
||
|
+ if (WIFSIGNALED (status))
|
||
|
+ {
|
||
|
+ printf ("%%SIGNALLED%%\n");
|
||
|
+ exit (77);
|
||
|
+ }
|
||
|
+
|
||
|
+ printf ("%%EXITERROR%%\n");
|
||
|
+ exit (78);
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Child continues. */
|
||
|
+ }
|
||
|
+
|
||
|
+ /* This is the last point in the program where we're still in the
|
||
|
+ "normal" namespace. */
|
||
|
+
|
||
|
#ifdef CLONE_NEWNS
|
||
|
/* The unshare here gives us our own spaces and capabilities. */
|
||
|
if (unshare (CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNS) < 0)
|
||
|
@@ -974,14 +1011,6 @@ main (int argc, char **argv)
|
||
|
int status;
|
||
|
waitpid (child, &status, 0);
|
||
|
|
||
|
- /* There's a bit of magic here, since the buildroot is mounted
|
||
|
- in our space, the paths are still valid, and since the mounts
|
||
|
- aren't recursive, it sees *only* the built root, not anything
|
||
|
- we would normally se if we rsync'd to "/" like mounted /dev
|
||
|
- files. */
|
||
|
- if (do_postclean)
|
||
|
- rsync (pristine_root_path, new_root_path, 1);
|
||
|
-
|
||
|
if (WIFEXITED (status))
|
||
|
exit (WEXITSTATUS (status));
|
||
|
|