summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--resolv/tst-resolv-res_init-skeleton.c69
-rw-r--r--support/Makefile1
-rw-r--r--support/namespace.h32
-rw-r--r--support/support_chroot.c71
5 files changed, 140 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index 42ffe74254..5cbeb7b89c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2017-07-05  Florian Weimer  <fweimer@redhat.com>
 
+	* support/namespace.h (struct support_chroot_configuration)
+	(struct support_chroot): Define.
+	(support_chroot_create, support_chroot_free): New functions.
+	* support/support_chroot.c: New file.
+	* support/Makefile (libsupport-routines): Add support_chroot.
+	* resolv/tst-resolv-res_init-skeleton.c (path_chroot)
+	(path_resolv_conf): Remove definitions.
+	(chroot_env): New variable.
+	(prepare): Call support_chroot_create.
+	(check_chroot_working, setup_nss_dns_and_chroot, run_res_init)
+	(special_test_callback, do_test): Likewise.
+
+2017-07-05  Florian Weimer  <fweimer@redhat.com>
+
 	Add subtest to check isolation of multiple loopback addresses.
 	* support/tst-support-namespace.c (test_localhost_bind): New function.
 	(do_test): Call it.
diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c
index 8f395d8ce9..3b7b4129e3 100644
--- a/resolv/tst-resolv-res_init-skeleton.c
+++ b/resolv/tst-resolv-res_init-skeleton.c
@@ -47,46 +47,23 @@
    res_init.  */
 static const char *const test_hostname = "www.example.com";
 
-/* Path to the test root directory.  */
-static char *path_chroot;
-
-/* Path to resolv.conf under path_chroot (outside the chroot).  */
-static char *path_resolv_conf;
+struct support_chroot *chroot_env;
 
 static void
 prepare (int argc, char **argv)
 {
-  path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
-  if (mkdtemp (path_chroot) == NULL)
-    FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", path_chroot);
-  add_temp_file (path_chroot);
-
-  /* Create the /etc directory in the chroot environment.  */
-  char *path_etc = xasprintf ("%s/etc", path_chroot);
-  xmkdir (path_etc, 0777);
-  add_temp_file (path_etc);
-
-  /* Create an empty resolv.conf file.  */
-  path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc);
-  add_temp_file (path_resolv_conf);
-  support_write_file_string (path_resolv_conf, "");
-
-  free (path_etc);
-
-  /* valgrind needs a temporary directory in the chroot.  */
-  {
-    char *path_tmp = xasprintf ("%s/tmp", path_chroot);
-    xmkdir (path_tmp, 0777);
-    add_temp_file (path_tmp);
-    free (path_tmp);
-  }
+  chroot_env = support_chroot_create
+    ((struct support_chroot_configuration)
+     {
+       .resolv_conf = "",
+     });
 }
 
 /* Verify that the chroot environment has been set up.  */
 static void
 check_chroot_working (void *closure)
 {
-  xchroot (path_chroot);
+  xchroot (chroot_env->path_chroot);
   FILE *fp = xfopen (_PATH_RESCONF, "r");
   xfclose (fp);
 
@@ -345,7 +322,7 @@ setup_nss_dns_and_chroot (void)
   /* Load nss_dns outside of the chroot.  */
   if (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) == NULL)
     FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
-  xchroot (path_chroot);
+  xchroot (chroot_env->path_chroot);
   /* Force the use of nss_dns.  */
   __nss_configure_lookup ("hosts", "dns");
 }
