Rocky 9: Fixing LookingGlass Module Build Failure

by Alex Johnson 50 views

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:

  1. Locate the kvmfr.c file: This is the main source file for your kvmfr module.
  2. Add MODULE_IMPORT_NS(DMA_BUF);: Place this line at the top of the file, after the module license declaration (e.g., `MODULE_LICENSE(