KernelSU 模块配置系统完全指南:持久化键值存储、生命周期与高级特性
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
KernelSU 为模块提供了一套内建配置系统,允许模块以键值对形式保存持久或临时配置,并在模块脚本(post-fs-data.sh、service.sh、boot-completed.sh等)中通过ksud module config命令行随时读写。本文基于官方文档 模块配置指南(及日文版 module-config.md),结合 配置系统核心实现 的源码细节,完整讲解配置类型、命令用法、校验限制、生命周期,以及override.description与manage.<feature>两项高级特性,帮助你为模块构建可靠的用户设置、功能开关与运行时状态管理。
配置系统概览
模块配置以二进制格式保存在/data/adb/ksu/module_configs/<module_id>/目录下,每个模块拥有独立配置目录。目录与文件名常量定义于 defs.rs:
pub const MODULE_CONFIG_DIR: &str = concatcp!(WORKING_DIR, "module_configs/"); pub const PERSIST_CONFIG_NAME: &str = "persist.config"; pub const TEMP_CONFIG_NAME: &str = "tmp.config";即一个模块的配置目录中可能包含两个文件:persist.config(持久配置)与tmp.config(临时配置)。文件采用带魔数与版本校验的二进制格式存储,任何 UTF-8 数据(包括换行、控制字符)都能被安全地读写。
配置类型
| 类型 | 文件名 | 生命周期 |
|---|---|---|
| 持久配置 | persist.config | 重启后保留,直到显式删除或模块被卸载 |
| 临时配置 | tmp.config | 每次开机时在 post-fs-data 阶段自动清空 |
优先级规则:读取配置时,对同一个键,临时值优先于持久值。这一合并逻辑在 module_config.rs 的merge_configs函数中实现——先加载持久配置,再用临时配置逐键覆盖:
// Temp config overrides persist config for (key, value) in temp { merged.insert(key, value); }在模块脚本中使用配置
所有模块脚本(post-fs-data.sh、service.sh、boot-completed.sh等)运行时,KSU_MODULE环境变量会被设置为当前模块 ID。从源码看,这一环境变量由 module.rs 中的get_common_script_envs统一注入(同时注入的还有KSU、KSU_VER、KSU_KERNEL_VER_CODE等变量)。因此脚本内可以直接执行ksud module config系列命令而无需显式指定模块 ID。
读取配置值
value=$(ksud module config get my_setting)写入配置值
# 设置持久配置值(重启后保留) ksud module config set my_setting "some value" # 设置临时配置值(重启后清空) ksud module config set --temp runtime_state "active"从 stdin 写入(适合多行或复杂数据)
当值包含换行、JSON 等结构化内容时,可省略位置参数而从 stdin 读取:
# 使用 heredoc 写入多行文本 ksud module config set my_key <<EOF 多行 文本值 EOF # 或从命令管道写入 echo "value" | ksud module config set my_key # 显式指定 stdin 标志(即使提供了位置参数也强制读 stdin) cat file.json | ksud module config set json_data --stdin从 cli.rs 的ModuleConfigCmd::Set实现看,stdin 读取逻辑是:当--stdin标志为真、或未提供位置参数时,读取整个 stdin 直到 EOF 作为值。这意味着--stdin可用于显式区分“以命令行参数传值”和“以 stdin 传值”两种场景。
列出、删除与清空
# 列出全部配置项(合并持久与临时,临时优先) ksud module config list # 删除配置项(默认删除持久配置中的项) ksud module config delete my_setting # 删除临时配置项 ksud module config delete --temp runtime_state # 清空全部持久配置 ksud module config clear # 清空全部临时配置 ksud module config clear --templist命令同样基于merge_configs输出合并结果,格式为key=value逐行打印;若配置为空则输出No config entries found。
校验限制
配置系统在写入时会强制执行以下限制(常量与校验函数均定义于 module_config.rs):
| 限制项 | 数值 | 源码常量 |
|---|---|---|
| 最大键长度 | 256 字节 | MAX_CONFIG_KEY_LEN = 256 |
| 最大值长度 | 1MB(1048576 字节) | MAX_CONFIG_VALUE_LEN = 1024 * 1024 |
| 每个模块最大配置条目数 | 32 个 | MAX_CONFIG_COUNT = 32 |
键格式:必须匹配正则^[a-zA-Z][a-zA-Z0-9._-]+$(与模块 ID 相同的校验规则):
- 必须以字母(a-zA-Z)开头;
- 可包含字母、数字、点号(
.)、下划线(_)、连字符(-); - 最小长度为 2 个字符。
校验实现在validate_config_key中,它复用regex_lite对同一正则进行匹配,与模块 ID 校验保持一致(见 module.rs 的validate_module_id)。
值格式:无任何字符限制——可以包含换行、控制字符等任意 UTF-8 字符。值以“长度前缀 + 原始字节”的二进制形式存储,确保所有数据安全处理;validate_config_value仅检查长度上限,不限制字符集。
条目数校验:save_config在写盘前会通过validate_config_count检查条目总数是否超过 32,超限直接报错。
生命周期
- 开机时:所有模块的临时配置会在 post-fs-data 阶段被自动清空。对应实现为
clear_all_temp_configs(),它遍历module_configs/下每个模块目录并删除其中的tmp.config文件。 - 模块卸载时:该模块的所有配置(持久与临时)会随配置目录一起被删除。对应实现为
clear_module_configs(module_id),直接移除整个<module_id>配置目录,该函数在卸载流程中被调用(见 module.rs 中卸载相关逻辑)。 - 文件格式:配置文件使用魔数
0x4b53554d(即 ASCII 字符串 "KSUM")与版本号(当前为 1)进行校验,读取时魔数或版本不匹配会直接报错,避免解析损坏数据。写入采用“先写临时文件再原子重命名”的方式(save_config中先创建<name>.tmp再fs::rename),并调用sync_all确保落盘,防止意外断电导致文件损坏。
典型使用场景
配置系统最适合以下需求:
- 用户偏好设置:存储用户通过 WebUI 或 action 脚本配置的模块选项;
- 功能开关:无需重新安装即可启用/禁用模块的某个功能;
- 运行时状态:跟踪应在重启时重置的临时状态(使用临时配置);
- 安装期设置:记住模块安装时用户做出的选择;
- 复杂数据:保存 JSON、多行文本、Base64 编码数据或任意结构化内容(上限 1MB)。
最佳实践
- 需要跨重启保留的用户偏好,使用持久配置;
- 应在开机时重置的运行时状态或功能开关,使用临时配置;
- 在脚本中使用配置值之前先做校验;
- 排查配置问题时,使用
ksud module config list查看合并后的完整配置。
高级特性
覆盖模块描述(override.description)
通过设置override.description配置键,可以动态覆盖module.prop中的description字段:
# 覆盖模块描述 ksud module config set override.description "在管理器里显示的自定义描述"当获取模块列表时,如果override.description配置存在,它会替换module.prop中的原始描述。从 module.rs 的模块列表构建逻辑可以看到这一替换过程:
// Apply override.description if let Some(desc) = config.get("override.description") { module_prop_map.insert("description".to_owned(), desc.clone()); }该特性适用于:
- 在模块描述中显示动态状态信息;
- 向用户展示运行时配置详情;
- 无需重新安装即可根据模块状态更新描述。
声明托管功能(manage.<feature>)
模块可以使用manage.<feature>配置模式声明其托管哪些 KernelSU 功能。这些功能与 KernelSU 内部的FeatureId枚举相对应(完整枚举见 feature.rs,共包含su_compat、kernel_umount、sulog、adb_root、selinux_hide五个成员)。
本配置模式支持的功能:
su_compat—— SU 兼容模式kernel_umount—— 内核自动卸载
# 声明本模块托管 SU 兼容模式并将其启用 ksud module config set manage.su_compat true # 声明本模块托管内核卸载并将其禁用 ksud module config set manage.kernel_umount false # 移除功能托管(模块不再控制该功能) ksud module config delete manage.su_compat工作原理:
manage.<feature>键的存在即表示模块正在托管该功能;- 值表示期望状态:
true/1表示启用,false/0(或任何其他值)表示禁用; - 要停止托管某个功能,直接删除该配置键。
布尔值的解析在 module_config.rs 的parse_bool_config中实现:对值做 trim 后,true或1(不区分大小写)视为真,其余一律视为假。
托管功能的暴露与冲突控制:托管功能会通过模块列表 API 以managedFeatures字段(逗号分隔字符串)暴露。在 module.rs 的列表构建中,所有以manage.开头且值为真的配置键会被收集并拼成该字段。其作用包括:
- 让 KernelSU 管理器检测哪些模块托管了哪些 KernelSU 功能;
- 防止多个模块尝试托管同一功能时产生冲突——feature.rs 的
set_feature在写入前会检查该功能是否已被其他模块托管,若被托管且调用方不是托管模块,会直接拒绝修改; - 实现模块与 KernelSU 核心功能之间的更好协调——初始化阶段
init_features会自动跳过被模块托管的功能,把控制权交给对应模块。
警告:仅使用受支持的功能名。请只使用上文列出的预定义功能名(
su_compat、kernel_umount),它们对应 KernelSU 内部真实存在的功能。使用其他功能名不会报错,但没有任何实际作用。
总结
KernelSU 的模块配置系统为模块开发提供了一套安全、可靠且功能完整的键值存储方案:持久/临时双文件模型配合“临时优先”的合并语义,覆盖了从用户偏好到运行时状态的各类需求;严格的键名校验与二进制长度前缀存储保证了数据安全;override.description与manage.<feature>两个高级特性则让模块能够动态影响管理器展示和 KernelSU 核心功能状态。结合 配置实现源码、CLI 定义 与 模块列表逻辑 阅读本文,即可完整掌握这一机制并应用于实际模块开发。
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考