fishinabarrel/linux-kernel-module-rust

Crate fails to compile due to missing file-operations binding

robinhundt opened this issue · 3 comments

I wanted to try out the hello-world example in the repo. Unfortunately the build fails with the following output:

make -C /lib/modules/4.4.0-164-generic/build M=/home/robin/code/linux-kernel-module-rust/hello-world
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-164-generic'
cd /home/robin/code/linux-kernel-module-rust/hello-world; env -u MAKE -u MAKEFLAGS cargo build -Z build-std=core,alloc --target=x86_64-linux-kernel
   Compiling linux-kernel-module v0.1.0 (/home/robin/code/linux-kernel-module-rust)
error[E0560]: struct `bindings::bindings::file_operations` has no field named `clone_file_range`
   --> /home/robin/code/linux-kernel-module-rust/src/chrdev.rs:201:13
    |
201 |             clone_file_range: None,
    |             ^^^^^^^^^^^^^^^^ `bindings::bindings::file_operations` does not have this field
    |
    = note: available fields are: `owner`, `llseek`, `read`, `write`, `read_iter` ... and 22 others

error[E0560]: struct `bindings::bindings::file_operations` has no field named `copy_file_range`
   --> /home/robin/code/linux-kernel-module-rust/src/chrdev.rs:203:13
    |
203 |             copy_file_range: None,
    |             ^^^^^^^^^^^^^^^ `bindings::bindings::file_operations` does not have this field
    |
    = note: available fields are: `owner`, `llseek`, `read`, `write`, `read_iter` ... and 22 others

error[E0560]: struct `bindings::bindings::file_operations` has no field named `dedupe_file_range`
   --> /home/robin/code/linux-kernel-module-rust/src/chrdev.rs:205:13
    |
205 |             dedupe_file_range: None,
    |             ^^^^^^^^^^^^^^^^^ `bindings::bindings::file_operations` does not have this field
    |
    = note: available fields are: `owner`, `llseek`, `read`, `write`, `read_iter` ... and 22 others

error[E0560]: struct `bindings::bindings::file_operations` has no field named `iterate_shared`
   --> /home/robin/code/linux-kernel-module-rust/src/chrdev.rs:215:13
    |
215 |             iterate_shared: None,
    |             ^^^^^^^^^^^^^^ `bindings::bindings::file_operations` does not have this field
    |
    = note: available fields are: `owner`, `llseek`, `read`, `write`, `read_iter` ... and 22 others

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0560`.
error: Could not compile `linux-kernel-module`.

To learn more, run the command again with --verbose.
/home/robin/code/linux-kernel-module-rust/hello-world/Kbuild:7: recipe for target '/home/robin/code/linux-kernel-module-rust/hello-world/target/x86_64-linux-kernel/debug/libhello_world.a' failed
make[2]: *** [/home/robin/code/linux-kernel-module-rust/hello-world/target/x86_64-linux-kernel/debug/libhello_world.a] Error 101
Makefile:1454: recipe for target '_module_/home/robin/code/linux-kernel-module-rust/hello-world' failed
make[1]: *** [_module_/home/robin/code/linux-kernel-module-rust/hello-world] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-164-generic'
Makefile:4: recipe for target 'all' failed
make: *** [all] Error 2

Current rust toolchain:

nightly-x86_64-unknown-linux-gnu (directory override for '/home/robin/code/linux-kernel-module-rust')
rustc 1.39.0-nightly (eceec57f7 2019-09-18)

gcc version:

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609

clang version:

clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

kernel:

Linux [...] 4.4.0-164-generic #192-Ubuntu SMP Fri Sep 13 12:02:50 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

From what I understand my kernel version doesn't have all the file operations used in the the initialization of the file_operations struct in chrdev.rs:193.
If i delete the missing fields i get the following error:

error[E0063]: missing field `aio_fsync` in initializer of `bindings::bindings::file_operations`
   --> /home/robin/code/linux-kernel-module-rust/src/chrdev.rs:193:30
    |
193 |         FileOperationsVtable(bindings::file_operations {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `aio_fsync`

adding aio_fsync: None then results in:

error[E0013]: constants cannot refer to statics, use a constant instead
  --> /home/robin/code/linux-kernel-module-rust/src/bindings.rs:14:31
   |
14 | pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL;
   |                               ^^^^^^^^^^^^^^^^^^^

error: use of extern static is unsafe and requires unsafe function or block (error E0133)
  --> /home/robin/code/linux-kernel-module-rust/src/bindings.rs:14:31
   |
14 | pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL;
   |                               ^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[deny(safe_extern_statics)]` on by default
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #36247 <https://github.com/rust-lang/rust/issues/36247>
   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0013`.
error: Could not compile `linux-kernel-module`.
alex commented

Thanks! It looks like the issue is that we don't support kernel 4.4.

We need to make a clear decision about which kernel versions we intend to support (so long as we are out of tree), but for now we should add the correct #[cfg()] blocks to support this.

That's what i suspected (maybe it's time for a new kernel 😅).
I also noticed that my clang version version wasn't high enough, i had 3.8 and not 3.9.

It's a fairly straightforward patch if you're up for it, see the build.rs and chrdev.rs changes in 327bb91 . You'll want to do something roughly like that for your kernel version.

For clang, you're on Xenial, right? apt-get install clang-3.9 or even up to clang-6.0 ought to work. If you want a much newer one, http://apt.llvm.org/ has backports maintained by the same people who maintain the actual Debian/Ubuntu packages. That will fix your BINDINGS_GPF_KERNEL problem. (Alternatively, hard-code it as 0x40 in your local checkout, I have a machine where I'm doing that....)