mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-23 18:15:30 +00:00
Eliminate unnecessarily copy on magiskinit
This patch reuses the abused /data tmpfs for magisktmp
This commit is contained in:
parent
0d38c94c9c
commit
4ed34cd648
@ -25,6 +25,7 @@ struct BootConfig {
|
||||
|
||||
#define DEFAULT_DT_DIR "/proc/device-tree/firmware/android"
|
||||
#define INIT_PATH "/system/bin/init"
|
||||
#define REDIR_PATH "/data/magiskinit"
|
||||
|
||||
extern std::vector<std::string> mount_list;
|
||||
|
||||
@ -48,6 +49,7 @@ protected:
|
||||
char **argv = nullptr;
|
||||
|
||||
[[noreturn]] void exec_init();
|
||||
void prepare_data();
|
||||
public:
|
||||
BaseInit(char *argv[], BootConfig *config = nullptr) : config(config), argv(argv) {}
|
||||
virtual ~BaseInit() = default;
|
||||
@ -58,8 +60,6 @@ class MagiskInit : public BaseInit {
|
||||
private:
|
||||
void mount_rules_dir();
|
||||
protected:
|
||||
mmap_data self;
|
||||
mmap_data magisk_cfg;
|
||||
std::string custom_rules_dir;
|
||||
|
||||
#if ENABLE_AVD_HACK
|
||||
@ -72,16 +72,12 @@ protected:
|
||||
bool hijack_sepolicy();
|
||||
void setup_tmp(const char *path);
|
||||
void patch_rw_root();
|
||||
void patch_ro_root();
|
||||
public:
|
||||
using BaseInit::BaseInit;
|
||||
};
|
||||
|
||||
class SARBase : public MagiskInit {
|
||||
protected:
|
||||
std::vector<raw_file> overlays;
|
||||
|
||||
void backup_files();
|
||||
void patch_ro_root();
|
||||
public:
|
||||
using MagiskInit::MagiskInit;
|
||||
};
|
||||
@ -134,6 +130,7 @@ public:
|
||||
LOGD("%s\n", __FUNCTION__);
|
||||
};
|
||||
void start() override {
|
||||
prepare_data();
|
||||
if (mount_system_root())
|
||||
first_stage_prep();
|
||||
else
|
||||
|
@ -214,8 +214,6 @@ success:
|
||||
}
|
||||
|
||||
bool LegacySARInit::mount_system_root() {
|
||||
backup_files();
|
||||
|
||||
LOGD("Mounting system_root\n");
|
||||
|
||||
// there's no /dev in stub cpio
|
||||
@ -296,11 +294,19 @@ void BaseInit::exec_init() {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void BaseInit::prepare_data() {
|
||||
LOGD("Setup data tmp\n");
|
||||
xmkdir("/data", 0755);
|
||||
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
|
||||
|
||||
cp_afc("/init", "/data/magiskinit");
|
||||
cp_afc("/.backup", "/data/.backup");
|
||||
cp_afc("/overlay.d", "/data/overlay.d");
|
||||
}
|
||||
|
||||
void MagiskInit::setup_tmp(const char *path) {
|
||||
LOGD("Setup Magisk tmp at %s\n", path);
|
||||
xmount("tmpfs", path, "tmpfs", 0, "mode=755");
|
||||
|
||||
chdir(path);
|
||||
chdir("/data");
|
||||
|
||||
xmkdir(INTLROOT, 0755);
|
||||
xmkdir(MIRRDIR, 0);
|
||||
@ -308,14 +314,15 @@ void MagiskInit::setup_tmp(const char *path) {
|
||||
|
||||
mount_rules_dir();
|
||||
|
||||
int fd = xopen(INTLROOT "/config", O_WRONLY | O_CREAT, 0);
|
||||
xwrite(fd, magisk_cfg.buf, magisk_cfg.sz);
|
||||
close(fd);
|
||||
cp_afc(".backup/.magisk", INTLROOT "/config");
|
||||
rm_rf(".backup");
|
||||
|
||||
// Create applet symlinks
|
||||
for (int i = 0; applet_names[i]; ++i)
|
||||
xsymlink("./magisk", applet_names[i]);
|
||||
xsymlink("./magiskpolicy", "supolicy");
|
||||
|
||||
xmount(".", path, nullptr, MS_BIND, nullptr);
|
||||
|
||||
chdir("/");
|
||||
}
|
||||
|
@ -130,19 +130,6 @@ static void magic_mount(const string &sdir, const string &ddir = "") {
|
||||
}
|
||||
}
|
||||
|
||||
void SARBase::backup_files() {
|
||||
if (access("/overlay.d", F_OK) == 0)
|
||||
backup_folder("/overlay.d", overlays);
|
||||
else if (access("/data/overlay.d", F_OK) == 0)
|
||||
backup_folder("/data/overlay.d", overlays);
|
||||
|
||||
self = mmap_data("/proc/self/exe");
|
||||
if (access("/.backup/.magisk", R_OK) == 0)
|
||||
magisk_cfg = mmap_data("/.backup/.magisk");
|
||||
else if (access("/data/.backup/.magisk", R_OK) == 0)
|
||||
magisk_cfg = mmap_data("/data/.backup/.magisk");
|
||||
}
|
||||
|
||||
static void patch_socket_name(const char *path) {
|
||||
static char rstr[16] = { 0 };
|
||||
if (rstr[0] == '\0')
|
||||
@ -181,7 +168,9 @@ static void extract_files(bool sbin) {
|
||||
#define ROOTMIR MIRRDIR "/system_root"
|
||||
#define NEW_INITRC "/system/etc/init/hw/init.rc"
|
||||
|
||||
void SARBase::patch_ro_root() {
|
||||
void MagiskInit::patch_ro_root() {
|
||||
mount_list.emplace_back("/data");
|
||||
|
||||
string tmp_dir;
|
||||
|
||||
if (access("/sbin", F_OK) == 0) {
|
||||
@ -205,7 +194,7 @@ void SARBase::patch_ro_root() {
|
||||
if (tmp_dir == "/sbin")
|
||||
recreate_sbin(ROOTMIR "/sbin", true);
|
||||
|
||||
xmkdir(ROOTOVL, 0);
|
||||
xrename("overlay.d", ROOTOVL);
|
||||
|
||||
#if ENABLE_AVD_HACK
|
||||
// Handle avd hack
|
||||
@ -222,9 +211,6 @@ void SARBase::patch_ro_root() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle overlay.d
|
||||
restore_folder(ROOTOVL, overlays);
|
||||
overlays.clear();
|
||||
load_overlay_rc(ROOTOVL);
|
||||
if (access(ROOTOVL "/sbin", F_OK) == 0) {
|
||||
// Move files in overlay.d/sbin into tmp_dir
|
||||
@ -260,9 +246,7 @@ void SARBase::patch_ro_root() {
|
||||
}
|
||||
|
||||
void RootFSInit::prepare() {
|
||||
self = mmap_data("/init");
|
||||
magisk_cfg = mmap_data("/.backup/.magisk");
|
||||
|
||||
prepare_data();
|
||||
LOGD("Restoring /init\n");
|
||||
rename(backup_init(), "/init");
|
||||
}
|
||||
@ -270,6 +254,7 @@ void RootFSInit::prepare() {
|
||||
#define PRE_TMPDIR "/magisk-tmp"
|
||||
|
||||
void MagiskInit::patch_rw_root() {
|
||||
mount_list.emplace_back("/data");
|
||||
// Create hardlink mirror of /sbin to /root
|
||||
mkdir("/root", 0777);
|
||||
clone_attr("/sbin", "/root");
|
||||
@ -307,9 +292,7 @@ void MagiskInit::patch_rw_root() {
|
||||
chdir("/");
|
||||
|
||||
// Dump magiskinit as magisk
|
||||
int fd = xopen("/sbin/magisk", O_WRONLY | O_CREAT, 0755);
|
||||
write(fd, self.buf, self.sz);
|
||||
close(fd);
|
||||
cp_afc(REDIR_PATH, "/sbin/magisk");
|
||||
}
|
||||
|
||||
int magisk_proxy_main(int argc, char *argv[]) {
|
||||
|
@ -8,30 +8,15 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define REDIR_PATH "/data/magiskinit"
|
||||
|
||||
void FirstStageInit::prepare() {
|
||||
xmkdirs("/data", 0755);
|
||||
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
|
||||
cp_afc("/init" /* magiskinit */, REDIR_PATH);
|
||||
|
||||
prepare_data();
|
||||
restore_ramdisk_init();
|
||||
|
||||
{
|
||||
auto init = mmap_data("/init", true);
|
||||
// Redirect original init to magiskinit
|
||||
init.patch({ make_pair(INIT_PATH, REDIR_PATH) });
|
||||
}
|
||||
|
||||
// Copy files to tmpfs
|
||||
cp_afc(".backup", "/data/.backup");
|
||||
cp_afc("overlay.d", "/data/overlay.d");
|
||||
auto init = mmap_data("/init", true);
|
||||
// Redirect original init to magiskinit
|
||||
init.patch({ make_pair(INIT_PATH, REDIR_PATH) });
|
||||
}
|
||||
|
||||
void LegacySARInit::first_stage_prep() {
|
||||
xmkdir("/data", 0755);
|
||||
xmount("tmpfs", "/data", "tmpfs", 0, "mode=755");
|
||||
|
||||
// Patch init binary
|
||||
int src = xopen("/init", O_RDONLY);
|
||||
int dest = xopen("/data/init", O_CREAT | O_WRONLY, 0);
|
||||
@ -43,29 +28,11 @@ void LegacySARInit::first_stage_prep() {
|
||||
close(dest);
|
||||
}
|
||||
xmount("/data/init", "/init", nullptr, MS_BIND, nullptr);
|
||||
|
||||
// Replace redirect init with magiskinit
|
||||
dest = xopen(REDIR_PATH, O_CREAT | O_WRONLY, 0);
|
||||
write(dest, self.buf, self.sz);
|
||||
fclone_attr(src, dest);
|
||||
close(src);
|
||||
close(dest);
|
||||
|
||||
// Copy files to tmpfs
|
||||
xmkdir("/data/.backup", 0);
|
||||
xmkdir("/data/overlay.d", 0);
|
||||
restore_folder("/data/overlay.d", overlays);
|
||||
int cfg = xopen("/data/.backup/.magisk", O_WRONLY | O_CREAT, 0);
|
||||
xwrite(cfg, magisk_cfg.buf, magisk_cfg.sz);
|
||||
close(cfg);
|
||||
}
|
||||
|
||||
bool SecondStageInit::prepare() {
|
||||
backup_files();
|
||||
|
||||
umount2("/init", MNT_DETACH);
|
||||
umount2("/proc/self/exe", MNT_DETACH);
|
||||
umount2("/data", MNT_DETACH);
|
||||
|
||||
// Make sure init dmesg logs won't get messed up
|
||||
argv[0] = (char *) INIT_PATH;
|
||||
|
Loading…
Reference in New Issue
Block a user