1

TL;DR

I get Kernelheaders with the correct version number but function definitions that were only introduced some kernel versions later. How do I get rid of these definition from the future?


Background

I have been writing a kernelmodule and noted that it did not compile on another machine with the error that pci_bus_address was not defined. A quick investigation yielded, that it should not be defined since it is running a 3.10 Kernel, and this function is only available since 3.14.

I figured that a quick #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) block should fix the issue. However, my host machine is running a 3.10 Kernel as well.

Why do my kernel-headers know about a function, that should only be defined in a later version of the kernel? How can I get correct Kernel headers, that do not include this function?

I ran repoquery -i kernel-devel to show the installed version:

Name        : kernel-devel
Version     : 3.10.0
Release     : 327.18.2.el7
Architecture: x86_64
Size        : 34442356
Packager    : None
Group       : System Environment/Kernel
URL         : http://www.kernel.org/
Repository  : updates
Summary     : Development package for building kernel modules to match the kernel
Source      : kernel-3.10.0-327.18.2.el7.src.rpm
Description :
This package provides kernel headers and makefiles sufficient to build modules
against the kernel package.

however running grep pci_bus_addr /usr/src/kernels/3.10.0-327.18.2.el7.x86_64/include/linux/pci.h returns static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)

ted
  • 4,791
  • 5
  • 38
  • 84
  • 2
    The problem is that the Red Hat kernel team backport features from later kernels, including kernel API changes. It can be quite annoying when building out-of-tree kernel stuff. Installing different kernel headers is not an option unless you also install the kernel that matches the different headers. Sometimes it is possible to detect backported features at the C preprocessor level. Other times, you need to detect them at "build configuration" time, for example by grepping the kernel headers in an autoconf macro. – Ian Abbott Jun 22 '16 at 16:10
  • 1
    In addition to checking LINUX_VERSION_CODE, you could check if the RHEL_RELEASE_CODE and RHEL_RELEASE_VERSION macros are defined, and if so, compare RHEL_RELEASE_CODE to various values of RHEL_RELEASE_CODE(major, minor). This assumes that Red Hat don't change internal kernel APIs within the kernel updates for a particular RHEL major.minor version, and I don't know whether that's the case or not. It's also a bit of a chore to find out the earliest RHEL major.minor version that includes a particular backported feature. – Ian Abbott Jun 22 '16 at 17:02
  • @IanAbbott: Would you care to turn this into an answer? P.S.: I did some digging based on your data, and will post my findings below. – ted Jun 22 '16 at 20:04

1 Answers1

1

@Ian Abbott pointed me the right way. As it turns out, Redhat packports patches. Stumbling through their git repository I could pinpoint the change to a specific kernel version.

While the specification in the changelog shows a specific release I am lucky, and the changes are tied to the RHEL_RELEASE_CODE (which is composed of the Major and Minor number of centos (i.e.the change in question is in Kernels past 7.1) and not the release code from the changelog, which can only be found as a string in <linux/version.h>. (Doing conditional compilation based on a string would be a nightmare (call an extra tool to parse the string and generate a headerfile based on this)).

Adding #if (RHEL_RELEASE_VERSION() <= RHEL_RELEASE_CODE) does the trick (relying on undefined constants being 0 for non redhat distibutions).

Community
  • 1
  • 1
ted
  • 4,791
  • 5
  • 38
  • 84