From 1e9f3547e22f52605796bc21ccdec05a881fb209 Mon Sep 17 00:00:00 2001 Message-Id: <1e9f3547e22f52605796bc21ccdec05a881fb209.1390394207.git.jdenemar@redhat.com> From: Eric Blake Date: Mon, 20 Jan 2014 09:03:25 -0700 Subject: [PATCH] build: fix build with latest rawhide kernel headers https://bugzilla.redhat.com/show_bug.cgi?id=1042937 Bother those kernel developers. In the latest rawhide, kernel and glibc have now been unified so that and no longer clash; but is still not self-contained. Because of the latest header change, the build is failing with: checking for linux/param.h... no configure: error: You must install kernel-headers in order to compile libvirt with QEMU or LXC support with details: In file included from conftest.c:561:0: /usr/include/linux/in6.h:71:18: error: field 'flr_dst' has incomplete type struct in6_addr flr_dst; We need a workaround to avoid our workaround :) * configure.ac (NETINET_LINUX_WORKAROUND): New test. * src/util/virnetdevbridge.c (includes): Use it. Signed-off-by: Eric Blake (cherry picked from commit e62e0094dcd0ca1484491a9cc62919473b647f11) Signed-off-by: Jiri Denemark --- configure.ac | 39 +++++++++++++++++++++++++++++---------- src/util/virnetdevbridge.c | 24 ++++++++++++++---------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/configure.ac b/configure.ac index a000dcb..eb20f1c 100644 --- a/configure.ac +++ b/configure.ac @@ -996,18 +996,37 @@ dnl check for kernel headers required by src/bridge.c dnl if test "$with_linux" = "yes"; then if test "$with_qemu" = "yes" || test "$with_lxc" = "yes" ; then + # Various kernel versions have headers that are not self-standing, but + # yet are incompatible with the corresponding glibc headers. In order + # to guarantee compilation across a wide range of versions (from RHEL 5 + # to rawhide), we first have to probe whether glibc and kernel can be + # used in tandem; and if not, provide workarounds that ensure that + # ABI-compatible IPv6 types are present for use by the kernel headers. + # These probes mirror the usage in virnetdevbridge.c + AC_CACHE_CHECK( + [whether and headers are compatible], + [lv_cv_netinet_linux_compatible], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]])], + [lv_cv_netinet_linux_compatible=yes], + [lv_cv_netinet_linux_compatible=no])]) + if test "x$lv_cv_netinet_linux_compatible" != xyes; then + AC_DEFINE([NETINET_LINUX_WORKAROUND], [1], + [define to 1 if Linux kernel headers require a workaround to avoid + compilation errors when mixed with glibc netinet headers]) + fi AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h linux/if_tun.h],, [AC_MSG_ERROR([You must install kernel-headers in order to compile libvirt with QEMU or LXC support])], - [[/* The kernel folks broke their headers when used with particular - * glibc versions; although the structs are ABI compatible, the - * C type system doesn't like struct redefinitions. We work around - * the problem here in the same manner as in virnetdevbridge.c. */ - #include - #define in6_addr in6_addr_ - #define sockaddr_in6 sockaddr_in6_ - #define ipv6_mreq ipv6_mreq_ - #define in6addr_any in6addr_any_ - #define in6addr_loopback in6addr_loopback_ + [[#include + #if NETINET_LINUX_WORKAROUND + # define in6_addr in6_addr_ + # define sockaddr_in6 sockaddr_in6_ + # define ipv6_mreq ipv6_mreq_ + # define in6addr_any in6addr_any_ + # define in6addr_loopback in6addr_loopback_ + #endif #include ]]) fi diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c index e4daa27..1a3740a 100644 --- a/src/util/virnetdevbridge.c +++ b/src/util/virnetdevbridge.c @@ -39,22 +39,26 @@ #ifdef __linux__ # include # include /* HZ */ +# if NETINET_LINUX_WORKAROUND /* Depending on the version of kernel vs. glibc, there may be a collision * between and kernel IPv6 structures. The different types * are ABI compatible, but choke the C type system; work around it by * using temporary redefinitions. */ -# define in6_addr in6_addr_ -# define sockaddr_in6 sockaddr_in6_ -# define ipv6_mreq ipv6_mreq_ -# define in6addr_any in6addr_any_ -# define in6addr_loopback in6addr_loopback_ +# define in6_addr in6_addr_ +# define sockaddr_in6 sockaddr_in6_ +# define ipv6_mreq ipv6_mreq_ +# define in6addr_any in6addr_any_ +# define in6addr_loopback in6addr_loopback_ +# endif # include # include /* SYSFS_BRIDGE_ATTR */ -# undef in6_addr -# undef sockaddr_in6 -# undef ipv6_mreq -# undef in6addr_any -# undef in6addr_loopback +# if NETINET_LINUX_WORKAROUND +# undef in6_addr +# undef sockaddr_in6 +# undef ipv6_mreq +# undef in6addr_any +# undef in6addr_loopback +# endif # define JIFFIES_TO_MS(j) (((j)*1000)/HZ) # define MS_TO_JIFFIES(ms) (((ms)*HZ)/1000) -- 1.8.5.3