Skip to content

Commit 582f290

Browse files
authored
Merge pull request #1014 from ggouaillardet/poc/libnl_version_check
configury: check libnl version and warn in case of conflict
2 parents b1aedf4 + f2a80dc commit 582f290

File tree

7 files changed

+339
-108
lines changed

7 files changed

+339
-108
lines changed

config/opal_check_libnl.m4

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
dnl -*- shell-script -*-
2+
dnl
3+
dnl Copyright (c) 2015-2016 Research Organization for Information Science
4+
dnl and Technology (RIST). All rights reserved.
5+
dnl $COPYRIGHT$
6+
dnl
7+
dnl Additional copyrights may follow
8+
dnl
9+
dnl $HEADER$
10+
dnl
11+
12+
dnl
13+
dnl More libnl v1/v3 sadness: the two versions are not compatible
14+
dnl and will not work correctly if simultaneously linked into the
15+
dnl same applications. Unfortunately, they *will* link into the
16+
dnl same image! On platforms like CentOS 7, libibverbs depends on
17+
dnl libnl-3.so.200 and friends, so if libnl3-devel packages are not
18+
dnl installed, but libnl-devel are, Open MPI should not try to use libnl.
19+
dnl
20+
dnl GROSS: libnl wants us to either use pkg-config (which we
21+
dnl can't assume is always present) or we need to look in a
22+
dnl particular directory for the right libnl3 include files. For
23+
dnl now, just hard code the special path into this logic.
24+
dnl
25+
dnl _OPAL_CHECK_PACKAGE_LIB() invokes OPAL_LIBNL_SANITY_CHECK() in order
26+
dnl to keep track of which libraries depend on libnl and which libraries
27+
dnl depend on libnl3.
28+
dnl Open MPI will not be able to build a component vs a given version of libnl
29+
dnl if the other libnl version is required by some third party components.
30+
dnl At the end of configure, display a summary of who is using what, and aborts
31+
dnl if both libnl versions are required.
32+
33+
dnl OPAL_LIBNL_SANITY_INIT()
34+
dnl --------------------------------------------------------------------
35+
AC_DEFUN([OPAL_LIBNL_SANITY_INIT], [
36+
opal_libnl_version=0
37+
opal_libnlv1_libs=
38+
opal_libnlv3_libs=
39+
AC_ARG_WITH([libnl],
40+
[AC_HELP_STRING([--with-libnl(=DIR)],
41+
[Directory prefix for libnl (typically only necessary if libnl is installed in a location that the compiler/linker will not search by default)])])
42+
43+
# The --with options carry two pieces of information: 1) do
44+
# you want a specific version of libnl, and 2) where that
45+
# version of libnl lives. For simplicity, let's separate
46+
# those two pieces of information.
47+
case "$with_libnl" in
48+
no)
49+
# Nope, don't want it
50+
opal_want_libnl=no
51+
;;
52+
"")
53+
# Just try to build with libnl
54+
opal_want_libnl=try
55+
opal_libnl_location=
56+
;;
57+
yes)
58+
# Yes, definitely want it
59+
opal_want_libnl=yes
60+
opal_libnl_location=
61+
;;
62+
*)
63+
# Yes, definitely want it -- at a specific location
64+
opal_want_libnl=yes
65+
opal_libnl_location=$with_libnl
66+
;;
67+
esac
68+
])
69+
70+
dnl OPAL_LIBNL_SANITY_CHECK(lib, function, LIBS)
71+
dnl --------------------------------------------------------------------
72+
AC_DEFUN([OPAL_LIBNL_SANITY_CHECK], [
73+
case $host in
74+
*linux*)
75+
OPAL_VAR_SCOPE_PUSH([ldd_output libnl_version])
76+
AC_LANG_PUSH(C)
77+
cat > conftest_c.$ac_ext << EOF
78+
extern void $2 (void);
79+
int main(int argc, char *argv[[]]) {
80+
$2 ();
81+
return 0;
82+
}
83+
EOF
84+
OPAL_LOG_COMMAND([$CC -o conftest $CFLAGS $CPPFLAGS conftest_c.$ac_ext $LDFLAGS -l$1 $LIBS $3],
85+
[ldd_output=`ldd conftest`
86+
libnl_version=0
87+
AS_IF([echo $ldd_output | grep -q libnl.so],
88+
[AS_IF([test $opal_libnl_version -eq 3],
89+
[AC_MSG_WARN([lib nl version conflict: $opal_libnlv3_libs requires libnl-3 whereas $1 requires libnl])],
90+
[opal_libnlv1_libs="$opal_libnlv1_libs $1"
91+
OPAL_UNIQ([opal_libnlv1_libs])
92+
opal_libnl_version=1])
93+
libnl_version=1])
94+
AS_IF([echo $ldd_output | grep -q libnl-3.so],
95+
[AS_IF([test $libnl_version -eq 1],
96+
[AC_MSG_WARN([lib $1 requires both libnl v1 and libnl v3 -- yoinks!])
97+
AC_MSG_WARN([This is a configuration that is known to cause run-time crashes])
98+
AC_MSG_ERROR([Cannot continue])])
99+
AS_IF([test $opal_libnl_version -eq 1],
100+
[AC_MSG_WARN([lib nl version conflict: $opal_libnlv1_libs requires libnl whereas $1 requires libnl-3])],
101+
[opal_libnlv3_libs="$opal_libnlv3_libs $1"
102+
OPAL_UNIQ([opal_libnlv3_libs])
103+
opal_libnl_version=3])])
104+
rm -f conftest conftest_c.$ac_ext],
105+
[AC_MSG_WARN([Could not link a simple program with lib $1])])
106+
AC_LANG_POP(C)
107+
OPAL_VAR_SCOPE_POP([ldd_output libnl_version])
108+
;;
109+
esac
110+
])
111+
112+
dnl
113+
dnl Check for libnl-3.
114+
dnl
115+
dnl Inputs:
116+
dnl
117+
dnl $1: prefix where to look for libnl-3
118+
dnl $2: var name prefix of _CPPFLAGS and _LDFLAGS and _LIBS
119+
dnl
120+
dnl Outputs:
121+
dnl
122+
dnl - Set $2_CPPFLAGS necessary to compile with libnl-3
123+
dnl - Set $2_LDFLAGS necessary to link with libnl-3
124+
dnl - Set $2_LIBS necessary to link with libnl-3
125+
dnl - Set OPAL_HAVE_LIBNL3 1 if libnl-3 will be used
126+
dnl
127+
AC_DEFUN([OPAL_CHECK_LIBNL_V3],[
128+
OPAL_VAR_SCOPE_PUSH([CPPFLAGS_save opal_tmp_CPPFLAGS LIBS_save LDFLAGS_save])
129+
AC_MSG_NOTICE([checking for libnl v3])
130+
131+
AS_IF([test "$opal_want_libnl" != "no"],
132+
[AS_IF([test -z "$opal_libnl_location"],
133+
[AC_MSG_CHECKING([for /usr/include/libnl3])
134+
AS_IF([test -d "/usr/include/libnl3"],
135+
[opal_tmp_CPPFLAGS=-I/usr/include/libnl3
136+
opal_libnlv3_happy=1
137+
AC_MSG_RESULT([found])],
138+
[AC_MSG_RESULT([not found])
139+
AC_MSG_CHECKING([for /usr/local/include/libnl3])
140+
AS_IF([test -d "/usr/local/include/libnl3"],
141+
[opal_tmp_CPPFLAGS=-I/usr/local/include/netlink3
142+
opal_libnlv3_happy=1
143+
AC_MSG_RESULT([found])],
144+
[opal_libnlv3_happy=0
145+
AC_MSG_RESULT([not found])])])],
146+
[AC_MSG_CHECKING([for $1/include/libnl3])
147+
AS_IF([test -d "$1/include/libnl3"],
148+
[opal_tmp_CPPFLAGS="-I$1/include/libnl3"
149+
opal_libnlv3_happy=1
150+
AC_MSG_RESULT([found])],
151+
[opal_libnlv3_happy=0
152+
AC_MSG_RESULT([not found])])])
153+
CPPFLAGS_save=$CPPFLAGS
154+
CPPFLAGS="$opal_tmp_CPPFLAGS $CPPFLAGS"
155+
156+
# Random note: netlink/version.h is only in libnl v3 - it is not in libnl v1.
157+
# Also, nl_recvmsgs_report is only in libnl v3.
158+
AS_IF([test $opal_libnlv3_happy -eq 1],
159+
[OPAL_CHECK_PACKAGE([$2],
160+
[netlink/version.h],
161+
[nl-3],
162+
[nl_recvmsgs_report],
163+
[],
164+
[$1],
165+
[],
166+
[],
167+
[opal_libnlv3_happy=0])
168+
169+
# Note that OPAL_CHECK_PACKAGE is going to add
170+
# -I$dir/include into $2_CPPFLAGS. But because libnl v3
171+
# puts the headers in $dir/include/libnl3, we need to
172+
# overwrite $2_CPPFLAGS with -I$dir/include/libnl3. We can do
173+
# this unconditionally; we don't have to check for
174+
# success (checking for success occurs below).
175+
$2_CPPFLAGS=$opal_tmp_CPPFLAGS])
176+
177+
# If we found libnl-3, we *also* need libnl-route-3
178+
LIBS_save=$LIBS
179+
LDFLAGS_save=$LDFLAGS
180+
AS_IF([test -n "$$2_LDFLAGS"],
181+
[LDFLAGS="$$2_LDFLAGS $LDFLAGS"])
182+
AS_IF([test $opal_libnlv3_happy -eq 1],
183+
[AC_SEARCH_LIBS([nl_rtgen_request],
184+
[nl-route-3],
185+
[],
186+
[opal_libnlv3_happy=0])])
187+
LIBS=$LIBS_save
188+
LDFLAGS=$LDFLAGS_save
189+
190+
# Just because libnl* is evil, double check that the
191+
# netlink/version.h we found was for libnl v3. As far as we
192+
# know, netlink/version.h only first appeared in version
193+
# 3... but let's really be sure.
194+
AS_IF([test $opal_libnlv3_happy -eq 1],
195+
[AC_MSG_CHECKING([to ensure these really are libnl v3 headers])
196+
AS_IF([test -n "$$2_CPPFLAGS"],
197+
[CPPFLAGS="$$2_CPPFLAGS $CPPFLAGS"])
198+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
199+
#include <netlink/netlink.h>
200+
#include <netlink/version.h>
201+
#ifndef LIBNL_VER_MAJ
202+
#error "LIBNL_VER_MAJ not defined!"
203+
#endif
204+
/* to the best of our knowledge, version.h only exists in libnl v3 */
205+
#if LIBNL_VER_MAJ != 3
206+
#error "LIBNL_VER_MAJ != 3, I am sad"
207+
#endif
208+
]])],
209+
[AC_MSG_RESULT([yes])],
210+
[AC_MSG_RESULT([no])
211+
opal_libnlv3_happy=0])])
212+
213+
CPPFLAGS=$CPPFLAGS_save],
214+
215+
[opal_libnlv3_happy=0])
216+
217+
# If we found everything
218+
AS_IF([test $opal_libnlv3_happy -eq 1],
219+
[$2_LIBS="-lnl-3 -lnl-route-3"
220+
OPAL_HAVE_LIBNL3=1])
221+
222+
OPAL_VAR_SCOPE_POP
223+
])
224+
225+
dnl
226+
dnl Check for libnl.
227+
dnl
228+
dnl Inputs:
229+
dnl
230+
dnl $1: prefix where to look for libnl
231+
dnl $2: var name prefix of _CPPFLAGS and _LDFLAGS and _LIBS
232+
dnl
233+
dnl Outputs:
234+
dnl
235+
dnl - Set $2_CPPFLAGS necessary to compile with libnl
236+
dnl - Set $2_LDFLAGS necessary to link with libnl
237+
dnl - Set $2_LIBS necessary to link with libnl
238+
dnl - Set OPAL_HAVE_LIBNL3 0 if libnl will be used
239+
dnl
240+
AC_DEFUN([OPAL_CHECK_LIBNL_V1],[
241+
AC_MSG_NOTICE([checking for libnl v1])
242+
243+
AS_IF([test "$opal_want_libnl" != "no"],
244+
[OPAL_CHECK_PACKAGE([$2],
245+
[netlink/netlink.h],
246+
[nl],
247+
[nl_connect],
248+
[-lm],
249+
[$1],
250+
[],
251+
[opal_libnlv1_happy=1],
252+
[opal_libnlv1_happy=0])],
253+
[opal_libnlv1_happy=0])
254+
255+
AS_IF([test $opal_libnlv1_happy -eq 1],
256+
[$2_LIBS="-lnl -lm"
257+
OPAL_HAVE_LIBNL3=0])
258+
])
259+
260+
dnl
261+
dnl Summarize libnl and libnl3 usage,
262+
dnl and abort if conflict is found
263+
dnl
264+
dnl Print the list of libraries that use libnl,
265+
dnl the list of libraries that use libnl3,
266+
dnl and aborts if both libnl and libnl3 are used.
267+
dnl
268+
AC_DEFUN([OPAL_CHECK_LIBNL_SUMMARY],[
269+
AC_MSG_CHECKING([for libraries that use libnl v1])
270+
AS_IF([test -n "$opal_libnlv1_libs"],
271+
[AC_MSG_RESULT([$opal_libnlv1_libs])],
272+
[AC_MSG_RESULT([(none)])])
273+
AC_MSG_CHECKING([for libraries that use libnl v3])
274+
AS_IF([test -n "$opal_libnlv3_libs"],
275+
[AC_MSG_RESULT([$opal_libnlv3_libs])],
276+
[AC_MSG_RESULT([(none)])])
277+
AS_IF([test -n "$opal_libnlv1_libs" && test -n "$opal_libnlv3_libs"],
278+
[AC_MSG_WARN([libnl v1 and libnl v3 have been found as dependent libraries])
279+
AC_ERROR([This is a configuration that is known to cause run-time crashes])])
280+
])

