diff --git a/userspace/ksud/src/event.rs b/userspace/ksud/src/event.rs index 3a8c0827..61aa7ea2 100644 --- a/userspace/ksud/src/event.rs +++ b/userspace/ksud/src/event.rs @@ -3,6 +3,7 @@ use log::{info, warn}; use std::path::PathBuf; use std::{collections::HashMap, path::Path}; +use crate::module::prune_modules; use crate::{ assets, defs, mount, restorecon, utils::{self, ensure_clean_dir, ensure_dir_exists}, @@ -148,6 +149,10 @@ pub fn on_post_data_fs() -> Result<()> { return Ok(()); } + if let Err(e) = prune_modules() { + warn!("prune modules failed: {}", e); + } + // Then exec common post-fs-data scripts if let Err(e) = crate::module::exec_common_scripts("post-fs-data.d", true) { warn!("exec common post-fs-data scripts failed: {}", e); diff --git a/userspace/ksud/src/module.rs b/userspace/ksud/src/module.rs index d917368c..d0144385 100644 --- a/userspace/ksud/src/module.rs +++ b/userspace/ksud/src/module.rs @@ -158,11 +158,14 @@ pub fn load_sepolicy_rule() -> Result<()> { let dir = std::fs::read_dir(modules_dir)?; for entry in dir.flatten() { let path = entry.path(); - let disabled = path.join(defs::DISABLE_FILE_NAME); - if disabled.exists() { + if path.join(defs::DISABLE_FILE_NAME).exists() { info!("{} is disabled, skip", path.display()); continue; } + if path.join(defs::REMOVE_FILE_NAME).exists() { + warn!("{} is removed, skip", path.display()); + continue; + } let rule_file = path.join("sepolicy.rule"); if !rule_file.exists() { @@ -225,9 +228,12 @@ pub fn exec_post_fs_data() -> Result<()> { let dir = std::fs::read_dir(modules_dir)?; for entry in dir.flatten() { let path = entry.path(); - let disabled = path.join(defs::DISABLE_FILE_NAME); - if disabled.exists() { - warn!("{} is disabled, skip", path.display()); + if path.join(defs::DISABLE_FILE_NAME).exists() { + info!("{} is disabled, skip", path.display()); + continue; + } + if path.join(defs::REMOVE_FILE_NAME).exists() { + warn!("{} is removed, skip", path.display()); continue; } @@ -270,9 +276,12 @@ pub fn exec_services() -> Result<()> { let dir = std::fs::read_dir(modules_dir)?; for entry in dir.flatten() { let path = entry.path(); - let disabled = path.join(defs::DISABLE_FILE_NAME); - if disabled.exists() { - warn!("{} is disabled, skip", path.display()); + if path.join(defs::DISABLE_FILE_NAME).exists() { + info!("{} is disabled, skip", path.display()); + continue; + } + if path.join(defs::REMOVE_FILE_NAME).exists() { + warn!("{} is removed, skip", path.display()); continue; } @@ -292,11 +301,14 @@ pub fn load_system_prop() -> Result<()> { let dir = std::fs::read_dir(modules_dir)?; for entry in dir.flatten() { let path = entry.path(); - let disabled = path.join(defs::DISABLE_FILE_NAME); - if disabled.exists() { + if path.join(defs::DISABLE_FILE_NAME).exists() { info!("{} is disabled, skip", path.display()); continue; } + if path.join(defs::REMOVE_FILE_NAME).exists() { + warn!("{} is removed, skip", path.display()); + continue; + } let system_prop = path.join("system.prop"); if !system_prop.exists() { @@ -316,6 +328,33 @@ pub fn load_system_prop() -> Result<()> { Ok(()) } +pub fn prune_modules() -> Result<()> { + let modules_dir = Path::new(defs::MODULE_DIR); + let dir = std::fs::read_dir(modules_dir)?; + for entry in dir.flatten() { + let path = entry.path(); + let remove = path.join(defs::REMOVE_FILE_NAME); + if !remove.exists() { + continue; + } + + info!("remove module: {}", path.display()); + + let uninstaller = path.join("uninstall.sh"); + if uninstaller.exists() { + if let Err(e) = exec_script(uninstaller, true) { + warn!("Failed to exec uninstaller: {}", e); + } + } + + if let Err(e) = remove_dir_all(&path) { + warn!("Failed to remove {}: {}", path.display(), e); + } + } + + Ok(()) +} + fn _install_module(zip: &str) -> Result<()> { ensure_boot_completed()?; @@ -557,11 +596,8 @@ pub fn uninstall_module(id: &str) -> Result<()> { } })?; if module_id.eq(mid) { - let uninstall_script = path.join("uninstall.sh"); - if uninstall_script.exists() { - exec_script(uninstall_script, true)?; - } - remove_dir_all(path)?; + let remove_file = path.join(defs::REMOVE_FILE_NAME); + File::create(remove_file).with_context(|| "Failed to create remove file.")?; break; } } @@ -570,7 +606,10 @@ pub fn uninstall_module(id: &str) -> Result<()> { let target_module_path = format!("{update_dir}/{mid}"); let target_module = Path::new(&target_module_path); if target_module.exists() { - remove_dir_all(target_module)?; + let remove_file = target_module.join(defs::REMOVE_FILE_NAME); + if !remove_file.exists() { + File::create(remove_file).with_context(|| "Failed to create remove file.")?; + } } let _ = mark_module_state(id, defs::REMOVE_FILE_NAME, true);