@@ -374,13 +351,13 @@ run_res_init (void *closure)
   switch (ctx->init)
     {
     case test_init:
-      xchroot (path_chroot);
+      xchroot (chroot_env->path_chroot);
       TEST_VERIFY (res_init () == 0);
       print_resp (stdout, &_res);
       return;
 
     case test_ninit:
-      xchroot (path_chroot);
+      xchroot (chroot_env->path_chroot);
       res_state resp = xmalloc (sizeof (*resp));
       memset (resp, 0, sizeof (*resp));
       TEST_VERIFY (res_ninit (resp) == 0);
@@ -390,7 +367,7 @@ run_res_init (void *closure)
       return;
 
     case test_mkquery:
-      xchroot (path_chroot);
+      xchroot (chroot_env->path_chroot);
       unsigned char buf[512];
       TEST_VERIFY (res_mkquery (QUERY, "www.example",
                                 C_IN, ns_t_a, NULL, 0,
@@ -783,7 +760,7 @@ special_test_callback (void *closure)
   TEST_VERIFY (test_index < special_tests_count);
   if (test_verbose > 0)
     printf ("info: special test %u\n", test_index);
-  xchroot (path_chroot);
+  xchroot (chroot_env->path_chroot);
 
   switch (test_index)
     {
@@ -1063,7 +1040,8 @@ do_test (void)
       TEST_VERIFY (test_cases[i].conf != NULL);
       TEST_VERIFY (test_cases[i].expected != NULL);
 
-      support_write_file_string (path_resolv_conf, test_cases[i].conf);
+      support_write_file_string (chroot_env->path_resolv_conf,
+                                 test_cases[i].conf);
 
       test_file_contents (&test_cases[i]);
 
@@ -1073,24 +1051,24 @@ do_test (void)
         {
           if (test_verbose > 0)
             printf ("info:  special test: missing file\n");
-          TEST_VERIFY (unlink (path_resolv_conf) == 0);
+          TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
           test_file_contents (&test_cases[i]);
 
           if (test_verbose > 0)
             printf ("info:  special test: dangling symbolic link\n");
-          TEST_VERIFY (symlink ("does-not-exist", path_resolv_conf) == 0);
+          TEST_VERIFY (symlink ("does-not-exist", chroot_env->path_resolv_conf) == 0);
           test_file_contents (&test_cases[i]);
-          TEST_VERIFY (unlink (path_resolv_conf) == 0);
+          TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
 
           if (test_verbose > 0)
             printf ("info:  special test: unreadable file\n");
-          support_write_file_string (path_resolv_conf, "");
-          TEST_VERIFY (chmod (path_resolv_conf, 0) == 0);
+          support_write_file_string (chroot_env->path_resolv_conf, "");
+          TEST_VERIFY (chmod (chroot_env->path_resolv_conf, 0) == 0);
           test_file_contents (&test_cases[i]);
 
           /* Restore the empty file.  */
-          TEST_VERIFY (unlink (path_resolv_conf) == 0);
-          support_write_file_string (path_resolv_conf, "");
+          TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
+          support_write_file_string (chroot_env->path_resolv_conf, "");
         }
     }
 
@@ -1106,10 +1084,7 @@ do_test (void)
       xwaitpid (server, NULL, 0);
     }
 
-  free (path_chroot);
-  path_chroot = NULL;
-  free (path_resolv_conf);
-  path_resolv_conf = NULL;
+  support_chroot_free (chroot_env);
   return 0;
 }
 
diff --git a/support/Makefile b/support/Makefile
index 423538d06a..1eba34b749 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -40,6 +40,7 @@ libsupport-routines = \
   support_can_chroot \
   support_capture_subprocess \
   support_capture_subprocess_check \
+  support_chroot \
   support_enter_network_namespace \
   support_format_address_family \
   support_format_addrinfo \
diff --git a/support/namespace.h b/support/namespace.h
index e1ccaa1ef0..859c2fda3f 100644
--- a/support/namespace.h
+++ b/support/namespace.h
@@ -60,6 +60,38 @@ bool support_in_uts_namespace (void);
    non-zero exit status.  */
 void support_isolate_in_subprocess (void (*callback) (void *), void *closure);
 
+/* Describe the setup of a chroot environment, for
+   support_chroot_create below.  */
+struct support_chroot_configuration
+{
+  /* File contents.  The files are not created if the field is
+     NULL.  */
+  const char *resolv_conf;
+};
+
+/* The result of the creation of a chroot.  */
+struct support_chroot
+{
+  /* Path information.  All these paths are relative to the parent
+     chroot.  */
+
+  /* Path to the chroot directory.  */
+  char *path_chroot;
+
+  /* Path to the /etc/resolv.conf file.  */
+  char *path_resolv_conf;
+};
+
+/* Create a chroot environment.  The returned data should be freed
+   using support_chroot_free below.  The files will be deleted when
+   the process exits.  This function does not enter the chroot.  */
+struct support_chroot *support_chroot_create
+  (struct support_chroot_configuration);
+
+/* Deallocate the chroot information created by
+   support_chroot_create.  */
+void support_chroot_free (struct support_chroot *);
+
 __END_DECLS
 
 #endif
diff --git a/support/support_chroot.c b/support/support_chroot.c
new file mode 100644
index 0000000000..c0807b313a
--- /dev/null
+++ b/support/support_chroot.c
@@ -0,0 +1,71 @@
+/* Setup a chroot environment for use within tests.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <support/check.h>
+#include <support/namespace.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <support/xunistd.h>
+
+struct support_chroot *
+support_chroot_create (struct support_chroot_configuration conf)
+{
+  struct support_chroot *chroot = xmalloc (sizeof (*chroot));
+
+  chroot->path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
+  if (mkdtemp (chroot->path_chroot) == NULL)
+    FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", chroot->path_chroot);
+  add_temp_file (chroot->path_chroot);
+
+  /* Create the /etc directory in the chroot environment.  */
+  char *path_etc = xasprintf ("%s/etc", chroot->path_chroot);
+  xmkdir (path_etc, 0777);
+  add_temp_file (path_etc);
+
+  if (conf.resolv_conf != NULL)
+    {
+      /* Create an empty resolv.conf file.  */
+      chroot->path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc);
+      add_temp_file (chroot->path_resolv_conf);
+      support_write_file_string (chroot->path_resolv_conf, conf.resolv_conf);
+    }
+  else
+    chroot->path_resolv_conf = NULL;
+
+  free (path_etc);
+
+  /* valgrind needs a temporary directory in the chroot.  */
+  {
+    char *path_tmp = xasprintf ("%s/tmp", chroot->path_chroot);
+    xmkdir (path_tmp, 0777);
+    add_temp_file (path_tmp);
+    free (path_tmp);
+  }
+
+  return chroot;
+}
+
+void
+support_chroot_free (struct support_chroot *chroot)
+{
+  free (chroot->path_chroot);
+  free (chroot->path_resolv_conf);
+  free (chroot);
+}