From 6c612d66d74b0e251397f47a13f800aea8fbc0c4 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Thu, 30 Jan 2025 18:39:34 +0800 Subject: [PATCH] Move BootConfig to rust --- native/src/base/include/base.hpp | 3 ++- native/src/init/getinfo.cpp | 38 +++++++++++++++++--------------- native/src/init/init.hpp | 20 ----------------- native/src/init/lib.rs | 21 ++++++++++++++++++ native/src/init/mount.cpp | 6 ++--- native/src/init/selinux.cpp | 4 ++-- 6 files changed, 48 insertions(+), 44 deletions(-) diff --git a/native/src/base/include/base.hpp b/native/src/base/include/base.hpp index 01d350a58..c2888fd76 100644 --- a/native/src/base/include/base.hpp +++ b/native/src/base/include/base.hpp @@ -7,4 +7,5 @@ #include "../base-rs.hpp" using rust::xpipe2; -using rust::fd_path; \ No newline at end of file +using rust::fd_path; +using kv_pairs = std::vector>; diff --git a/native/src/init/getinfo.cpp b/native/src/init/getinfo.cpp index 28cd20bae..5c42b9c47 100644 --- a/native/src/init/getinfo.cpp +++ b/native/src/init/getinfo.cpp @@ -118,7 +118,7 @@ static bool check_key_combo() { return false; } -void BootConfig::set(const kv_pairs &kv) { +void BootConfig::set(const kv_pairs &kv) noexcept { for (const auto &[key, value] : kv) { if (key == "androidboot.slot_suffix") { // Many Amlogic devices are A-only but have slot_suffix... @@ -126,10 +126,10 @@ void BootConfig::set(const kv_pairs &kv) { LOGW("Skip invalid androidboot.slot_suffix=[normal]\n"); continue; } - strscpy(slot, value.data(), sizeof(slot)); + strscpy(slot.data(), value.data(), slot.size()); } else if (key == "androidboot.slot") { slot[0] = '_'; - strscpy(slot + 1, value.data(), sizeof(slot) - 1); + strscpy(slot.data() + 1, value.data(), slot.size() - 1); } else if (key == "skip_initramfs") { skip_initramfs = true; } else if (key == "androidboot.force_normal_boot") { @@ -137,13 +137,13 @@ void BootConfig::set(const kv_pairs &kv) { } else if (key == "rootwait") { rootwait = true; } else if (key == "androidboot.android_dt_dir") { - strscpy(dt_dir, value.data(), sizeof(dt_dir)); + strscpy(dt_dir.data(), value.data(), dt_dir.size()); } else if (key == "androidboot.hardware") { - strscpy(hardware, value.data(), sizeof(hardware)); + strscpy(hardware.data(), value.data(), hardware.size()); } else if (key == "androidboot.hardware.platform") { - strscpy(hardware_plat, value.data(), sizeof(hardware_plat)); + strscpy(hardware_plat.data(), value.data(), hardware_plat.size()); } else if (key == "androidboot.fstab_suffix") { - strscpy(fstab_suffix, value.data(), sizeof(fstab_suffix)); + strscpy(fstab_suffix.data(), value.data(), fstab_suffix.size()); } else if (key == "qemu") { emulator = true; } else if (key == "androidboot.partition_map") { @@ -151,34 +151,36 @@ void BootConfig::set(const kv_pairs &kv) { // For example, "androidboot.partition_map=vdb,metadata;vdc,userdata" maps // "vdb" to "metadata", and "vdc" to "userdata". // https://android.googlesource.com/platform/system/core/+/refs/heads/android13-release/init/devices.cpp#191 - partition_map = parse_partition_map(value); + for (const auto &[k, v]: parse_partition_map(value)) { + partition_map.emplace_back(k, v); + } } } } -void BootConfig::print() { +void BootConfig::print() const noexcept { LOGD("skip_initramfs=[%d]\n", skip_initramfs); LOGD("force_normal_boot=[%d]\n", force_normal_boot); LOGD("rootwait=[%d]\n", rootwait); - LOGD("slot=[%s]\n", slot); - LOGD("dt_dir=[%s]\n", dt_dir); - LOGD("fstab_suffix=[%s]\n", fstab_suffix); - LOGD("hardware=[%s]\n", hardware); - LOGD("hardware.platform=[%s]\n", hardware_plat); + LOGD("slot=[%s]\n", slot.data()); + LOGD("dt_dir=[%s]\n", dt_dir.data()); + LOGD("fstab_suffix=[%s]\n", fstab_suffix.data()); + LOGD("hardware=[%s]\n", hardware.data()); + LOGD("hardware.platform=[%s]\n", hardware_plat.data()); LOGD("emulator=[%d]\n", emulator); } #define read_dt(name, key) \ -ssprintf(file_name, sizeof(file_name), "%s/" name, dt_dir); \ +ssprintf(file_name, sizeof(file_name), "%s/" name, dt_dir.data()); \ if (access(file_name, R_OK) == 0) { \ string data = full_read(file_name); \ if (!data.empty()) { \ data.pop_back(); \ - strscpy(key, data.data(), sizeof(key)); \ + strscpy(key.data(), data.data(), key.size()); \ } \ } -void BootConfig::init() { +void BootConfig::init() noexcept { set(parse_cmdline(full_read("/proc/cmdline"))); set(parse_bootconfig(full_read("/proc/bootconfig"))); @@ -191,7 +193,7 @@ void BootConfig::init() { }); if (dt_dir[0] == '\0') - strscpy(dt_dir, DEFAULT_DT_DIR, sizeof(dt_dir)); + strscpy(dt_dir.data(), DEFAULT_DT_DIR, dt_dir.size()); char file_name[128]; read_dt("fstab_suffix", fstab_suffix) diff --git a/native/src/init/init.hpp b/native/src/init/init.hpp index c2cd3a097..dbf3a3caf 100644 --- a/native/src/init/init.hpp +++ b/native/src/init/init.hpp @@ -3,26 +3,6 @@ #include "init-rs.hpp" -using kv_pairs = std::vector>; - -struct BootConfig { - bool skip_initramfs; - bool force_normal_boot; - bool rootwait; - bool emulator; - char slot[3]; - char dt_dir[64]; - char fstab_suffix[32]; - char hardware[32]; - char hardware_plat[32]; - kv_pairs partition_map; - - void init(); -private: - void set(const kv_pairs &); - void print(); -}; - #define DEFAULT_DT_DIR "/proc/device-tree/firmware/android" #define INIT_PATH "/system/bin/init" #define REDIR_PATH "/data/magiskinit" diff --git a/native/src/init/lib.rs b/native/src/init/lib.rs index fc50dc54f..00567bd8c 100644 --- a/native/src/init/lib.rs +++ b/native/src/init/lib.rs @@ -14,6 +14,23 @@ mod rootdir; #[cxx::bridge] pub mod ffi { + struct KeyValue { + key: String, + value: String, + } + struct BootConfig { + skip_initramfs: bool, + force_normal_boot: bool, + rootwait: bool, + emulator: bool, + slot: [c_char; 3], + dt_dir: [c_char; 64], + fstab_suffix: [c_char; 32], + hardware: [c_char; 32], + hardware_plat: [c_char; 32], + partition_map: Vec, + } + #[namespace = "rust"] extern "Rust" { fn setup_klog(); @@ -30,5 +47,9 @@ pub mod ffi { #[namespace = "rust"] #[cxx_name = "Utf8CStr"] type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>; + fn init(self: &mut BootConfig); + fn print(self: &BootConfig); + type kv_pairs; + fn set(self: &mut BootConfig, config: &kv_pairs); } } diff --git a/native/src/init/mount.cpp b/native/src/init/mount.cpp index a4da46866..b40bba317 100644 --- a/native/src/init/mount.cpp +++ b/native/src/init/mount.cpp @@ -60,10 +60,10 @@ void MagiskInit::collect_devices() { strscpy(dev.dmname, name.data(), sizeof(dev.dmname)); } if (auto it = std::ranges::find_if(config.partition_map, [&](const auto &i) { - return i.first == dev.devname; + return i.key == dev.devname; }); dev.partname[0] == '\0' && it != config.partition_map.end()) { // use androidboot.partition_map as partname fallback. - strscpy(dev.partname, it->second.data(), sizeof(dev.partname)); + strscpy(dev.partname, it->value.data(), sizeof(dev.partname)); } sprintf(path, "/sys/dev/block/%s", entry->d_name); xrealpath(path, dev.devpath, sizeof(dev.devpath)); @@ -163,7 +163,7 @@ bool MagiskInit::mount_system_root() { // Try normal partname char sys_part[32]; - sprintf(sys_part, "system%s", config.slot); + sprintf(sys_part, "system%s", config.slot.data()); dev = find_block(sys_part); if (dev > 0) goto mount_root; diff --git a/native/src/init/selinux.cpp b/native/src/init/selinux.cpp index 8a4a0e0fb..57325a002 100644 --- a/native/src/init/selinux.cpp +++ b/native/src/init/selinux.cpp @@ -64,7 +64,7 @@ bool MagiskInit::hijack_sepolicy() { // This only happens on Android 8.0 - 9.0 char buf[4096]; - ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir); + ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir.data()); dt_compat = full_read(buf); if (dt_compat.empty()) { // Device does not do early mount and uses monolithic policy @@ -106,7 +106,7 @@ bool MagiskInit::hijack_sepolicy() { int fd = xopen(MOCK_COMPAT, O_WRONLY); char buf[4096]; - ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir); + ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config.dt_dir.data()); xumount2(buf, MNT_DETACH); hijack();