Previously, magic mount creates its own mirror devices and mount mirror mount points. With these mirror mount points, magic mount can get the original files and directory trees. However, some devices use overlayfs to modify some mount points, and thus after magic mount, the overlayed files are missing because the mirror mount points do not contain the overlayed files. To address this issue and make magic mount more compatible, this patch refactors how magic mount works. The new workflows are as follows: 1. make MAGISKTMP a private mount point so that we can create the private mount points there 2. for mirror mount points, we instead of creating our own mirror devices and mount the mirror mount points, we "copy" the original mount points by recursively mounting / 3. to prevent magic mount affecting the mirror mount points, we recursively set the mirror mount points private 4. to trace the mount points we created for reverting mounts, we again make the mirror mount points shared, and by this way we create a new peer group for each mirror mount points 5. as for tracing the newly created tmpfs mount point by magic mount, we create a dedicated tmpfs mount point for them, namely worker mount point, and obviously, it is shared as in a newly created peer group for tracing 6. when reverting mount points by magic mount, we can then trace the peer group id and unmount the mount points whose peer group ids are created by us The advantages are as follows: 1. it is more compatible, (e.g., with overlayfs, fix #2359) 2. it can mount more partitions for which previous implementation cannot create mirror mount points (fix #3338)
Native Development
Prerequisite
Install the NDK required to build and develop Magisk with ./build.py ndk
. The NDK will be installed to $ANDROID_SDK_ROOT/ndk/magisk
. You don't need to manually install a Rust toolchain with rustup
, as the NDK installed already has a Rust toolchain bundled.
Build Configs
All C/C++ code and its dependencies are built with ndk-build
and configured with several *.mk
files scattered in many places.
The src
folder is also a proper Cargo workspace, and all Rust code is built with cargo
just like normal Rust projects.
Rust + C/C++
To reduce complexity involved in linking, all Rust code is built as staticlib
and linked to C++ targets to ensure our final product is built with an officially supported NDK build system. Each C++ target can at most link to one Rust staticlib
or else multiple definitions error will occur.
We use the cxx
project for Rust and C++ interop.
Development / IDE
All C++ code should be recognized and properly indexed by Android Studio out of the box. For Rust:
- Install the Rust plugin in Android Studio
- In Preferences > Languages & Frameworks > Rust, set
$ANDROID_SDK_ROOT/ndk/magisk/toolchains/rust/bin
as the toolchain location - Open
native/src/Cargo.toml
, and select "Attach" in the "No Cargo projects found" banner
Note: run ./build.py binary
before developing to make sure generated code is created.