1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-22 17:34:18 +03:00

tests: avoid test failure on rawhide gnutls

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.
This commit is contained in:
Eric Blake 2012-01-06 14:07:23 -07:00
parent b41d440e61
commit 74ff57506c

View 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;