]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
tests: avoid test failure on rawhide gnutls
authorEric Blake <eblake@redhat.com>
Fri, 6 Jan 2012 21:07:23 +0000 (14:07 -0700)
committerEric Blake <eblake@redhat.com>
Fri, 6 Jan 2012 21:24:32 +0000 (14:24 -0700)
I hit a VERY weird testsuite failure on rawhide, which included
_binary_ output to stderr, followed by a hang waiting for me
to type something! (Here, using ^@ for NUL):

$ ./commandtest
TEST: commandtest
      WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
.WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
.WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
WARNING: gnome-keyring:: couldn't send data: Bad file descriptor
.8^@^@^@8^@^@^@^A^@^@^@^Bay^A^@^@^@)PRIVATE-GNOME-KEYRING-PKCS11-PROTOCOL-V-1

I finally traced it to the fact that gnome-keyring, called via
gnutls_global_init which is turn called by virNetTLSInit, opens
an internal fd that it expects to communicate to via a
pthread_atfork handler (never mind that it violates POSIX by
using non-async-signal-safe functions in that handler:
https://bugzilla.redhat.com/show_bug.cgi?id=772320).

Our problem stems from the fact that we pulled the rug out from
under the library's expectations by closing an fd that it had
just opened.  While we aren't responsible for fixing the bugs
in that pthread_atfork handler, we can at least avoid the bugs
by not closing the fd in the first place.

* tests/commandtest.c (mymain): Avoid closing fds that were opened
by virInitialize.

tests/commandtest.c

index efc48fe20fbd04ec6e335dd89b5da04c45aac63f..b4b6044a668ccfbe1feeb9b782b505a0b840b186 100644 (file)
@@ -784,6 +784,22 @@ mymain(void)
     setpgid(0, 0);
     setsid();
 
+    /* Our test expects particular fd values; to get that, we must not
+     * leak fds that we inherited from a lazy parent.  At the same
+     * time, virInitialize may open some fds (perhaps via third-party
+     * libraries that it uses), and we must not kill off an fd that
+     * this process opens as it might break expectations of a
+     * pthread_atfork handler, as well as interfering with our tests
+     * trying to ensure we aren't leaking to our children.  The
+     * solution is to do things in two phases - reserve the fds we
+     * want by overwriting any externally inherited fds, then
+     * initialize, then clear the slots for testing.  */
+    if ((fd = open("/dev/null", O_RDONLY)) < 0 ||
+        dup2(fd, 3) < 0 ||
+        dup2(fd, 4) < 0 ||
+        dup2(fd, 5) < 0 ||
+        (fd > 5 && VIR_CLOSE(fd) < 0))
+        return EXIT_FAILURE;
 
     /* Prime the debug/verbose settings from the env vars,
      * since we're about to reset 'environ' */
@@ -791,8 +807,8 @@ mymain(void)
     virTestGetVerbose();
 
     virInitialize();
-    /* Kill off any inherited fds that might interfere with our
-     * testing.  */
+
+    /* Phase two of killing interfering fds; see above.  */
     fd = 3;
     VIR_FORCE_CLOSE(fd);
     fd = 4;