Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ksud: add post_mount stage #864

Merged
merged 7 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions userspace/ksud/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ pub fn on_post_data_fs() -> Result<()> {

// exec modules post-fs-data scripts
// TODO: Add timeout
if let Err(e) = crate::module::exec_post_fs_data() {
if let Err(e) = crate::module::exec_stage_script("post-fs-data", true) {
warn!("exec post-fs-data scripts failed: {}", e);
}

Expand All @@ -194,12 +194,14 @@ pub fn on_post_data_fs() -> Result<()> {
warn!("do systemless mount failed: {}", e);
}

run_stage("post-mount", true);

std::env::set_current_dir("/").with_context(|| "failed to chdir to /")?;

Ok(())
}

fn run_stage(stage: &str) {
fn run_stage(stage: &str, block: bool) {
utils::umask(0);

if utils::has_magisk() {
Expand All @@ -212,16 +214,17 @@ fn run_stage(stage: &str) {
return;
}

if let Err(e) = crate::module::exec_common_scripts(&format!("{stage}.d"), false) {
if let Err(e) = crate::module::exec_common_scripts(&format!("{stage}.d"), block) {
warn!("Failed to exec common {stage} scripts: {e}");
}
if let Err(e) = crate::module::exec_stage_scripts(stage) {
if let Err(e) = crate::module::exec_stage_script(stage, block) {
warn!("Failed to exec {stage} scripts: {e}");
}
}

pub fn on_services() -> Result<()> {
run_stage("service");
info!("on_services triggered!");
run_stage("service", false);
Ylarod marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}
Expand All @@ -241,7 +244,7 @@ pub fn on_boot_completed() -> Result<()> {
}
}

run_stage("boot-completed");
run_stage("boot-completed", false);

Ok(())
}
Expand Down
23 changes: 4 additions & 19 deletions userspace/ksud/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,14 @@ fn exec_script<T: AsRef<Path>>(path: T, wait: bool) -> Result<()> {
result.map_err(|err| anyhow!("Failed to exec {}: {}", path.as_ref().display(), err))
}

/// execute every modules' post-fs-data.sh
pub fn exec_post_fs_data() -> Result<()> {
pub fn exec_stage_script(stage: &str, block: bool) -> Result<()> {
foreach_active_module(|module| {
let post_fs_data = module.join("post-fs-data.sh");
if !post_fs_data.exists() {
let script_path = module.join(format!("{stage}.sh"));
if !script_path.exists() {
return Ok(());
}

exec_script(&post_fs_data, true)
exec_script(&script_path, block)
})?;

Ok(())
Expand Down Expand Up @@ -276,20 +275,6 @@ pub fn exec_common_scripts(dir: &str, wait: bool) -> Result<()> {
Ok(())
}

/// execute every modules' [stage].sh (service.sh, boot-completed.sh)
pub fn exec_stage_scripts(stage: &str) -> Result<()> {
foreach_active_module(|module| {
let service = module.join(format!("{stage}.sh"));
if !service.exists() {
return Ok(());
}

exec_script(&service, false)
})?;

Ok(())
}

pub fn load_system_prop() -> Result<()> {
foreach_active_module(|module| {
let system_prop = module.join("system.prop");
Expand Down
1 change: 1 addition & 0 deletions website/docs/guide/difference-with-magisk.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ Here are some differences:
- The directories for BusyBox are different. The built-in BusyBox in KernelSU is located in `/data/adb/ksu/bin/busybox`, while in Magisk it is in `/data/adb/magisk/busybox`. **Note that this is an internal behavior of KernelSU and may change in the future!**
- KernelSU does not support `.replace` files; however, KernelSU supports the `REMOVE` and `REPLACE` variable to remove or replace files and folders.
- KernelSU adds `boot-completed` stage to run some scripts on boot completed.
- KernelSU adds `post-mount` stage to run some scripts after mounting overlayfs
7 changes: 4 additions & 3 deletions website/docs/guide/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ A KernelSU module is a folder placed in `/data/adb/modules` with the structure b
│ │ *** Optional Files ***
│ │
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
│ ├── post-mount.sh <--- This script will be executed in post-mount
│ ├── service.sh <--- This script will be executed in late_start service
│ ├── boot-completed.sh <--- This script will be executed on boot completed
| ├── uninstall.sh <--- This script will be executed when KernelSU removes your module
Expand Down Expand Up @@ -103,7 +104,7 @@ description=<string>

### Shell scripts

Please read the [Boot Scripts](#boot-scripts) section to understand the difference between `post-fs-data.sh` and `service.sh`. For most module developers, `service.sh` should be good enough if you just need to run a boot script, if you need to run the script after boot completed, please use `boot-completed.sh`.
Please read the [Boot Scripts](#boot-scripts) section to understand the difference between `post-fs-data.sh` and `service.sh`. For most module developers, `service.sh` should be good enough if you just need to run a boot script, if you need to run the script after boot completed, please use `boot-completed.sh`. If you want to do something after mounting overlayfs, please use `post-mount.sh`.

In all scripts of your module, please use `MODDIR=${0%/*}` to get your module's base directory path; do **NOT** hardcode your module path in scripts.

Expand Down Expand Up @@ -244,13 +245,13 @@ In KernelSU, scripts are divided into two types based on their running mode: pos
In KernelSU, startup scripts are divided into two types based on their storage location: general scripts and module scripts:

- General Scripts
- Placed in `/data/adb/post-fs-data.d`, `/data/adb/service.d` or `/data/adb/boot-completed.d`
- Placed in `/data/adb/post-fs-data.d`, `/data/adb/service.d`, `/data/adb/post-mount.d` or `/data/adb/boot-completed.d`
- Only executed if the script is set as executable (`chmod +x script.sh`)
- Scripts in `post-fs-data.d` runs in post-fs-data mode, and scripts in `service.d` runs in late_start service mode.
- Modules should **NOT** add general scripts during installation
- Module Scripts
- Placed in the module's own folder
- Only executed if the module is enabled
- `post-fs-data.sh` runs in post-fs-data mode, `service.sh` runs in late_start service mode, `boot-completed.sh` runs on boot completed.
- `post-fs-data.sh` runs in post-fs-data mode, `service.sh` runs in late_start service mode, `boot-completed.sh` runs on boot completed, `post-mount.sh` runs on overlayfs mounted.

All boot scripts will run in KernelSU's BusyBox `ash` shell with "Standalone Mode" enabled.
1 change: 1 addition & 0 deletions website/docs/zh_CN/guide/difference-with-magisk.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@
4. BusyBox 的目录不同;KernelSU 内置的 BusyBox 在 `/data/adb/ksu/bin/busybox` 而 Magisk 在 `/data/adb/magisk/busybox`;**注意此为 KernelSU 内部行为,未来可能会更改!**
5. KernelSU 不支持 `.replace` 文件;但 KernelSU 支持 `REPLACE` 和 `REMOVE` 变量。
6. KernelSU 新增了一种脚本 `boot-completed.sh`,以便在 Android 系统启动后运行某些任务。
7. KernelSU 新增了一种脚本 `post-moount.sh`,以便在 Overlayfs 挂载后运行某些任务。
7 changes: 4 additions & 3 deletions website/docs/zh_CN/guide/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ KernelSU 模块就是一个放置在 `/data/adb/modules` 内且满足如下结
│ │ *** 可选文件 ***
│ │
│ ├── post-fs-data.sh <--- 这个脚本将会在 post-fs-data 模式下运行
│ ├── post-mount.sh <--- 这个脚本将会在 post-mount 模式下运行
│ ├── service.sh <--- 这个脚本将会在 late_start 服务模式下运行
│ ├── boot-completed.sh <--- 这个脚本将会在 Android 系统启动完毕后以服务模式运行
| ├── uninstall.sh <--- 这个脚本将会在模块被卸载时运行
Expand Down Expand Up @@ -107,7 +108,7 @@ description=<string>

### Shell 脚本 {#shell-scripts}

请阅读 [启动脚本](#boot-scripts) 一节,以了解 `post-fs-data.sh`, `service.sh` 和 `boot-completed.sh` 之间的区别。对于大多数模块开发者来说,如果您只需要运行一个启动脚本,`service.sh` 应该已经足够了。
请阅读 [启动脚本](#boot-scripts) 一节,以了解 `post-fs-data.sh`, `post-mount.sh`, `service.sh` 和 `boot-completed.sh` 之间的区别。对于大多数模块开发者来说,如果您只需要运行一个启动脚本,`service.sh` 应该已经足够了。

在您的模块的所有脚本中,请使用 `MODDIR=${0%/*}`来获取您的模块的基本目录路径;请勿在脚本中硬编码您的模块路径。

Expand Down Expand Up @@ -251,14 +252,14 @@ set_perm_recursive <directory> <owner> <group> <dirpermission> <filepermission>
在 KernelSU 中,启动脚本根据存放位置的不同还分为两种:通用脚本和模块脚本。

- 通用脚本
- 放置在 `/data/adb/post-fs-data.d`, `/data/adb/service.d` 或 `/data/adb/boot-completed.d` 中。
- 放置在 `/data/adb/post-fs-data.d`, `/data/adb/post-mount.d`, `/data/adb/service.d` 或 `/data/adb/boot-completed.d` 中。
- 只有在脚本被设置为可执行(`chmod +x script.sh`)时才会被执行。
- 在 `post-fs-data.d` 中的脚本以 post-fs-data 模式运行,在 `service.d` 中的脚本以 late_start 服务模式运行。
- 模块**不应**在安装过程中添加通用脚本。

- 模块脚本
- 放置在模块自己的文件夹中。
- 只有当模块被启用时才会执行。
- `post-fs-data.sh` 以 post-fs-data 模式运行,而 `service.sh` 则以 late_start 服务模式运行,`boot-completed` 在 Android 系统启动完毕后以服务模式运行。
- `post-fs-data.sh` 以 post-fs-data 模式运行,`post-mount.sh` 以 post-mount 模式运行,而 `service.sh` 则以 late_start 服务模式运行,`boot-completed` 在 Android 系统启动完毕后以服务模式运行。

所有启动脚本都将在 KernelSU 的 BusyBox ash shell 中运行,并启用“独立模式”。
Loading