Rocky 9: Fixing LookingGlass Module Build Failure
Encountering build failures when trying to compile modules, specifically LookingGlass, on Rocky 9 can be a frustrating experience. This article dives into a specific build failure related to the class_create function and DMA_BUF namespace issues, offering insights and potential solutions to get your module building successfully.
Understanding the Initial Build Failure
The initial error encountered during the module build on Rocky 9 points to an incompatibility with the class_create function. Let's break down the error message:
/var/lib/dkms/kvmfr/0.0.12/build/kvmfr.c: In function ‘kvmfr_module_init’:
./include/linux/export.h:29:22: error: passing argument 1 of ‘class_create’ from incompatible pointer type [-Werror=incompatible-pointer-types]
29 | #define THIS_MODULE (&__this_module)
| ~^~~~~~~~~~~~~~~
| |
| struct module *
/var/lib/dkms/kvmfr/0.0.12/build/kvmfr.c:601:32: note: in expansion of macro ‘THIS_MODULE’
601 | kvmfr->pClass = class_create(THIS_MODULE, KVMFR_DEV_NAME);
| ^~~~~~~~~~~
In file included from ./include/linux/device.h:31,
from /var/lib/dkms/kvmfr/0.0.12/build/kvmfr.c:24:
./include/linux/device/class.h:230:54: note: expected ‘const char *’ but argument is of type ‘struct module *’
230 | struct class * __must_check class_create(const char *name);
| ~~~~~~~~~~~~^~~~~
/var/lib/dkms/kvmfr/0.0.12/build/kvmfr.c:601:19: error: too many arguments to function ‘class_create’
601 | kvmfr->pClass = class_create(THIS_MODULE, KVMFR_DEV_NAME);
| ^~~~~~~~~~~~
In file included from ./include/linux/device.h:31,
from /var/lib/dkms/kvmfr/0.0.12/build/kvmfr.c:24:
./include/linux/device/class.h:230:29: note: declared here
230 | struct class * __must_check class_create(const char *name);
| ^~~~~~~~~~~~
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:249: /var/lib/dkms/kvmfr/0.0.12/build/kvmfr.o] Error 1
make[1]: *** [Makefile:1947: /var/lib/dkms/kvmfr/0.0.12/build] Error 2
make[1]: Leaving directory '/usr/src/kernels/5.14.0-570.58.1.el9_6.x86_64'
make: *** [Makefile:7: all] Error 2
This error arises because the class_create function in the kernel expects a const char * (a string representing the class name) as its argument, but it's receiving THIS_MODULE, which is a pointer to the module structure (struct module *). This usually indicates that the code was written for an older kernel version where class_create accepted the module pointer as an argument. The kernel 5.14 in Rocky 9 likely has a backported version of class_create that requires only the class name.
The key point here is the evolution of the kernel API. Functions like class_create sometimes change their signatures between kernel versions. Code that worked on an older kernel might need adjustments to compile correctly on a newer one.
To resolve this, you'll need to modify the code to use the correct class_create signature. Instead of passing THIS_MODULE, you should only pass the KVMFR_DEV_NAME which is the class name. This aligns with the expected input of the class_create function in the kernel version used by Rocky 9.
Addressing DMA_BUF Namespace Errors
After addressing the class_create issue, you might encounter new errors related to the DMA_BUF namespace. These errors look like this:
ERROR: modpost: module kvmfr uses symbol dma_buf_export from namespace DMA_BUF, but does not import it.
ERROR: modpost: module kvmfr uses symbol dma_buf_fd from namespace DMA_BUF, but does not import it.
These errors indicate that your module, kvmfr, is using symbols (dma_buf_export and dma_buf_fd) that belong to the DMA_BUF namespace, but it hasn't explicitly declared that it needs to import them. The DMA_BUF subsystem is a mechanism for sharing buffers between different drivers and userspace in Linux.
To resolve this, you need to tell the kernel that your module depends on the DMA_BUF namespace. This is typically done by adding a MODULE_IMPORT_NS(DMA_BUF) macro to your module's source code (usually in the main .c file).
Here's how to implement this solution:
- Locate the
kvmfr.cfile: This is the main source file for yourkvmfrmodule. - Add
MODULE_IMPORT_NS(DMA_BUF);: Place this line at the top of the file, after the module license declaration (e.g., `MODULE_LICENSE(