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