config/opal_check_package.m4

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ AC_DEFUN([_OPAL_CHECK_PACKAGE_LIB], [
138138
test "$ac_cv_search_$3" != "none required"],
139139
[$1_LIBS="$ac_cv_search_$3 $4"],
140140
[$1_LIBS="$4"])
141+
# libnl v1 and libnl3 are known *not* to coexist
142+
# for each library, figure out whether it depends on libnl or libnl3 or none
143+
# so conflicts can be reported and/or prevented
144+
OPAL_LIBNL_SANITY_CHECK([$2], [$3], [$$1_LIBS])
141145
$7],
142146
[$8])
143147

config/opal_functions.m4

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ dnl Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
1414
dnl Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
1515
dnl Copyright (c) 2009-2015 Cisco Systems, Inc. All rights reserved.
1616
dnl Copyright (c) 2014 Intel, Inc. All rights reserved.
17-
dnl Copyright (c) 2015 Research Organization for Information Science
17+
dnl Copyright (c) 2015-2016 Research Organization for Information Science
1818
dnl and Technology (RIST). All rights reserved.
1919
dnl
2020
dnl $COPYRIGHT$
@@ -98,6 +98,8 @@ OPAL_CONFIGURE_USER="`whoami`"
9898
OPAL_CONFIGURE_HOST="`hostname | head -n 1`"
9999
OPAL_CONFIGURE_DATE="`date`"
100100

