On Fri, Feb 17, 2012 at 03:46:17PM +0900, Simon Horman wrote:
> On Thu, Feb 16, 2012 at 04:53:35PM -0800, Ben Pfaff wrote:
> > On Thu, Feb 16, 2012 at 04:32:57PM -0800, Jesse Gross wrote:
> > > On Thu, Feb 16, 2012 at 10:36 AM, Ben Pfaff <b...@nicira.com> wrote:
> > > > OVS needs to inspect the headers in the kernel source directory at build
> > > > time.  Debian keeps moving the source directory relative to the build
> > > > directory and doesn't provide an obvious way to find the source 
> > > > directory,
> > > > so in the past we've used some name-based heuristics to essentially 
> > > > guess
> > > > where it is.
> > > >
> > > > This commit introduces a new heuristic that I hope will be more 
> > > > reliable:
> > > > extracting the source directory from the Makefile in the build 
> > > > directory.
> > > > In Debian's case, it looks like the Makefile generally contains a line 
> > > > of
> > > > the form "MAKEARGS := -C <srcdir> O=<outdir>".  This commit extracts the
> > > > source directory from that line.
> > > >
> > > > To avoid regressions this commit retains the older heuristics as 
> > > > fallbacks.
> > > >
> > > > CC: 659...@bugs.debian.org
> > > > Reported-by: Thomas Goirand <z...@debian.org>
> > > > Signed-off-by: Ben Pfaff <b...@nicira.com>
> > > 
> > > It seems OK to me.  
> > 
> > Thanks.  Pushed to master and branch-1.[2345].
> > 
> > > How do other packages solve this problem?  It
> > > seems like we have a particularly bad time.
> > 
> > I've been unable to locate other modules that do this kind of thing.
> > I looked at virtualbox, the nvidia drivers, ndiswrapper,
> > xtables-addons.
> 
> Curious.
> 
> I'm fine with your patch as it seems to improve things.
> But it would be nice not to have to jump thorough hoops like this.

Here's a different set of hoops.  Perhaps you like these better:

--8<--------------------------cut here-------------------------->8--

From: Ben Pfaff <b...@nicira.com>
Date: Fri, 17 Feb 2012 14:32:22 -0800
Subject: [PATCH] datapath: Use "make" instead of Autoconf to figure out kernel 
compat issues.

