On Wed, Dec 16, 2009 at 06:46:52PM +0000, Daniel P. Berrange wrote: > GNUTLS uses gcrypt for its crypto functions. gcrypt requires > that the app/library initializes threading before using it. > We don't want to force apps using libvirt to know about > gcrypt, so we make virInitialize init threading on their > behalf. This location also ensures libvirtd has initialized > it correctly. This initialization is required even if libvirt > itself were only using one thread, since another non-libvirt > library (eg GTK-VNC) could also be using gcrypt from another > thread > > * src/libvirt.c: Register thread functions for gcrypt > * configure.in: Add -lgcrypt to linker flags > --- > build-aux/.gitignore | 2 + > configure.in | 4 ++- > src/libvirt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 58 insertions(+), 1 deletions(-) > > diff --git a/build-aux/.gitignore b/build-aux/.gitignore > index 72e8ffc..a1b5d3b 100644 > --- a/build-aux/.gitignore > +++ b/build-aux/.gitignore > @@ -1 +1,3 @@ > * > +/link-warning.h > +/mktempd > diff --git a/configure.in b/configure.in > index 6ed2efd..c86ee97 100644 > --- a/configure.in > +++ b/configure.in > @@ -547,7 +547,9 @@ if test "$GNUTLS_FOUND" = "no"; then > test $fail = 1 && > AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt]) > > - GNUTLS_LIBS=$LIBS > + dnl Not all versions of gnutls include -lgcrypt, and so we add > + dnl it explicitly for the calls to gcry_control/check_version > + GNUTLS_LIBS="$LIBS -lgcrypt" > LIBS="$old_libs" > fi > > diff --git a/src/libvirt.c b/src/libvirt.c > index 103b331..cad33c2 100644 > --- a/src/libvirt.c > +++ b/src/libvirt.c > @@ -22,6 +22,7 @@ > #include <sys/wait.h> > #endif > #include <time.h> > +#include <gcrypt.h> > > #include <libxml/parser.h> > #include <libxml/xpath.h> > @@ -251,6 +252,55 @@ winsock_init (void) > } > #endif > > +static int virTLSMutexInit (void **priv) > +{ \ > + virMutexPtr lock = NULL; > + > + if (VIR_ALLOC(lock) < 0) > + return ENOMEM; > + > + if (virMutexInit(lock) < 0) { > + VIR_FREE(lock); > + return errno; > + } > + > + *priv = lock; > + return 0; > +} > + > +static int virTLSMutexDestroy(void **priv) > +{ > + virMutexPtr lock = *priv; > + virMutexDestroy(lock); > + VIR_FREE(lock); > + return 0; > +} > + > +static int virTLSMutexLock(void **priv) > +{ > + virMutexPtr lock = *priv; > + virMutexLock(lock); > + return 0; > +} > + > +static int virTLSMutexUnlock(void **priv) > +{ > + virMutexPtr lock = *priv; > + virMutexUnlock(lock); > + return 0; > +} > + > +static struct gcry_thread_cbs virTLSThreadImpl = { > + (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), > + NULL, > + virTLSMutexInit, > + virTLSMutexDestroy, > + virTLSMutexLock, > + virTLSMutexUnlock, > + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL > +}; > + > + > /** > * virInitialize: > * > @@ -273,6 +323,9 @@ virInitialize(void) > virRandomInitialize(time(NULL) ^ getpid())) > return -1; > > + gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl); > + gcry_check_version(NULL); > + > virLogSetFromEnv(); > > DEBUG0("register drivers"); Ah, subtle, I wonder how you realized that though :-) ACK Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list