From d087ec510e83b0d6f6fd9091ec32c89e06b3a4af Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Mon, 14 Apr 2025 15:26:30 +0800 Subject: [PATCH] Ksud: refactor KPM event handling logic, add error handling and ensure KPM catalog exists --- userspace/ksud/src/kpm.rs | 106 +++++++++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 31 deletions(-) diff --git a/userspace/ksud/src/kpm.rs b/userspace/ksud/src/kpm.rs index cc0b0f4c..0e0e84bc 100644 --- a/userspace/ksud/src/kpm.rs +++ b/userspace/ksud/src/kpm.rs @@ -3,11 +3,13 @@ use notify::{Watcher, RecursiveMode}; use std::path::Path; use std::fs; use anyhow::anyhow; +use std::ffi::OsStr; pub const KPM_DIR: &str = "/data/adb/kpm"; pub const KPMMGR_PATH: &str = "/data/adb/ksu/bin/kpmmgr"; +// 确保 KPM 目录存在,如果不存在则创建 pub fn ensure_kpm_dir() -> Result<()> { if !Path::new(KPM_DIR).exists() { fs::create_dir_all(KPM_DIR)?; @@ -39,83 +41,125 @@ pub fn start_kpm_watcher() -> Result<()> { Ok(()) } +// 处理 KPM 事件 pub fn handle_kpm_event(event: notify::Event) { match event.kind { - notify::EventKind::Create(_) => { - event.paths.iter().for_each(|path| { - if path.extension().is_some_and(|ext| ext == "kpm") { - let _ = load_kpm(path); - } - }); - } - notify::EventKind::Remove(_) => { - event.paths.iter().for_each(|path| { - if let Some(name) = path.file_stem() { - let _ = unload_kpm(name.to_string_lossy().as_ref()); - } - }); - } + notify::EventKind::Create(_) => handle_create_event(event.paths), + notify::EventKind::Remove(_) => handle_remove_event(event.paths), + notify::EventKind::Modify(_) => handle_modify_event(event.paths), _ => {} } } +fn handle_create_event(paths: Vec) { + for path in paths { + if path.extension() == Some(OsStr::new("kpm")) { + if let Err(e) = load_kpm(&path) { + log::warn!("Failed to load {}: {}", path.display(), e); + } + } + } +} + +fn handle_remove_event(paths: Vec) { + for path in paths { + if let Some(name) = path.file_stem().and_then(|s| s.to_str()) { + if let Err(e) = unload_kpm(name) { + log::warn!("Failed to unload {}: {}", name, e); + } + if let Err(e) = fs::remove_file(&path) { + log::error!("Failed to delete file: {}: {}", path.display(), e); + } + } + } +} + +// 加载 KPM 模块 pub fn load_kpm(path: &Path) -> Result<()> { + let path_str = path.to_str().ok_or_else(|| anyhow!("Invalid path: {}", path.display()))?; let status = std::process::Command::new(KPMMGR_PATH) - .args(["load", path.to_str().unwrap(), ""]) + .args(["load", path_str, ""]) .status()?; - + if status.success() { log::info!("Loaded KPM: {}", path.display()); } Ok(()) } +// 卸载 KPM 模块并尝试删除对应文件 pub fn unload_kpm(name: &str) -> Result<()> { let status = std::process::Command::new(KPMMGR_PATH) .args(["unload", name]) .status() .map_err(|e| anyhow!("Failed to execute kpmmgr: {}", e))?; - let kpm_path = Path::new(KPM_DIR).join(format!("{}.kpm", name)); - if kpm_path.exists() { - fs::remove_file(&kpm_path) - .map_err(|e| anyhow!("Failed to delete KPM file: {}", e)) - .map(|_| log::info!("Deleted KPM file: {}", kpm_path.display()))?; - } - if status.success() { + let kpm_path = find_kpm_file(name)?; + if let Some(path) = kpm_path { + fs::remove_file(&path) + .map_err(|e| anyhow!("Failed to delete KPM file: {}: {}", path.display(), e))?; + log::info!("Deleted KPM file: {}", path.display()); + } + log::info!("Successfully unloaded KPM: {}", name); } else { log::warn!("KPM unloading may have failed: {}", name); } - + Ok(()) } +// 通过名称查找 KPM 文件 +fn find_kpm_file(name: &str) -> Result> { + let kpm_dir = Path::new(KPM_DIR); + if !kpm_dir.exists() { + return Ok(None); + } + + for entry in fs::read_dir(kpm_dir)? { + let path = entry?.path(); + if let Some(file_name) = path.file_stem() { + if let Some(file_name_str) = file_name.to_str() { + if file_name_str == name && path.extension() == Some(OsStr::new("kpm")) { + return Ok(Some(path)); + } + } + } + } + Ok(None) +} + +// 安全模式下删除所有 KPM 模块 pub fn remove_all_kpms() -> Result<()> { ensure_kpm_dir()?; - + for entry in fs::read_dir(KPM_DIR)? { let path = entry?.path(); if path.extension().is_some_and(|ext| ext == "kpm") { if let Some(name) = path.file_stem() { - unload_kpm(name.to_string_lossy().as_ref()) - .unwrap_or_else(|e| log::error!("Failed to remove KPM: {}", e)); - let _ = fs::remove_file(&path); + if let Err(e) = unload_kpm(name.to_string_lossy().as_ref()) { + log::error!("Failed to remove KPM: {}", e); + } + if let Err(e) = fs::remove_file(&path) { + log::error!("Failed to delete file: {}: {}", path.display(), e); + } } } } Ok(()) } -// 加载所有现有的 KPM 模块 +// 系统启动后加载所有现有的 KPM 模块 pub fn load_existing_kpms() -> Result<()> { ensure_kpm_dir()?; - + for entry in fs::read_dir(KPM_DIR)? { let path = entry?.path(); if path.extension().map_or(false, |ext| ext == "kpm") { - let _ = load_kpm(&path); + if let Err(e) = load_kpm(&path) { + log::warn!("Failed to load {}: {}", path.display(), e); + } } } Ok(())