From f98066cb998fc043ef4ca77d1fa8b1a734ba5da5 Mon Sep 17 00:00:00 2001 From: tiann Date: Mon, 16 Jan 2023 12:22:47 +0800 Subject: [PATCH] ksud: support services. close #60 --- userspace/ksud/src/cli.rs | 2 +- userspace/ksud/src/event.rs | 16 ++++++++++++++- userspace/ksud/src/module.rs | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/userspace/ksud/src/cli.rs b/userspace/ksud/src/cli.rs index 9c08348a..78862bad 100644 --- a/userspace/ksud/src/cli.rs +++ b/userspace/ksud/src/cli.rs @@ -89,7 +89,7 @@ pub fn run() -> Result<()> { } Commands::Install => event::install(), Commands::Sepolicy => todo!(), - Commands::Services => todo!(), + Commands::Services => event::on_services(), }; if let Err(e) = &result { diff --git a/userspace/ksud/src/event.rs b/userspace/ksud/src/event.rs index 0cc5321d..824ad386 100644 --- a/userspace/ksud/src/event.rs +++ b/userspace/ksud/src/event.rs @@ -1,6 +1,9 @@ use std::path::{Path, PathBuf}; -use crate::{defs, utils::{mount_image, ensure_clean_dir}}; +use crate::{ + defs, + utils::{ensure_clean_dir, mount_image}, +}; use anyhow::{bail, Result}; use subprocess::Exec; @@ -102,6 +105,17 @@ pub fn on_post_data_fs() -> Result<()> { Ok(()) } +pub fn on_services() -> Result<()> { + // exec modules service.sh scripts + if !crate::utils::is_safe_mode().unwrap_or(false) { + let _ = crate::module::exec_services(); + } else { + println!("safe mode, skip module post-fs-data scripts"); + } + + Ok(()) +} + pub fn on_boot_completed() -> Result<()> { let module_update_img = Path::new(defs::MODULE_UPDATE_IMG); let module_img = Path::new(defs::MODULE_IMG); diff --git a/userspace/ksud/src/module.rs b/userspace/ksud/src/module.rs index 988d7030..d2e1dfdd 100644 --- a/userspace/ksud/src/module.rs +++ b/userspace/ksud/src/module.rs @@ -190,6 +190,44 @@ pub fn exec_post_fs_data() -> Result<()> { Ok(()) } +/// execute every modules' service.sh +pub fn exec_services() -> 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 disabled = path.join(defs::DISABLE_FILE_NAME); + if disabled.exists() { + println!("{} is disabled, skip", path.display()); + continue; + } + + let service = path.join("service.sh"); + if !service.exists() { + continue; + } + println!("exec {} service.sh", path.display()); + + // pre_exec is unsafe! + unsafe { + Command::new("/system/bin/sh") + .arg(&service) + .process_group(0) + .pre_exec(|| { + // ignore the error? + let _ = switch_cgroups(); + Ok(()) + }) + .current_dir(path) + .env("KSU", "true") + .spawn() // don't wait + .with_context(|| format!("Failed to exec {}", service.display()))?; + } + } + + Ok(()) +} + const RESETPROP: &[u8] = include_bytes!("./resetprop"); const RESETPROP_PATH: &str = concatcp!(defs::WORKING_DIR, "/resetprop");