101+
OPAL_LIBNL_SANITY_INIT
102+
101103
#
102104
# Save these details so that they can be used in opal_info later
103105
#

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,8 @@ m4_ifdef([project_orte], [ORTE_CONFIG_FILES])
14491449
m4_ifdef([project_ompi], [OMPI_CONFIG_FILES])
14501450
m4_ifdef([project_oshmem], [OSHMEM_CONFIG_FILES])
14511451
1452+
OPAL_CHECK_LIBNL_SUMMARY
1453+
14521454
AC_OUTPUT
14531455
14541456
OPAL_SUMMARY_PRINT

opal/mca/reachable/netlink/Makefile.am

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#
22
# Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
3+
# Copyright (c) 2016 Research Organization for Information Science
4+
# and Technology (RIST). All rights reserved.
35
# $COPYRIGHT$
46
#
57
# Additional copyrights may follow
@@ -29,16 +31,16 @@ component_install =
2931
endif
3032

3133
AM_CPPFLAGS = \
32-
$(opal_reachable_netlink_LIBNL_CPPFLAGS) \
33-
-DHAVE_LIBNL3=$(HAVE_LIBNL3)
34+
$(opal_reachable_netlink_CPPFLAGS) \
35+
-DOPAL_HAVE_LIBNL3=$(OPAL_HAVE_LIBNL3)
3436

3537
mcacomponentdir = $(opallibdir)
3638
mcacomponent_LTLIBRARIES = $(component_install)
3739
mca_reachable_netlink_la_SOURCES = $(sources)
3840
mca_reachable_netlink_la_LDFLAGS = -module -avoid-version
39-
mca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBNL_LIBS)
41+
mca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBS)
4042

4143
noinst_LTLIBRARIES = $(component_noinst)
4244
libmca_reachable_netlink_la_SOURCES =$(sources)
4345
libmca_reachable_netlink_la_LDFLAGS = -module -avoid-version
44-
libmca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBNL_LIBS)
46+
libmca_reachable_netlink_la_LIBADD = $(opal_reachable_netlink_LIBS)

0 commit comments

Comments
 (0)