Build ZFS on OEL with UEK7
ZFS version 2.1.11 is supposed to work correctly with Oracle UEK 7. However, on update (and later – a reboot) – it broke. The driver cannot build using dkms, and the error message is something like this:
checking kernel source version... 5.15.0-100.96.32.el8uek.x86_64
checking for kernel config option compatibility... done
checking whether CONFIG_MODULES is defined... no
configure: error:
*** This kernel does not include the required loadable module
*** support!
***
*** To build OpenZFS as a loadable Linux kernel module
*** enable loadable module support by setting
*** `CONFIG_MODULES=y` in the kernel configuration and run
*** `make modules_prepare` in the Linux source tree.
***
*** If you don't intend to enable loadable kernel module
*** support, please compile OpenZFS as a Linux kernel built-in.
***
*** Prepare the Linux source tree by running `make prepare`,
*** use the OpenZFS `--enable-linux-builtin` configure option,
*** copy the OpenZFS sources into the Linux source tree using
*** `./copy-builtin <linux source directory>`,
*** set `CONFIG_ZFS=y` in the kernel configuration and compile
*** kernel as usual.
If you look into /boot/config-`uname -r` output, and look for CONFIG_MODULES string, you will indeed find that it is set to ‘y’. So what is the problem?
The root of the problem is with the GCC toolset used to build UEK7 kernel, which is different from the one used to build Redhat compatible version. RH kernel is built (using the default) GCC. The following output is shown:
# gcc --version
gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-16.0.2)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
However, the GCC we need is of version 11, and the correct out put should look like this:
# gcc --version
gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9.1.0.3)
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The solution is in SCL. We can use SCL to enforce using, for a session, a different version of toolsets. Read more about SCL, because it is interesting, however, in this particular case, we will need to load the correct SCL module.
If the correct module has not been installed yet, run the following command:
dnf install -y gcc-toolset-11-annobin-plugin-gcc
Now, you can call the module on demand, and run your dkms build like this:
. /opt/rh/gcc-toolset-11/enable
dkms install zfs/2.1.11
It can be enough for most, however, I wanted dkms to build the kernel driver on every subsequent kernel update, so I’ve had to modify the systemd script for dkms service. First, I needed to create the systemd unit file. So I have created /etc/systemd/system/dkms.service :
[Unit]
Description=Builds and install new kernel modules through DKMS
Documentation=man:dkms(8)
Before=network-pre.target graphical.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=bash -c ". /opt/rh/gcc-toolset-11/enable && /usr/sbin/dkms autoinstall --verbose --kernelver %v"
[Install]
WantedBy=multi-user.target
Now, we need to reload systemd using
systemctl daemon-reload
And then we just need to enable the service:
systemctl enable --now dkms.service
Now, on future kernel updates, ZFS driver will be built and loaded as part of the startup. You can follow up on the logs (in /var/log/messages) to see the build process completes successfully.