[libvirt] [PATCHv2] build: avoid -lgcrypt with newer gnutls

Doug Goldstein cardoe at gentoo.org
Sat Jul 27 01:22:29 UTC 2013


On Fri, Jul 26, 2013 at 5:04 PM, Eric Blake <eblake at redhat.com> wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=951637
>
> Newer gnutls uses nettle, rather than gcrypt, which is a lot nicer
> regarding initialization.  Yet we were unconditionally initializing
> gcrypt even when gnutls wouldn't be using it, and having two crypto
> libraries linked into libvirt.so is pointless.
>
> Assume that the switch to gnutls 3.0 is a reliable witness, when
> pkg-config is present; otherwise be pessimistic and use gcrypt.
>
> * configure.ac (WITH_GNUTLS): Probe whether to add -lgcrypt, and
> define a witness WITH_GNUTLS_GCRYPT.
> * src/libvirt.c (virTLSMutexInit, virTLSMutexDestroy)
> (virTLSMutexLock, virTLSMutexUnlock, virTLSThreadImpl)
> (virGlobalInit): Honor the witness.
> * libvirt.spec.in (BuildRequires): Make gcrypt usage conditional,
> no longer needed in Fedora 19.
>
> Signed-off-by: Eric Blake <eblake at redhat.com>
> ---
>
> v2: use second pkg-config invocation rather than ldd to determine
> whether gnutls uses gcrypt
>
>  configure.ac    | 27 +++++++++++++++++++--------
>  libvirt.spec.in |  2 ++
>  src/libvirt.c   | 10 ++++++----
>  3 files changed, 27 insertions(+), 12 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index cc9942a..eb56b63 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -1076,12 +1076,19 @@ if test "x$with_gnutls" != "xno"; then
>    LIBS="$LIBS $GNUTLS_LIBS"
>
>    GNUTLS_FOUND=no
> +  GNUTLS_GCRYPT=no
>    if test -x "$PKG_CONFIG" ; then
> +    dnl double probe, since we know that gnutls 3.0 switched to nettle instead of
> +    dnl gcrypt
>      PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_REQUIRED,
> -      [GNUTLS_FOUND=yes], [GNUTLS_FOUND=no])
> +      [GNUTLS_FOUND=yes
> +       PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.0], [], [GNUTLS_GCRYPT=yes])],
> +      [GNUTLS_FOUND=no])
>    fi
>    if test "$GNUTLS_FOUND" = "no"; then
> +    dnl pkg-config couldn't help us, assume gcrypt is necessary
>      fail=0
> +    GNUTLS_GCRYPT=yes
>      AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1])
>      AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt])
>
> @@ -1098,13 +1105,17 @@ if test "x$with_gnutls" != "xno"; then
>        AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt])
>      fi
>    else
> -    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="$GNUTLS_LIBS -lgcrypt"
> -
> -    dnl We're not using gcrypt deprecated features so define
> -    dnl GCRYPT_NO_DEPRECATED to avoid deprecated warnings
> -    GNUTLS_CFLAGS="$GNUTLS_CFLAGS -DGCRYPT_NO_DEPRECATED"
> +    dnl If gnutls linked against -lgcrypt, then we must initialize gcrypt
> +    dnl prior to using gnutls.  Newer versions of gnutls use -lnettle, in
> +    dnl which case we don't want to drag in gcrypt ourselves.
> +    if test "$GNUTLS_GCRYPT" = yes; then
> +      GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt"
> +      dnl We're not using gcrypt deprecated features so define
> +      dnl GCRYPT_NO_DEPRECATED to avoid deprecated warnings
> +      GNUTLS_CFLAGS="$GNUTLS_CFLAGS -DGCRYPT_NO_DEPRECATED"
> +      AC_DEFINE_UNQUOTED([WITH_GNUTLS_GCRYPT], 1,
> +        [set to 1 if it is known or assumed that GNUTLS uses gcrypt])
> +    fi
>
>      dnl gnutls 3.x moved some declarations to a new header
>      AC_CHECK_HEADERS([gnutls/crypto.h], [], [], [[
> diff --git a/libvirt.spec.in b/libvirt.spec.in
> index e0e0004..4320281 100644
> --- a/libvirt.spec.in
> +++ b/libvirt.spec.in
> @@ -422,7 +422,9 @@ BuildRequires: readline-devel
>  BuildRequires: ncurses-devel
>  BuildRequires: gettext
>  BuildRequires: libtasn1-devel
> +%if (0%{?rhel} && 0%{?rhel} < 7) || (0%{?fedora} && 0%{?fedora} < 19)
>  BuildRequires: libgcrypt-devel
> +%endif
>  BuildRequires: gnutls-devel
>  BuildRequires: libattr-devel
>  %if %{with_libvirtd}
> diff --git a/src/libvirt.c b/src/libvirt.c
> index 8157488..66e8248 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -55,7 +55,9 @@
>  #include "intprops.h"
>  #include "virconf.h"
>  #if WITH_GNUTLS
> -# include <gcrypt.h>
> +# if WITH_GNUTLS_GCRYPT
> +#  include <gcrypt.h>
> +# endif
>  # include "rpc/virnettlscontext.h"
>  #endif
>  #include "vircommand.h"
> @@ -270,7 +272,7 @@ winsock_init(void)
>  #endif
>
>
> -#ifdef WITH_GNUTLS
> +#ifdef WITH_GNUTLS_GCRYPT
>  static int virTLSMutexInit(void **priv)
>  {
>      virMutexPtr lock = NULL;
> @@ -323,7 +325,7 @@ static struct gcry_thread_cbs virTLSThreadImpl = {
>      virTLSMutexUnlock,
>      NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
>  };
> -#endif
> +#endif /* WITH_GNUTLS_GCRYPT */
>
>  /* Helper macros to implement VIR_DOMAIN_DEBUG using just C99.  This
>   * assumes you pass fewer than 15 arguments to VIR_DOMAIN_DEBUG, but
> @@ -407,7 +409,7 @@ virGlobalInit(void)
>          virErrorInitialize() < 0)
>          goto error;
>
> -#ifdef WITH_GNUTLS
> +#ifdef WITH_GNUTLS_GCRYPT
>      /*
>       * This sequence of API calls it copied exactly from
>       * gnutls 2.12.23 source lib/gcrypt/init.c, with
> --
> 1.8.3.1
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

Hate to throw a monkey wrench in the plan, but GnuTLS 3.0 isn't the
nettle cut over. On my stable Gentoo box with GnuTLS 2.12.23, its
using nettle as seen by ldd.

 ldd /usr/lib64/libgnutls.so.26
	linux-vdso.so.1 (0x00007fffad3ff000)
	libnettle.so.4 => /usr/lib64/libnettle.so.4 (0x00007f60fa4f4000)
	libgmp.so.10 => /usr/lib64/libgmp.so.10 (0x00007f60fa284000)
	libhogweed.so.2 => /usr/lib64/libhogweed.so.2 (0x00007f60fa054000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f60f9e3e000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f60f9c21000)
	libtasn1.so.3 => /usr/lib64/libtasn1.so.3 (0x00007f60f9a0f000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f60f9661000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f60fa9ec000)

It appears it was an optional cutover and I guess Gentoo made the
plunge. Another idea, that you might hate would be to use pkg-config
directly and pass --static so we can get the private libraries. I'm
not running Fedora 19 yet so the best I can do is give you Fedora 18
as a comp, but that works out great since its using 2.12.23 as well.

stable Gentoo:

Name: GnuTLS
Description: Transport Security Layer implementation for the GNU system
URL: http://www.gnu.org/software/gnutls/
Version: 2.12.23
Libs: -L${libdir} -lgnutls
Libs.private:  -L/usr/lib64 -lnettle -lgmp -lhogweed
Requires.private: libtasn1 , zlib
Cflags: -I${includedir}

$ pkg-config --libs --static gnutls
-lgnutls -ltasn1 -lz -lnettle -lgmp -lhogweed

Fedora 18:

Name: GnuTLS
Description: Transport Security Layer implementation for the GNU system
URL: http://www.gnu.org/software/gnutls/
Version: 2.12.23
Libs: -L${libdir} -lgnutls
Libs.private: -L/usr/lib64 -lgcrypt -L/usr/lib64 -lgpg-error
Requires.private: libtasn1 , zlib, p11-kit-1
Cflags: -I${includedir}

$ pkg-config --libs --static gnutls
-lgnutls -lgcrypt -lgpg-error -ltasn1 -lz -lp11-kit

With GnuTLS 3.2 I get the following:

 pkg-config --libs --static gnutls
-lgnutls -lhogweed -lnettle -lz  -lgmp


Maybe that helps?
-- 
Doug Goldstein




More information about the libvir-list mailing list