---
 acinclude.m4                    |  206 +--------------------------------------
 datapath/linux/.gitignore       |    2 +-
 datapath/linux/Kbuild.in        |  120 ++++++++++++++++++++++-
 datapath/linux/Makefile.main.in |    3 +-
 4 files changed, 122 insertions(+), 209 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 69bb772..d1347ef 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -32,15 +32,9 @@ AC_DEFUN([OVS_CHECK_LINUX], [
   AC_ARG_WITH([linux],
               [AC_HELP_STRING([--with-linux=/path/to/linux],
                               [Specify the Linux kernel build directory])])
-  AC_ARG_WITH([linux-source],
-              [AC_HELP_STRING([--with-linux-source=/path/to/linux-source],
-                              [Specify the Linux kernel source directory
-                              (usually figured out automatically from build
-                              directory)])])
 
-  # Deprecated equivalents to --with-linux, --with-linux-source.
+  # Deprecated equivalent to --with-linux.
   AC_ARG_WITH([l26])
-  AC_ARG_WITH([l26-source])
 
   if test X"$with_linux" != X; then
     KBUILD=$with_linux
@@ -51,19 +45,6 @@ AC_DEFUN([OVS_CHECK_LINUX], [
     KBUILD=
   fi
 
-  if test X"$KBUILD" != X; then
-    if test X"$with_linux_source" != X; then
-      KSRC=$with_linux_source
-    elif test X"$with_l26_source" != X; then
-      KSRC=$with_l26_source
-      AC_MSG_WARN([--with-l26-source is deprecated, please use 
--with-linux-source instead])
-    else
-      KSRC=
-    fi
-  elif test X"$with_linux_source" != X || test X"$with_l26_source" != X; then
-    AC_MSG_ERROR([Linux source directory may not be specified without Linux 
build directory])
-  fi
-
   if test -n "$KBUILD"; then
     KBUILD=`eval echo "$KBUILD"`
     case $KBUILD in
@@ -82,200 +63,15 @@ AC_DEFUN([OVS_CHECK_LINUX], [
        AC_ERROR([source dir $KBUILD doesn't exist])
     fi
 
-    # Debian breaks kernel headers into "source" header and "build" headers.
-    # We want the source headers, but $KBUILD gives us the "build" headers.
-    # Use heuristics to find the source headers.
-    AC_MSG_CHECKING([for Linux source directory])
-    if test -n "$KSRC"; then
-      KSRC=`eval echo "$KSRC"`
-      case $KSRC in
-          /*) ;;
-          *) KSRC=`pwd`/$KSRC ;;
-      esac
-      if test ! -e $KSRC/include/linux/kernel.h; then
-        AC_MSG_ERROR([$KSRC is not a kernel source directory])
-      fi
-    else
-      KSRC=$KBUILD
-      if test ! -e $KSRC/include/linux/kernel.h; then
-        # Debian kernel build Makefiles tend to include a line of the form:
-        # MAKEARGS := -C /usr/src/linux-headers-3.2.0-1-common 
O=/usr/src/linux-headers-3.2.0-1-486
-        # First try to extract the source directory from this line.
-        KSRC=`sed -n 's/.*-C \([[^ ]]*\).*/\1/p' "$KBUILD"/Makefile`
-        if test ! -e "$KSRC"/include/linux/kernel.h; then
-          # Didn't work.  Fall back to name-based heuristics that used to work.
-          case `echo "$KBUILD" | sed 's,/*$,,'` in # (
-            */build)
-              KSRC=`echo "$KBUILD" | sed 's,/build/*$,/source,'`
-              ;; # (
-            *)
-              KSRC=`(cd $KBUILD && pwd -P) | sed 's,-[[^-]]*$,-common,'`
-              ;;
-          esac
-        fi
-      fi
-      if test ! -e "$KSRC"/include/linux/kernel.h; then
-        AC_MSG_ERROR([cannot find source directory (please use 
--with-linux-source)])
-      fi
-    fi
-    AC_MSG_RESULT([$KSRC])
-
-    AC_MSG_CHECKING([for kernel version])
-    version=`sed -n 's/^VERSION = //p' "$KSRC/Makefile"`
-    patchlevel=`sed -n 's/^PATCHLEVEL = //p' "$KSRC/Makefile"`
-    sublevel=`sed -n 's/^SUBLEVEL = //p' "$KSRC/Makefile"`
-    if test X"$version" = X || test X"$patchlevel" = X; then
-       AC_ERROR([cannot determine kernel version])
-    elif test X"$sublevel" = X; then
-       kversion=$version.$patchlevel
-    else
-       kversion=$version.$patchlevel.$sublevel
-    fi
-    AC_MSG_RESULT([$kversion])
-
-    if test "$version" -ge 3; then
-       : # Linux 3.x
-    elif test "$version" = 2 && test "$patchlevel" -ge 6; then
-       : # Linux 2.6.x
-    else
-       if test "$KBUILD" = "$KSRC"; then
-         AC_ERROR([Linux kernel in $KBUILD is version $kversion, but version 
2.6 or later is required])
-       else
-         AC_ERROR([Linux kernel in build tree $KBUILD (source tree $KSRC) is 
version $kversion, but version 2.6 or later is required])
-       fi
-    fi
     if test ! -e "$KBUILD"/include/linux/version.h || \
        (test ! -e "$KBUILD"/include/linux/autoconf.h && \
         test ! -e "$KBUILD"/include/generated/autoconf.h); then
        AC_MSG_ERROR([Linux kernel source in $KBUILD is not configured])
     fi
-    OVS_CHECK_LINUX_COMPAT
   fi
   AM_CONDITIONAL(LINUX_ENABLED, test -n "$KBUILD")
 ])
 
-dnl OVS_GREP_IFELSE(FILE, REGEX, [IF-MATCH], [IF-NO-MATCH])
-dnl
-dnl Greps FILE for REGEX.  If it matches, runs IF-MATCH, otherwise IF-NO-MATCH.
-dnl If IF-MATCH is empty then it defines to OVS_DEFINE(HAVE_<REGEX>), with
-dnl <REGEX> translated to uppercase.
-AC_DEFUN([OVS_GREP_IFELSE], [
-  AC_MSG_CHECKING([whether $2 matches in $1])
-  if test -f $1; then
-    grep '$2' $1 >/dev/null 2>&1
-    status=$?
-    case $status in
-      0) 
-        AC_MSG_RESULT([yes])
-        m4_if([$3], [], [OVS_DEFINE([HAVE_]m4_toupper([$2]))], [$3])
-        ;;
-      1) 
-        AC_MSG_RESULT([no])
-        $4
-        ;;
-      *) 
-        AC_MSG_ERROR([grep exited with status $status])
-        ;;
-    esac
-  else
-    AC_MSG_RESULT([file not found])
-    $4
-  fi
-])
-
-dnl OVS_DEFINE(NAME)
-dnl
-dnl Defines NAME to 1 in kcompat.h.
-AC_DEFUN([OVS_DEFINE], [
-  echo '#define $1 1' >> datapath/linux/kcompat.h.new
-])
-
-AC_DEFUN([OVS_CHECK_LOG2_H], [
-  AC_MSG_CHECKING([for $KSRC/include/linux/log2.h])
-  if test -e $KSRC/include/linux/log2.h; then
-    AC_MSG_RESULT([yes])
-    OVS_DEFINE([HAVE_LOG2_H])
-  else
-    AC_MSG_RESULT([no])
-  fi
-])
-
-dnl OVS_CHECK_LINUX_COMPAT
-dnl
-dnl Runs various Autoconf checks on the Linux 2.6 kernel source in
-dnl the directory in $KBUILD.
-AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
-  rm -f datapath/linux/kcompat.h.new
-  mkdir -p datapath/linux
-  : > datapath/linux/kcompat.h.new
-
-  OVS_GREP_IFELSE([$KSRC/arch/x86/include/asm/checksum_32.h], [src_err,],
-                  [OVS_DEFINE([HAVE_CSUM_COPY_DBG])])
-
-  OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [ERR_CAST])
-
-  OVS_GREP_IFELSE([$KSRC/include/linux/in.h], [ipv4_is_multicast])
-
-  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [dev_disable_lro])
-  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [dev_get_stats])
-  OVS_GREP_IFELSE([$KSRC/include/linux/netdevice.h], [dev_get_by_index_rcu])
-
-  OVS_GREP_IFELSE([$KSRC/include/linux/rcupdate.h], [rcu_read_lock_held], [],
-                  [OVS_GREP_IFELSE([$KSRC/include/linux/rtnetlink.h],
-                                   [rcu_read_lock_held])])
-  
-  # Check for the proto_data_valid member in struct sk_buff.  The [^@]
-  # is necessary because some versions of this header remove the
-  # member but retain the kerneldoc comment that describes it (which
-  # starts with @).  The brackets must be doubled because of m4
-  # quoting rules.
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [[[^@]]proto_data_valid],
-                  [OVS_DEFINE([HAVE_PROTO_DATA_VALID])])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [raw],
-                  [OVS_DEFINE([HAVE_MAC_RAW])])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_dst(],
-                  [OVS_DEFINE([HAVE_SKB_DST_ACCESSOR_FUNCS])])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], 
-                  [skb_copy_from_linear_data_offset])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h],
-                  [skb_reset_tail_pointer])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_cow_head])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_transport_header],
-                  [OVS_DEFINE([HAVE_SKBUFF_HEADER_HELPERS])])
-  OVS_GREP_IFELSE([$KSRC/include/linux/icmpv6.h], [icmp6_hdr],
-                  [OVS_DEFINE([HAVE_ICMP6_HDR])])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [skb_warn_if_lro],
-                  [OVS_DEFINE([HAVE_SKB_WARN_LRO])])
-  OVS_GREP_IFELSE([$KSRC/include/linux/skbuff.h], [consume_skb])
-
-  OVS_GREP_IFELSE([$KSRC/include/linux/string.h], [kmemdup], [],
-                  [OVS_GREP_IFELSE([$KSRC/include/linux/slab.h], [kmemdup])])
-
-  OVS_GREP_IFELSE([$KSRC/include/linux/types.h], [bool],
-                  [OVS_DEFINE([HAVE_BOOL_TYPE])])
-  OVS_GREP_IFELSE([$KSRC/include/linux/types.h], [__wsum],
-                  [OVS_DEFINE([HAVE_CSUM_TYPES])])
-
-  OVS_GREP_IFELSE([$KSRC/include/net/checksum.h], [csum_replace4])
-  OVS_GREP_IFELSE([$KSRC/include/net/checksum.h], [csum_unfold])
-
-  OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [NLA_NUL_STRING])
-  OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_get_be16])
-  OVS_GREP_IFELSE([$KSRC/include/net/netlink.h], [nla_find_nested])
-
-  OVS_GREP_IFELSE([$KSRC/include/linux/if_vlan.h], [ADD_ALL_VLANS_CMD],
-                  [OVS_DEFINE([HAVE_VLAN_BUG_WORKAROUND])])
-
-  OVS_CHECK_LOG2_H
-
-  if cmp -s datapath/linux/kcompat.h.new \
-            datapath/linux/kcompat.h >/dev/null 2>&1; then
-    rm datapath/linux/kcompat.h.new
-  else
-    mv datapath/linux/kcompat.h.new datapath/linux/kcompat.h
-  fi
-])
-
 dnl Checks for net/if_packet.h.
 AC_DEFUN([OVS_CHECK_IF_PACKET],
   [AC_CHECK_HEADER([net/if_packet.h],
diff --git a/datapath/linux/.gitignore b/datapath/linux/.gitignore
index 0aee746..8067279 100644
--- a/datapath/linux/.gitignore
+++ b/datapath/linux/.gitignore
@@ -19,7 +19,7 @@
 /genetlink-brcompat.c
 /genetlink-openvswitch.c
 /ip_output-openvswitch.c
-/kcompat.h
+/kcompat/
 /kmemdup.c
 /loop_counter.c
 /modules.order
diff --git a/datapath/linux/Kbuild.in b/datapath/linux/Kbuild.in
index 07d106d..a451f41 100644
--- a/datapath/linux/Kbuild.in
+++ b/datapath/linux/Kbuild.in
@@ -17,7 +17,7 @@ else
 EXTRA_CFLAGS += -DBUILDNR=\"+build$(BUILDNR)\"
 endif
 EXTRA_CFLAGS += -g
-EXTRA_CFLAGS += -include $(builddir)/kcompat.h
+EXTRA_CFLAGS += -include $(builddir)/kcompat/kcompat.h
 
 # These include directories have to go before -I$(KSRC)/include.
 # NOSTDINC_FLAGS just happens to be a variable that goes in the
@@ -28,6 +28,124 @@ obj-m := $(patsubst %,%_mod.o,$(build_modules))
 
 define module_template
 $(1)_mod-y = $$(notdir $$(patsubst %.c,%.o,$($(1)_sources)))
+$$(addprefix $$(obj)/,$$(notdir $$(patsubst %.c,%.o,$($(1)_sources)))): 
$(obj)/kcompat/kcompat.h
 endef
+#$(addprefix $(obj)/,$(notdir $(patsubst %.c,%.o,$(brcompat_sources)))): 
$(obj)/kcompat/kcompat.h
 
 $(foreach module,$(build_modules),$(eval $(call module_template,$(module))))
+
+define GREP
+for file in $^; do \
+    if test -f "$$file"; then \
+        grep '$(1)' $$file >/dev/null 2>&1; \
+       status=$$?; \
+       case $$status in \
+         0) \
+            $(kecho) "  GREP   \"$(1)\" found in $$file"; \
+           echo >&3 '#define $(if $(2),$(2),HAVE_$(shell echo $(1) | tr a-z 
A-Z)) 1'; \
+           break \
+           ;; \
+         1) \
+            $(kecho) "  GREP   \"$(1)\" not in $$file"; \
+           ;; \
+         *) \
+           echo "grep exited with status $$status"; \
+           exit $$status \
+           ;; \
+       esac; \
+    else \
+        $(kecho) "file not found"; \
+    fi; \
+done
+endef
+
+$(obj)/datapath.o: $(obj)/kcompat/kcompat.h
+$(obj)/kcompat/kcompat.h: \
+    $(obj)/kcompat/checksum.h \
+    $(obj)/kcompat/err.h \
+    $(obj)/kcompat/icmpv6.h \
+    $(obj)/kcompat/if_vlan.h \
+    $(obj)/kcompat/in.h \
+    $(obj)/kcompat/netdevice.h \
+    $(obj)/kcompat/netlink.h \
+    $(obj)/kcompat/rcupdate.h \
+    $(obj)/kcompat/skbuff.h \
+    $(obj)/kcompat/string.h \
+    $(obj)/kcompat/types.h \
+    $(obj)/kcompat/checksum_32.h \
+    $(obj)/kcompat/log2.h
+       @$(kecho) "  GEN     $@"
+       @$(O)cat $^ > $@.$$$$ && mv $@.$$$$ $@
+
+$(obj)/kcompat/checksum.h: include/net/checksum.h
+       @($(call GREP,csum_replace4); \
+         $(call GREP,csum_unfold)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/err.h: include/linux/err.h
+       @($(call GREP,ERR_CAST)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/icmpv6.h: include/linux/icmpv6.h
+       @($(call GREP,icmp6_hdr)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/if_vlan.h: include/linux/if_vlan.h
+       @($(call GREP,ADD_ALL_VLANS_CMD,HAVE_VLAN_BUG_WORKAROUND)) \
+       3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/in.h: include/linux/in.h
+       @($(call GREP,ipv4_is_multicast)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/netdevice.h: include/linux/netdevice.h
+       @($(call GREP,dev_disable_lro); \
+         $(call GREP,dev_get_stats); \
+         $(call GREP,dev_get_by_index_rcu)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/netlink.h: include/net/netlink.h
+       @($(call GREP,NLA_NUL_STRING); \
+         $(call GREP,nla_get_be16); \
+         $(call GREP,nla_find_nested)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/rcupdate.h: include/linux/rcupdate.h include/linux/rtnetlink.h
+       @($(call GREP,rcu_read_lock_held)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/skbuff.h: include/linux/skbuff.h
+       @($(call GREP,[^@]proto_data_valid,HAVE_PROTO_DATA_VALID); \
+         $(call GREP,raw,HAVE_MAC_RAW); \
+         ${call GREP,skb_dst(,HAVE_SKB_DST_ACCESSOR_FUNCS}; \
+         $(call GREP,skb_copy_from_linear_data_offset); \
+         $(call GREP,skb_reset_tail_pointer); \
+         $(call GREP,skb_cow_head); \
+         $(call GREP,skb_transport_header,HAVE_SKBUFF_HEADER_HELPERS); \
+         $(call GREP,skb_warn_if_lro,HAVE_SKB_WARN_LRO); \
+         $(call GREP,consume_skb)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/string.h: include/linux/string.h include/linux/slab.h
+       @($(call GREP,kmemdup)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+$(obj)/kcompat/types.h: include/linux/types.h
+       @($(call GREP,bool,HAVE_BOOL_TYPE); \
+         $(call GREP,__wsum,HAVE_CSUM_TYPES)) 3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+
+ifneq ($(wildcard arch/x86/include/asm/checksum_32.h),)
+# Generate kcompat/checksum_32.h.
+comma := ,
+$(obj)/kcompat/checksum_32.h: arch/x86/include/asm/checksum_32.h
+       @($(call GREP,src_err$(comma),HAVE_CSUM_COPY_DBG)) \
+       3> $@.tmp$$$$; mv $@.tmp$$$$ $@
+else ifneq ($(shell (test ! -e $(obj)/kcompat/checksum_32.h || test -s 
$(obj)/kcompat/checksum_32.h) && echo needs-update),)
+# kcompat/checksum_32.h needs to be an empty file but isn't.
+.PHONY: $(obj)/kcompat/checksum_32.h
+$(obj)/kcompat/checksum_32.h:
+       : > $@
+else
+# kcompat/checksum_32.h is empty and that's what we want.
+endif
+
+ifneq ($(wildcard include/linux/log2.h),)
+ifneq ($(shell test -s $(obj)/kcompat/log2.h && echo nonempty),)
+# $(obj)/kcompat/log2.h is nonempty and should be.
+else
+# $(obj)/kcompat/log2.h is empty but should not be.
+.PHONY: $(obj)/kcompat/log2.h
+$(obj)/kcompat/log2.h:
+       @echo '#define HAVE_LOG2_H 1' > $@.tmp$$$$ && mv $@.tmp$$$$ $@
+endif
+else
+ifneq ($(shell test -s $(obj)/kcompat/log2.h && echo nonempty),)
+# $(obj)/kcompat/log2.h is nonempty but should be empty.
+.PHONY: $(obj)/kcompat/log2.h
+$(obj)/kcompat/log2.h:
+       : > $@
+else
+# $(obj)/kcompat/log2.h is empty and should be.
+endif
+endif
diff --git a/datapath/linux/Makefile.main.in b/datapath/linux/Makefile.main.in
index 0302fc6..5d5d29e 100644
--- a/datapath/linux/Makefile.main.in
+++ b/datapath/linux/Makefile.main.in
@@ -29,10 +29,9 @@ check: all
 installcheck:
 mostlyclean:
 clean:
-       rm -f *.o *.ko *_mod.* Module.symvers *.cmd kcompat.h.new
+       rm -f *.o *.ko *_mod.* Module.symvers *.cmd kcompat/*.h
        for d in $(build_links); do if test -h $$d; then rm $$d; fi; done
 distclean: clean
-       rm -f kcompat.h
 maintainer-clean: distclean
 dvi:
 pdf:
-- 
1.7.2.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to