mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-11 10:37:33 +00:00
Migrate prepare_modules to Rust
This commit is contained in:
@@ -309,7 +309,7 @@ impl Directory {
|
||||
self.pre_order_walk_impl(&mut f)
|
||||
}
|
||||
|
||||
pub fn remove_all(&mut self) -> OsResultStatic<()> {
|
||||
pub fn remove_all(mut self) -> OsResultStatic<()> {
|
||||
self.post_order_walk(|e| {
|
||||
e.unlink()?;
|
||||
Ok(WalkResult::Continue)
|
||||
|
@@ -227,7 +227,7 @@ impl Utf8CStr {
|
||||
pub fn remove_all(&self) -> OsResultStatic<()> {
|
||||
let attr = self.get_attr()?;
|
||||
if attr.is_dir() {
|
||||
let mut dir = Directory::try_from(open_fd(self, O_RDONLY | O_CLOEXEC, 0)?)?;
|
||||
let dir = Directory::try_from(open_fd(self, O_RDONLY | O_CLOEXEC, 0)?)?;
|
||||
dir.remove_all()?;
|
||||
}
|
||||
Ok(self.remove()?)
|
||||
|
@@ -5,7 +5,7 @@ use crate::ffi::{
|
||||
exec_module_scripts, get_magisk_tmp, initialize_denylist, setup_magisk_env,
|
||||
};
|
||||
use crate::logging::{magisk_logging, setup_logfile, start_log_daemon};
|
||||
use crate::mount::{clean_mounts, setup_module_mount, setup_preinit_dir};
|
||||
use crate::mount::{clean_mounts, setup_preinit_dir};
|
||||
use crate::package::ManagerInfo;
|
||||
use crate::selinux::restore_tmpcon;
|
||||
use crate::su::SuInfo;
|
||||
@@ -144,10 +144,7 @@ impl MagiskD {
|
||||
Ordering::Release,
|
||||
);
|
||||
initialize_denylist();
|
||||
setup_module_mount();
|
||||
let modules = self.load_modules();
|
||||
self.module_list.set(modules).ok();
|
||||
self.apply_modules();
|
||||
self.handle_modules();
|
||||
clean_mounts();
|
||||
|
||||
false
|
||||
|
@@ -11,32 +11,6 @@ using namespace std;
|
||||
* Filesystem operations
|
||||
************************/
|
||||
|
||||
static void prepare_modules() {
|
||||
// Upgrade modules
|
||||
if (auto dir = open_dir(MODULEUPGRADE); dir) {
|
||||
int ufd = dirfd(dir.get());
|
||||
int mfd = xopen(MODULEROOT, O_RDONLY | O_CLOEXEC);
|
||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
||||
if (entry->d_type == DT_DIR) {
|
||||
// Cleanup old module if exists
|
||||
if (faccessat(mfd, entry->d_name, F_OK, 0) == 0) {
|
||||
int modfd = xopenat(mfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
||||
if (faccessat(modfd, "disable", F_OK, 0) == 0) {
|
||||
auto disable = entry->d_name + "/disable"s;
|
||||
close(xopenat(ufd, disable.data(), O_RDONLY | O_CREAT | O_CLOEXEC, 0));
|
||||
}
|
||||
frm_rf(modfd);
|
||||
unlinkat(mfd, entry->d_name, AT_REMOVEDIR);
|
||||
}
|
||||
LOGI("Upgrade / New module: %s\n", entry->d_name);
|
||||
renameat(ufd, entry->d_name, mfd, entry->d_name);
|
||||
}
|
||||
}
|
||||
close(mfd);
|
||||
rm_rf(MODULEUPGRADE);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
static void foreach_module(Func fn) {
|
||||
auto dir = open_dir(MODULEROOT);
|
||||
@@ -135,7 +109,6 @@ static rust::Vec<ModuleInfo> collect_modules(bool zygisk_enabled, bool open_zygi
|
||||
|
||||
rust::Vec<ModuleInfo> MagiskD::load_modules() const noexcept {
|
||||
bool zygisk = zygisk_enabled();
|
||||
prepare_modules();
|
||||
exec_module_scripts("post-fs-data", collect_modules(zygisk, false));
|
||||
// Recollect modules (module scripts could remove itself)
|
||||
auto list = collect_modules(zygisk, true);
|
||||
|
@@ -1,13 +1,15 @@
|
||||
use crate::consts::{MODULEMNT, MODULEROOT, WORKERDIR};
|
||||
use crate::consts::{MODULEMNT, MODULEROOT, MODULEUPGRADE, WORKERDIR};
|
||||
use crate::daemon::MagiskD;
|
||||
use crate::ffi::{get_magisk_tmp, get_zygisk_lib_name};
|
||||
use crate::ffi::{ModuleInfo, get_magisk_tmp, get_zygisk_lib_name};
|
||||
use crate::load_prop_file;
|
||||
use crate::mount::setup_module_mount;
|
||||
use base::{
|
||||
Directory, FsPathBuilder, LoggedResult, OsResultStatic, ResultExt, Utf8CStr, Utf8CStrBuf,
|
||||
Utf8CString, WalkResult, clone_attr, cstr, debug, error, info, libc, warn,
|
||||
Directory, FsPathBuilder, LibcReturn, LoggedResult, OsResultStatic, ResultExt, Utf8CStr,
|
||||
Utf8CStrBuf, Utf8CString, WalkResult, clone_attr, cstr, debug, error, info, libc, warn,
|
||||
};
|
||||
use libc::{MS_RDONLY, O_CLOEXEC, O_CREAT, O_RDONLY};
|
||||
use libc::{AT_REMOVEDIR, MS_RDONLY, O_CLOEXEC, O_CREAT, O_RDONLY};
|
||||
use std::collections::BTreeMap;
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::path::{Component, Path};
|
||||
|
||||
const MAGISK_BIN_INJECT_PARTITIONS: [&Utf8CStr; 4] = [
|
||||
@@ -548,8 +550,48 @@ fn inject_zygisk_bins(system: &mut FsNode) {
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_modules() -> LoggedResult<()> {
|
||||
let mut upgrade = Directory::open(cstr!(MODULEUPGRADE))?;
|
||||
let ufd = upgrade.as_raw_fd();
|
||||
let root = Directory::open(cstr!(MODULEROOT))?;
|
||||
while let Some(ref e) = upgrade.read()? {
|
||||
if !e.is_dir() {
|
||||
continue;
|
||||
}
|
||||
let module_name = e.name();
|
||||
let mut disable = false;
|
||||
// Cleanup old module if exists
|
||||
if root.contains_path(module_name) {
|
||||
let module = root.open_as_dir_at(module_name)?;
|
||||
// If the old module is disabled, we need to also disable the new one
|
||||
disable = module.contains_path(cstr!("disable"));
|
||||
module.remove_all()?;
|
||||
root.unlink_at(module_name, AT_REMOVEDIR)?;
|
||||
}
|
||||
info!("Upgrade / New module: {module_name}");
|
||||
unsafe {
|
||||
libc::renameat(
|
||||
ufd,
|
||||
module_name.as_ptr(),
|
||||
root.as_raw_fd(),
|
||||
module_name.as_ptr(),
|
||||
)
|
||||
.check_os_err("renameat", Some(module_name), None)?;
|
||||
}
|
||||
if disable {
|
||||
let path = cstr::buf::default()
|
||||
.join_path(module_name)
|
||||
.join_path("disable");
|
||||
let _ = root.open_as_file_at(&path, O_RDONLY | O_CREAT | O_CLOEXEC, 0)?;
|
||||
}
|
||||
}
|
||||
upgrade.remove_all()?;
|
||||
cstr!(MODULEUPGRADE).remove()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl MagiskD {
|
||||
pub fn apply_modules(&self) {
|
||||
fn apply_modules(&self, module_list: &[ModuleInfo]) {
|
||||
let mut system = FsNode::new_dir();
|
||||
|
||||
// Build all the base "prefix" paths
|
||||
@@ -578,7 +620,7 @@ impl MagiskD {
|
||||
// In this step, there is zero logic applied during tree construction; we simply collect and
|
||||
// record the union of all module filesystem trees under each of their /system directory.
|
||||
|
||||
for info in self.module_list.get().iter().flat_map(|v| v.iter()) {
|
||||
for info in module_list {
|
||||
let mut module_paths = root_paths.append(&info.name);
|
||||
{
|
||||
// Read props
|
||||
@@ -656,4 +698,12 @@ impl MagiskD {
|
||||
root.commit(path, true).log_ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_modules(&self) {
|
||||
setup_module_mount();
|
||||
prepare_modules().ok();
|
||||
let modules = self.load_modules();
|
||||
self.apply_modules(&modules);
|
||||
self.module_list.set(modules).ok();
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ pub const LOGFILE: &str = "/cache/magisk.log";
|
||||
// data paths
|
||||
pub const SECURE_DIR: &str = "/data/adb";
|
||||
pub const MODULEROOT: &str = concatcp!(SECURE_DIR, "/modules");
|
||||
pub const MODULEUPGRADE: &str = concatcp!(SECURE_DIR, "/modules_update");
|
||||
pub const DATABIN: &str = concatcp!(SECURE_DIR, "/magisk");
|
||||
pub const MAGISKDB: &str = concatcp!(SECURE_DIR, "/magisk.db");
|
||||
|
||||
|
@@ -21,7 +21,7 @@ pub(crate) fn switch_root(path: &Utf8CStr) {
|
||||
let res: LoggedResult<()> = try {
|
||||
debug!("Switch root to {}", path);
|
||||
let mut mounts = BTreeSet::new();
|
||||
let mut rootfs = Directory::open(cstr!("/"))?;
|
||||
let rootfs = Directory::open(cstr!("/"))?;
|
||||
for info in parse_mount_info("self") {
|
||||
if info.target == "/" || info.target.as_str() == path.as_str() {
|
||||
continue;
|
||||
|
Reference in New Issue
Block a user