summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-09-23 04:17:01 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-09-23 04:17:01 +0000
commit1537b639c0611c8715b2f3d7564d8f9c13aad2ba (patch)
treeefd7d1a498b8e9344452ba20d309751f441750e4 /src
parentd302e8d278bcd5b10ab7a30a467b5d8e21139ff2 (diff)
parenta7fea44fe38b61a65ebc2d840c4c6c9e1bd8431d (diff)
downloadnix-1537b639c0611c8715b2f3d7564d8f9c13aad2ba.zip
Merge #930
930: Add wrapper for linux kernel module loading r=Susurrus a=bachp - init_module and finit_module to load kernel modules - delete_module to unload kernel modules Co-authored-by: Pascal Bach <pascal.bach@nextrem.ch>
Diffstat (limited to 'src')
-rw-r--r--src/kmod.rs123
-rw-r--r--src/lib.rs9
-rw-r--r--src/pty.rs3
3 files changed, 131 insertions, 4 deletions
diff --git a/src/kmod.rs b/src/kmod.rs
new file mode 100644
index 00000000..e853261b
--- /dev/null
+++ b/src/kmod.rs
@@ -0,0 +1,123 @@
+//! Load and unload kernel modules.
+//!
+//! For more details see
+
+use libc;
+use std::ffi::CStr;
+use std::os::unix::io::AsRawFd;
+
+use errno::Errno;
+use 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)`](http://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)`](http://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)`](http://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)`](http://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)
+}
diff --git a/src/lib.rs b/src/lib.rs
index ed96a8e1..48426594 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -43,7 +43,11 @@ pub mod fcntl;
target_os = "netbsd",
target_os = "openbsd"))]
pub mod ifaddrs;
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android",
+ target_os = "linux"))]
+pub mod kmod;
+#[cfg(any(target_os = "android",
+ target_os = "linux"))]
pub mod mount;
#[cfg(any(target_os = "dragonfly",
target_os = "freebsd",
@@ -57,7 +61,8 @@ pub mod net;
pub mod poll;
#[deny(missing_docs)]
pub mod pty;
-#[cfg(any(target_os = "linux", target_os = "android"))]
+#[cfg(any(target_os = "android",
+ target_os = "linux"))]
pub mod sched;
pub mod sys;
// This can be implemented for other platforms as soon as libc
diff --git a/src/pty.rs b/src/pty.rs
index ec250aa7..b7171885 100644
--- a/src/pty.rs
+++ b/src/pty.rs
@@ -108,8 +108,7 @@ pub fn grantpt(fd: &PtyMaster) -> Result<()> {
/// let slave_name = unsafe { ptsname(&master_fd) }?;
///
/// // Try to open the slave
-/// # #[allow(unused_variables)]
-/// let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?;
+/// let _slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?;
/// # Ok(())
/// # }
/// ```