123 lines
3.6 KiB
Rust
123 lines
3.6 KiB
Rust
//! Load and unload kernel modules.
|
|
//!
|
|
//! For more details see
|
|
|
|
use std::ffi::CStr;
|
|
use std::os::unix::io::AsRawFd;
|
|
|
|
use crate::errno::Errno;
|
|
use crate::Result;
|
|
|
|
/// Loads a kernel module from a buffer.
|
|
///
|
|
/// It loads an ELF image into kernel space,
|
|
/// performs any necessary symbol relocations,
|
|
/// initializes module parameters to values provided by the caller,
|
|
/// and then runs the module's init function.
|
|
///
|
|
/// This function requires `CAP_SYS_MODULE` privilege.
|
|
///
|
|
/// The `module_image` argument points to a buffer containing the binary image
|
|
/// to be loaded. The buffer should contain a valid ELF image
|
|
/// built for the running kernel.
|
|
///
|
|
/// The `param_values` argument is a string containing space-delimited specifications
|
|
/// of the values for module parameters.
|
|
/// Each of the parameter specifications has the form:
|
|
///
|
|
/// `name[=value[,value...]]`
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```no_run
|
|
/// use std::fs::File;
|
|
/// use std::io::Read;
|
|
/// use std::ffi::CString;
|
|
/// use nix::kmod::init_module;
|
|
///
|
|
/// let mut f = File::open("mykernel.ko").unwrap();
|
|
/// let mut contents: Vec<u8> = Vec::new();
|
|
/// f.read_to_end(&mut contents).unwrap();
|
|
/// init_module(&mut contents, &CString::new("who=Rust when=Now,12").unwrap()).unwrap();
|
|
/// ```
|
|
///
|
|
/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
|
|
pub fn init_module(module_image: &[u8], param_values: &CStr) -> Result<()> {
|
|
let res = unsafe {
|
|
libc::syscall(
|
|
libc::SYS_init_module,
|
|
module_image.as_ptr(),
|
|
module_image.len(),
|
|
param_values.as_ptr(),
|
|
)
|
|
};
|
|
|
|
Errno::result(res).map(drop)
|
|
}
|
|
|
|
libc_bitflags!(
|
|
/// Flags used by the `finit_module` function.
|
|
pub struct ModuleInitFlags: libc::c_uint {
|
|
/// Ignore symbol version hashes.
|
|
MODULE_INIT_IGNORE_MODVERSIONS;
|
|
/// Ignore kernel version magic.
|
|
MODULE_INIT_IGNORE_VERMAGIC;
|
|
}
|
|
);
|
|
|
|
/// Loads a kernel module from a given file descriptor.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```no_run
|
|
/// use std::fs::File;
|
|
/// use std::ffi::CString;
|
|
/// use nix::kmod::{finit_module, ModuleInitFlags};
|
|
///
|
|
/// let f = File::open("mymod.ko").unwrap();
|
|
/// finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()).unwrap();
|
|
/// ```
|
|
///
|
|
/// See [`man init_module(2)`](https://man7.org/linux/man-pages/man2/init_module.2.html) for more information.
|
|
pub fn finit_module<T: AsRawFd>(fd: &T, param_values: &CStr, flags: ModuleInitFlags) -> Result<()> {
|
|
let res = unsafe {
|
|
libc::syscall(
|
|
libc::SYS_finit_module,
|
|
fd.as_raw_fd(),
|
|
param_values.as_ptr(),
|
|
flags.bits(),
|
|
)
|
|
};
|
|
|
|
Errno::result(res).map(drop)
|
|
}
|
|
|
|
libc_bitflags!(
|
|
/// Flags used by `delete_module`.
|
|
///
|
|
/// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html)
|
|
/// for a detailed description how these flags work.
|
|
pub struct DeleteModuleFlags: libc::c_int {
|
|
O_NONBLOCK;
|
|
O_TRUNC;
|
|
}
|
|
);
|
|
|
|
/// Unloads the kernel module with the given name.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```no_run
|
|
/// use std::ffi::CString;
|
|
/// use nix::kmod::{delete_module, DeleteModuleFlags};
|
|
///
|
|
/// delete_module(&CString::new("mymod").unwrap(), DeleteModuleFlags::O_NONBLOCK).unwrap();
|
|
/// ```
|
|
///
|
|
/// See [`man delete_module(2)`](https://man7.org/linux/man-pages/man2/delete_module.2.html) for more information.
|
|
pub fn delete_module(name: &CStr, flags: DeleteModuleFlags) -> Result<()> {
|
|
let res = unsafe { libc::syscall(libc::SYS_delete_module, name.as_ptr(), flags.bits()) };
|
|
|
|
Errno::result(res).map(drop)
|
|
}
|