hwdrivers.rs (1716B)
1 use std::collections::HashSet; 2 3 use async_process::{Command, Stdio}; 4 use async_trait::async_trait; 5 use blocking::unblock; 6 use futures_lite::StreamExt; 7 use futures_lite::stream::iter; 8 use log::info; 9 use walkdir::WalkDir; 10 11 use kanit_common::error::{Context, Result}; 12 use kanit_unit::{Dependencies, Unit}; 13 14 use crate::oneshot::{DevFs, SysFs}; 15 use crate::unit_name; 16 17 pub struct HwDrivers; 18 19 impl HwDrivers { 20 async fn load_modules() -> Result<()> { 21 // todo; better walker 22 let modules = iter( 23 unblock(move || { 24 WalkDir::new("/sys") 25 .into_iter() 26 .filter_map(|e| e.ok()) 27 .filter(|e| e.file_type().is_file() && e.file_name() == "modalias") 28 }) 29 .await, 30 ) 31 .then(|e| async { async_fs::read_to_string(e.into_path()).await }) 32 .filter_map(|e| e.ok()) 33 .collect::<HashSet<String>>() 34 .await; 35 36 // we don't care about status 37 Command::new("modprobe") 38 .stderr(Stdio::null()) 39 .args(["-b", "-a"]) 40 .args(modules) 41 .spawn() 42 .context("failed to spawn modprobe")? 43 .status() 44 .await 45 .context("failed to wait")?; 46 47 Ok(()) 48 } 49 } 50 51 #[async_trait] 52 impl Unit for HwDrivers { 53 unit_name!("hwdrivers"); 54 55 fn dependencies(&self) -> Dependencies { 56 Dependencies::new() 57 .need(DevFs.name()) 58 .need(SysFs.name()) 59 .clone() 60 } 61 62 async fn start(&mut self) -> Result<()> { 63 info!("loading modules for hardware"); 64 65 Self::load_modules().await?; 66 Self::load_modules().await?; 67 68 Ok(()) 69 } 70 }