From patchwork Wed Jul 5 17:06:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 21439 Received: (qmail 75212 invoked by alias); 5 Jul 2017 17:06:10 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 74868 invoked by uid 89); 5 Jul 2017 17:06:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com F092F78EA8 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=fweimer@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com F092F78EA8 Date: Wed, 05 Jul 2017 19:06:02 +0200 To: libc-alpha@sourceware.org Subject: [PATCH COMMITTED] support: Add support_chroot_create and support_chroot_free User-Agent: Heirloom mailx 12.5 7/5/10 MIME-Version: 1.0 Message-Id: <20170705170603.04A15439942F0@oldenburg.str.redhat.com> From: fweimer@redhat.com (Florian Weimer) 2017-07-05 Florian Weimer * 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. diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c index 8f395d8..3b7b412 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 423538d..1eba34b 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 e1ccaa1..859c2fd 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 0000000..c0807b3 --- /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 + . */ + +#include +#include +#include +#include +#include +#include +#include + +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); +}