summary refs log tree commit diff
path: root/resolv/tst-resolv-res_init-skeleton.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-07-03 21:06:23 +0200
committerFlorian Weimer <fweimer@redhat.com>2017-07-03 21:06:23 +0200
commitaef16cc8a4c670036d45590877d411a97f01e0cd (patch)
tree4403f1962170ce92087a6e1af62dbb92e15d27f6 /resolv/tst-resolv-res_init-skeleton.c
parenta1c4eb8794e789b5055d7ceb13b2b3231abf5e26 (diff)
downloadglibc-aef16cc8a4c670036d45590877d411a97f01e0cd.tar.gz
glibc-aef16cc8a4c670036d45590877d411a97f01e0cd.tar.xz
glibc-aef16cc8a4c670036d45590877d411a97f01e0cd.zip
resolv: Automatically reload a changed /etc/resolv.conf file [BZ #984]
This commit enhances the stub resolver to reload the configuration
in the per-thread _res object if the /etc/resolv.conf file has
changed.  The resolver checks whether the application has modified
_res and will not overwrite the _res object in that case.

The struct resolv_context mechanism is used to check the
configuration file only once per name lookup.
Diffstat (limited to 'resolv/tst-resolv-res_init-skeleton.c')
-rw-r--r--resolv/tst-resolv-res_init-skeleton.c72
1 files changed, 50 insertions, 22 deletions
diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c
index f98e9f4030..9e496a3212 100644
--- a/resolv/tst-resolv-res_init-skeleton.c
+++ b/resolv/tst-resolv-res_init-skeleton.c
@@ -151,6 +151,7 @@ print_resp (FILE *fp, res_state resp)
         print_option_flag (fp, &options, RES_SNGLKUPREOP,
                            "single-request-reopen");
         print_option_flag (fp, &options, RES_NOTLDQUERY, "no-tld-query");
+        print_option_flag (fp, &options, RES_NORELOAD, "no-reload");
         fputc ('\n', fp);
         if (options != 0)
           fprintf (fp, "; error: unresolved option bits: 0x%x\n", options);
@@ -470,6 +471,28 @@ struct test_case test_cases[] =
      "nameserver 192.0.2.1\n"
      "; nameserver[0]: [192.0.2.1]:53\n"
     },
+    {.name = "basic no-reload",
+     .conf = "options no-reload\n"
+     "search corp.example.com example.com\n"
+     "nameserver 192.0.2.1\n",
+     .expected = "options no-reload\n"
+     "search corp.example.com example.com\n"
+     "; search[0]: corp.example.com\n"
+     "; search[1]: example.com\n"
+     "nameserver 192.0.2.1\n"
+     "; nameserver[0]: [192.0.2.1]:53\n"
+    },
+    {.name = "basic no-reload via RES_OPTIONS",
+     .conf = "search corp.example.com example.com\n"
+     "nameserver 192.0.2.1\n",
+     .expected = "options no-reload\n"
+     "search corp.example.com example.com\n"
+     "; search[0]: corp.example.com\n"
+     "; search[1]: example.com\n"
+     "nameserver 192.0.2.1\n"
+     "; nameserver[0]: [192.0.2.1]:53\n",
+     .res_options = "no-reload"
+    },
     {.name = "whitespace",
      .conf = "# This test covers comment and whitespace processing "
      " (trailing whitespace,\n"
@@ -722,18 +745,7 @@ test_file_contents (const struct test_case *t)
 }
 
 /* Special tests which do not follow the general pattern.  */
-enum { special_tests_count = 7 };
-
-#if TEST_THREAD
-/* Called from test number 3-6 to trigger reloading of the
-   configuration.  */
-static void *
-special_test_call_res_init (void *closure)
-{
-  TEST_VERIFY (res_init () == 0);
-  return NULL;
-}
-#endif
+enum { special_tests_count = 11 };
 
 /* Implementation of special tests.  */
 static void
@@ -800,20 +812,29 @@ special_test_callback (void *closure)
     case 4:
     case 5:
     case 6:
-      /* Test res_init change broadcast.  This requires a second
-         thread to trigger the reload.  */
-#if TEST_THREAD
       support_write_file_string (_PATH_RESCONF,
                                  "options edns0\n"
                                  "nameserver 192.0.2.1\n");
+      goto reload_tests;
+    case 7: /* 7 and the following tests are with no-reload.  */
+    case 8:
+    case 9:
+    case 10:
+        support_write_file_string (_PATH_RESCONF,
+                                   "options edns0 no-reload\n"
+                                   "nameserver 192.0.2.1\n");
+        /* Fall through.  */
+    reload_tests:
       for (int iteration = 0; iteration < 2; ++iteration)
         {
           switch (test_index)
             {
             case 3:
+            case 7:
               TEST_VERIFY (res_init () == 0);
               break;
             case 4:
+            case 8:
               {
                 unsigned char buf[512];
                 TEST_VERIFY
@@ -822,37 +843,44 @@ special_test_callback (void *closure)
               }
               break;
             case 5:
+            case 9:
               gethostbyname (test_hostname);
               break;
             case 6:
+            case 10:
               {
                 struct addrinfo *ai;
                 (void) getaddrinfo (test_hostname, NULL, NULL, &ai);
               }
               break;
             }
-          if (iteration == 0)
+          /* test_index == 7 is res_init and performs a reload even
+             with no-reload.  */
+          if (iteration == 0 || test_index > 7)
             {
               TEST_VERIFY (_res.options & RES_USE_EDNS0);
               TEST_VERIFY (!(_res.options & RES_ROTATE));
+              if (test_index < 7)
+                TEST_VERIFY (!(_res.options & RES_NORELOAD));
+              else
+                TEST_VERIFY (_res.options & RES_NORELOAD);
               TEST_VERIFY (_res.nscount == 1);
+              /* File change triggers automatic reloading.  */
               support_write_file_string (_PATH_RESCONF,
                                          "options rotate\n"
                                          "nameserver 192.0.2.1\n"
                                          "nameserver 192.0.2.2\n");
-              xpthread_join (xpthread_create
-                             (NULL, special_test_call_res_init, NULL));
             }
           else
             {
-              /* edns0 was dropped, but the flag is not cleared.  See
-                 bug 21701.  */
-              /* TEST_VERIFY (!(_res.options & RES_USE_EDNS0)); */
+              if (test_index != 3 && test_index != 7)
+                /* test_index 3, 7 are res_init; this function does
+                   not reset flags.  See bug 21701.  */
+                TEST_VERIFY (!(_res.options & RES_USE_EDNS0));
               TEST_VERIFY (_res.options & RES_ROTATE);
               TEST_VERIFY (_res.nscount == 2);
             }
         }
-#endif
       break;
     }
 }