blob: 8789cb69f4617f41f40cc997b3dbe7ed6187a987 [file] [log] [blame]
Andrew Walbran12f61402020-10-14 11:10:53 +01001//! Load and unload kernel modules.
2//!
3//! For more details see
4
5use libc;
6use std::ffi::CStr;
7use std::os::unix::io::AsRawFd;
8
9use crate::errno::Errno;
10use crate::Result;
11
12/// Loads a kernel module from a buffer.
13///
14/// It loads an ELF image into kernel space,
15/// performs any necessary symbol relocations,
16/// initializes module parameters to values provided by the caller,
17/// and then runs the module's init function.
18///
19/// This function requires `CAP_SYS_MODULE` privilege.
20///
21/// The `module_image` argument points to a buffer containing the binary image
22/// to be loaded. The buffer should contain a valid ELF image
23/// built for the running kernel.
24///
25/// The `param_values` argument is a string containing space-delimited specifications
26/// of the values for module parameters.
27/// Each of the parameter specifications has the form:
28///
29/// `name[=value[,value...]]`
30///
31/// # Example
32///
33/// ```no_run
34/// use std::fs::File;
35/// use std::io::Read;
36/// use std::ffi::CString;
37/// use nix::kmod::init_module;
38///
39/// let mut f = File::open("mykernel.ko").unwrap();
40/// let mut contents: Vec<u8> = Vec::new();
41/// f.read_to_end(&mut contents).unwrap();
42/// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap();
43/// ```
44///
45/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
46pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> {
47 let res = unsafe {
48 libc::syscall(
49 libc::SYS_init_module,
50 module_image.as_ptr(),
51 module_image.len(),
52 param_values.as_ptr(),
53 )
54 };
55
56 Errno::result(res).map(drop)
57}
58
59libc_bitflags!(
60 /// Flags used by the `finit_module` function.
61 pub struct ModuleInitFlags: libc::c_uint {
62 /// Ignore symbol version hashes.
63 MODULE_INIT_IGNORE_MODVERSIONS;
64 /// Ignore kernel version magic.
65 MODULE_INIT_IGNORE_VERMAGIC;
66 }
67);
68
69/// Loads a kernel module from a given file descriptor.
70///
71/// # Example
72///
73/// ```no_run
74/// use std::fs::File;
75/// use std::ffi::CString;
76/// use nix::kmod::{finit_module, ModuleInitFlags};
77///
78/// let f = File::open("mymod.ko").unwrap();
79/// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap();
80/// ```
81///
82/// See [`man init_module(2)`](http://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
83pub fn finit_module<T: AsRawFd>(fd: &T, param_values: &CStr, flags: ModuleInitFlags) -> Result<()> {
84 let res = unsafe {
85 libc::syscall(
86 libc::SYS_finit_module,
87 fd.as_raw_fd(),
88 param_values.as_ptr(),
89 flags.bits(),
90 )
91 };
92
93 Errno::result(res).map(drop)
94}
95
96libc_bitflags!(
97 /// Flags used by `delete_module`.
98 ///
99 /// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html)
100 /// for a detailed description how these flags work.
101 pub struct DeleteModuleFlags: libc::c_int {
102 O_NONBLOCK;
103 O_TRUNC;
104 }
105);
106
107/// Unloads the kernel module with the given name.
108///
109/// # Example
110///
111/// ```no_run
112/// use std::ffi::CString;
113/// use nix::kmod::{delete_module, DeleteModuleFlags};
114///
115/// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap();
116/// ```
117///
118/// See [`man delete_module(2)`](http://man7.org/linux/man-pages/man2/delete_module.2.html) for more information.
119pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> {
120 let res = unsafe { libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) };
121
122 Errno::result(res).map(drop)
123}