13da5c369Sopenharmony_ciuse crate::*; 23da5c369Sopenharmony_ciuse std::fs::copy; 33da5c369Sopenharmony_ciuse std::path::PathBuf; 43da5c369Sopenharmony_ciuse std::process::Command; 53da5c369Sopenharmony_ciuse tempfile::{tempdir, TempDir}; 63da5c369Sopenharmony_ci 73da5c369Sopenharmony_cifn compile_kernel_module() -> (PathBuf, String, TempDir) { 83da5c369Sopenharmony_ci let _m = crate::FORK_MTX.lock(); 93da5c369Sopenharmony_ci 103da5c369Sopenharmony_ci let tmp_dir = 113da5c369Sopenharmony_ci tempdir().expect("unable to create temporary build directory"); 123da5c369Sopenharmony_ci 133da5c369Sopenharmony_ci copy( 143da5c369Sopenharmony_ci "test/test_kmod/hello_mod/hello.c", 153da5c369Sopenharmony_ci tmp_dir.path().join("hello.c"), 163da5c369Sopenharmony_ci ) 173da5c369Sopenharmony_ci .expect("unable to copy hello.c to temporary build directory"); 183da5c369Sopenharmony_ci copy( 193da5c369Sopenharmony_ci "test/test_kmod/hello_mod/Makefile", 203da5c369Sopenharmony_ci tmp_dir.path().join("Makefile"), 213da5c369Sopenharmony_ci ) 223da5c369Sopenharmony_ci .expect("unable to copy Makefile to temporary build directory"); 233da5c369Sopenharmony_ci 243da5c369Sopenharmony_ci let status = Command::new("make") 253da5c369Sopenharmony_ci .current_dir(tmp_dir.path()) 263da5c369Sopenharmony_ci .status() 273da5c369Sopenharmony_ci .expect("failed to run make"); 283da5c369Sopenharmony_ci 293da5c369Sopenharmony_ci assert!(status.success()); 303da5c369Sopenharmony_ci 313da5c369Sopenharmony_ci // Return the relative path of the build kernel module 323da5c369Sopenharmony_ci (tmp_dir.path().join("hello.ko"), "hello".to_owned(), tmp_dir) 333da5c369Sopenharmony_ci} 343da5c369Sopenharmony_ci 353da5c369Sopenharmony_ciuse nix::errno::Errno; 363da5c369Sopenharmony_ciuse nix::kmod::{delete_module, DeleteModuleFlags}; 373da5c369Sopenharmony_ciuse nix::kmod::{finit_module, init_module, ModuleInitFlags}; 383da5c369Sopenharmony_ciuse std::ffi::CString; 393da5c369Sopenharmony_ciuse std::fs::File; 403da5c369Sopenharmony_ciuse std::io::Read; 413da5c369Sopenharmony_ci 423da5c369Sopenharmony_ci#[test] 433da5c369Sopenharmony_cifn test_finit_and_delete_module() { 443da5c369Sopenharmony_ci require_capability!("test_finit_and_delete_module", CAP_SYS_MODULE); 453da5c369Sopenharmony_ci let _m0 = crate::KMOD_MTX.lock(); 463da5c369Sopenharmony_ci let _m1 = crate::CWD_LOCK.read(); 473da5c369Sopenharmony_ci 483da5c369Sopenharmony_ci let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); 493da5c369Sopenharmony_ci 503da5c369Sopenharmony_ci let f = File::open(kmod_path).expect("unable to open kernel module"); 513da5c369Sopenharmony_ci finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()) 523da5c369Sopenharmony_ci .expect("unable to load kernel module"); 533da5c369Sopenharmony_ci 543da5c369Sopenharmony_ci delete_module( 553da5c369Sopenharmony_ci &CString::new(kmod_name).unwrap(), 563da5c369Sopenharmony_ci DeleteModuleFlags::empty(), 573da5c369Sopenharmony_ci ) 583da5c369Sopenharmony_ci .expect("unable to unload kernel module"); 593da5c369Sopenharmony_ci} 603da5c369Sopenharmony_ci 613da5c369Sopenharmony_ci#[test] 623da5c369Sopenharmony_cifn test_finit_and_delete_module_with_params() { 633da5c369Sopenharmony_ci require_capability!( 643da5c369Sopenharmony_ci "test_finit_and_delete_module_with_params", 653da5c369Sopenharmony_ci CAP_SYS_MODULE 663da5c369Sopenharmony_ci ); 673da5c369Sopenharmony_ci let _m0 = crate::KMOD_MTX.lock(); 683da5c369Sopenharmony_ci let _m1 = crate::CWD_LOCK.read(); 693da5c369Sopenharmony_ci 703da5c369Sopenharmony_ci let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); 713da5c369Sopenharmony_ci 723da5c369Sopenharmony_ci let f = File::open(kmod_path).expect("unable to open kernel module"); 733da5c369Sopenharmony_ci finit_module( 743da5c369Sopenharmony_ci &f, 753da5c369Sopenharmony_ci &CString::new("who=Rust number=2018").unwrap(), 763da5c369Sopenharmony_ci ModuleInitFlags::empty(), 773da5c369Sopenharmony_ci ) 783da5c369Sopenharmony_ci .expect("unable to load kernel module"); 793da5c369Sopenharmony_ci 803da5c369Sopenharmony_ci delete_module( 813da5c369Sopenharmony_ci &CString::new(kmod_name).unwrap(), 823da5c369Sopenharmony_ci DeleteModuleFlags::empty(), 833da5c369Sopenharmony_ci ) 843da5c369Sopenharmony_ci .expect("unable to unload kernel module"); 853da5c369Sopenharmony_ci} 863da5c369Sopenharmony_ci 873da5c369Sopenharmony_ci#[test] 883da5c369Sopenharmony_cifn test_init_and_delete_module() { 893da5c369Sopenharmony_ci require_capability!("test_init_and_delete_module", CAP_SYS_MODULE); 903da5c369Sopenharmony_ci let _m0 = crate::KMOD_MTX.lock(); 913da5c369Sopenharmony_ci let _m1 = crate::CWD_LOCK.read(); 923da5c369Sopenharmony_ci 933da5c369Sopenharmony_ci let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); 943da5c369Sopenharmony_ci 953da5c369Sopenharmony_ci let mut f = File::open(kmod_path).expect("unable to open kernel module"); 963da5c369Sopenharmony_ci let mut contents: Vec<u8> = Vec::new(); 973da5c369Sopenharmony_ci f.read_to_end(&mut contents) 983da5c369Sopenharmony_ci .expect("unable to read kernel module content to buffer"); 993da5c369Sopenharmony_ci init_module(&contents, &CString::new("").unwrap()) 1003da5c369Sopenharmony_ci .expect("unable to load kernel module"); 1013da5c369Sopenharmony_ci 1023da5c369Sopenharmony_ci delete_module( 1033da5c369Sopenharmony_ci &CString::new(kmod_name).unwrap(), 1043da5c369Sopenharmony_ci DeleteModuleFlags::empty(), 1053da5c369Sopenharmony_ci ) 1063da5c369Sopenharmony_ci .expect("unable to unload kernel module"); 1073da5c369Sopenharmony_ci} 1083da5c369Sopenharmony_ci 1093da5c369Sopenharmony_ci#[test] 1103da5c369Sopenharmony_cifn test_init_and_delete_module_with_params() { 1113da5c369Sopenharmony_ci require_capability!( 1123da5c369Sopenharmony_ci "test_init_and_delete_module_with_params", 1133da5c369Sopenharmony_ci CAP_SYS_MODULE 1143da5c369Sopenharmony_ci ); 1153da5c369Sopenharmony_ci let _m0 = crate::KMOD_MTX.lock(); 1163da5c369Sopenharmony_ci let _m1 = crate::CWD_LOCK.read(); 1173da5c369Sopenharmony_ci 1183da5c369Sopenharmony_ci let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); 1193da5c369Sopenharmony_ci 1203da5c369Sopenharmony_ci let mut f = File::open(kmod_path).expect("unable to open kernel module"); 1213da5c369Sopenharmony_ci let mut contents: Vec<u8> = Vec::new(); 1223da5c369Sopenharmony_ci f.read_to_end(&mut contents) 1233da5c369Sopenharmony_ci .expect("unable to read kernel module content to buffer"); 1243da5c369Sopenharmony_ci init_module(&contents, &CString::new("who=Nix number=2015").unwrap()) 1253da5c369Sopenharmony_ci .expect("unable to load kernel module"); 1263da5c369Sopenharmony_ci 1273da5c369Sopenharmony_ci delete_module( 1283da5c369Sopenharmony_ci &CString::new(kmod_name).unwrap(), 1293da5c369Sopenharmony_ci DeleteModuleFlags::empty(), 1303da5c369Sopenharmony_ci ) 1313da5c369Sopenharmony_ci .expect("unable to unload kernel module"); 1323da5c369Sopenharmony_ci} 1333da5c369Sopenharmony_ci 1343da5c369Sopenharmony_ci#[test] 1353da5c369Sopenharmony_cifn test_finit_module_invalid() { 1363da5c369Sopenharmony_ci require_capability!("test_finit_module_invalid", CAP_SYS_MODULE); 1373da5c369Sopenharmony_ci let _m0 = crate::KMOD_MTX.lock(); 1383da5c369Sopenharmony_ci let _m1 = crate::CWD_LOCK.read(); 1393da5c369Sopenharmony_ci 1403da5c369Sopenharmony_ci let kmod_path = "/dev/zero"; 1413da5c369Sopenharmony_ci 1423da5c369Sopenharmony_ci let f = File::open(kmod_path).expect("unable to open kernel module"); 1433da5c369Sopenharmony_ci let result = 1443da5c369Sopenharmony_ci finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); 1453da5c369Sopenharmony_ci 1463da5c369Sopenharmony_ci assert_eq!(result.unwrap_err(), Errno::EINVAL); 1473da5c369Sopenharmony_ci} 1483da5c369Sopenharmony_ci 1493da5c369Sopenharmony_ci#[test] 1503da5c369Sopenharmony_cifn test_finit_module_twice_and_delete_module() { 1513da5c369Sopenharmony_ci require_capability!( 1523da5c369Sopenharmony_ci "test_finit_module_twice_and_delete_module", 1533da5c369Sopenharmony_ci CAP_SYS_MODULE 1543da5c369Sopenharmony_ci ); 1553da5c369Sopenharmony_ci let _m0 = crate::KMOD_MTX.lock(); 1563da5c369Sopenharmony_ci let _m1 = crate::CWD_LOCK.read(); 1573da5c369Sopenharmony_ci 1583da5c369Sopenharmony_ci let (kmod_path, kmod_name, _kmod_dir) = compile_kernel_module(); 1593da5c369Sopenharmony_ci 1603da5c369Sopenharmony_ci let f = File::open(kmod_path).expect("unable to open kernel module"); 1613da5c369Sopenharmony_ci finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()) 1623da5c369Sopenharmony_ci .expect("unable to load kernel module"); 1633da5c369Sopenharmony_ci 1643da5c369Sopenharmony_ci let result = 1653da5c369Sopenharmony_ci finit_module(&f, &CString::new("").unwrap(), ModuleInitFlags::empty()); 1663da5c369Sopenharmony_ci 1673da5c369Sopenharmony_ci assert_eq!(result.unwrap_err(), Errno::EEXIST); 1683da5c369Sopenharmony_ci 1693da5c369Sopenharmony_ci delete_module( 1703da5c369Sopenharmony_ci &CString::new(kmod_name).unwrap(), 1713da5c369Sopenharmony_ci DeleteModuleFlags::empty(), 1723da5c369Sopenharmony_ci ) 1733da5c369Sopenharmony_ci .expect("unable to unload kernel module"); 1743da5c369Sopenharmony_ci} 1753da5c369Sopenharmony_ci 1763da5c369Sopenharmony_ci#[test] 1773da5c369Sopenharmony_cifn test_delete_module_not_loaded() { 1783da5c369Sopenharmony_ci require_capability!("test_delete_module_not_loaded", CAP_SYS_MODULE); 1793da5c369Sopenharmony_ci let _m0 = crate::KMOD_MTX.lock(); 1803da5c369Sopenharmony_ci let _m1 = crate::CWD_LOCK.read(); 1813da5c369Sopenharmony_ci 1823da5c369Sopenharmony_ci let result = delete_module( 1833da5c369Sopenharmony_ci &CString::new("hello").unwrap(), 1843da5c369Sopenharmony_ci DeleteModuleFlags::empty(), 1853da5c369Sopenharmony_ci ); 1863da5c369Sopenharmony_ci 1873da5c369Sopenharmony_ci assert_eq!(result.unwrap_err(), Errno::ENOENT); 1883da5c369Sopenharmony_ci} 189