Android折腾重启报set_policy_failed:/data/adb
TL;DR: 修改init脚本,把 init.usb.rc 中 encryption=Require 改成encryption=DeleteIfNecessary,在system分区中应用修改,再重启。
起因¶
调试 KernelSU,把 /data/adb 删了,manager创建了个新的。结果就这样。
原理¶
File based encryption. init脚本会在开机时配置/创建所需要的文件目录结构,但若所设加密策略与实际不匹配,就会报错要求擦除数据。
以LineageOS 23.0为例,
见 system/core/init/builtins.cpp:
if (IsFbeEnabled()) {
if (!FscryptSetDirectoryPolicy(ref_basename, options.fscrypt_action, options.target)) {
return reboot_into_recovery(
{"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + options.target});
}
}
又见 system/core/init/fscrypt_init_extensions.cpp:
bool FscryptSetDirectoryPolicy(const std::string& ref_basename, FscryptAction action,
const std::string& dir) {
if (action == FscryptAction::kNone) {
return true;
}
if (SetPolicyOn(ref_basename, dir) || action == FscryptAction::kAttempt) {
return true;
}
if (action == FscryptAction::kDeleteIfNecessary) {
LOG(ERROR) << "Setting policy failed, deleting: " << dir;
delete_dir_contents(dir);
return SetPolicyOn(ref_basename, dir);
}
return false;
}
而 init.usb.rc 中有:
on post-fs-data
...(skip)
mkdir /data/adb 0700 root root encryption=Require
导致 /data/adb 出加密配置问题时系统会提示擦除数据。
幸好有办法在遇到错误时删掉整个目录……不然从备份恢复也够麻烦的……