]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Initialize gcrypt threading
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 17 Jul 2009 19:20:08 +0000 (20:20 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 17 Dec 2009 18:22:09 +0000 (18:22 +0000)
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
configure.in
src/libvirt.c

index 72e8ffc0db8aad71a934dd11e5968bd5109e54b4..a1b5d3bf74bc8a4176b2faf828068418d9454aef 100644 (file)
@@ -1 +1,3 @@
 *
+/link-warning.h
+/mktempd
index 6ed2efde58529222f5471f1458b8876797097322..c86ee97d35a37adad5bee4520e3c54f9be390839 100644 (file)
@@ -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
 
index 103b3312ddf1c816bc8886f2b7f849f965e7b214..cad33c2a7346d290f7d56f033736ab77c410c773 100644 (file)
@@ -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");