mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-20 11:18:29 +00:00
Use symlink to setup preinit
This commit is contained in:
parent
2754b1dcf8
commit
0869a90fe3
@ -49,16 +49,13 @@ pub fn setup_mounts() {
|
|||||||
let preinit_dir = Utf8CStr::from_string(&mut preinit_dir);
|
let preinit_dir = Utf8CStr::from_string(&mut preinit_dir);
|
||||||
let r: LoggedResult<()> = try {
|
let r: LoggedResult<()> = try {
|
||||||
FsPath::from(preinit_dir).mkdir(0o700)?;
|
FsPath::from(preinit_dir).mkdir(0o700)?;
|
||||||
mnt_path.mkdirs(0o755)?;
|
let mut buf = Utf8CStrBufArr::default();
|
||||||
|
if mnt_path.parent(&mut buf) {
|
||||||
|
FsPath::from(&buf).mkdirs(0o755)?;
|
||||||
|
}
|
||||||
|
mnt_path.remove().ok();
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::mount(
|
libc::symlink(preinit_dir.as_ptr(), mnt_path.as_ptr()).as_os_err()?
|
||||||
preinit_dir.as_ptr(),
|
|
||||||
mnt_path.as_ptr(),
|
|
||||||
ptr::null(),
|
|
||||||
libc::MS_BIND,
|
|
||||||
ptr::null(),
|
|
||||||
)
|
|
||||||
.as_os_err()?
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if r.is_ok() {
|
if r.is_ok() {
|
||||||
@ -134,14 +131,12 @@ pub fn setup_mounts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// when partitions have the same fs type, the order is:
|
// when partitions have the same fs type, the order is:
|
||||||
// - preinit: it's selected previously, so it's always the first
|
|
||||||
// - data: it has sufficient space and can be safely written
|
// - data: it has sufficient space and can be safely written
|
||||||
// - cache: size is limited, but still can be safely written
|
// - cache: size is limited, but still can be safely written
|
||||||
// - metadata: size is limited, and it might cause unexpected behavior if written
|
// - metadata: size is limited, and it might cause unexpected behavior if written
|
||||||
// - persist: it's the last resort, as it's dangerous to write to it
|
// - persist: it's the last resort, as it's dangerous to write to it
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||||
enum PartId {
|
enum PartId {
|
||||||
PreInit,
|
|
||||||
Data,
|
Data,
|
||||||
Cache,
|
Cache,
|
||||||
Metadata,
|
Metadata,
|
||||||
@ -165,16 +160,10 @@ pub fn find_preinit_device() -> String {
|
|||||||
} else {
|
} else {
|
||||||
EncryptType::File
|
EncryptType::File
|
||||||
};
|
};
|
||||||
let mount = unsafe { libc::getuid() } == 0 && std::env::var("MAGISKTMP").is_ok();
|
|
||||||
let make_dev = mount && std::env::var_os("MAKEDEV").is_some();
|
|
||||||
|
|
||||||
let mut matched_info = parse_mount_info("self")
|
let mut matched_info = parse_mount_info("self")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|info| {
|
.filter_map(|info| {
|
||||||
// if preinit is already mounted, choose it unconditionally
|
|
||||||
if info.target.ends_with(PREINITMIRR) {
|
|
||||||
return Some((PartId::PreInit, info));
|
|
||||||
}
|
|
||||||
if info.root != "/" || !info.source.starts_with('/') || info.source.contains("/dm-") {
|
if info.root != "/" || !info.source.starts_with('/') || info.source.contains("/dm-") {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -222,47 +211,45 @@ pub fn find_preinit_device() -> String {
|
|||||||
_ => ap.cmp(bp),
|
_ => ap.cmp(bp),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let preinit_source = match preinit_info {
|
let info = &preinit_info.1;
|
||||||
(PartId::PreInit, info) => &info.source,
|
let mut target = info.target.clone();
|
||||||
(_, info) => {
|
let mut preinit_dir = resolve_preinit_dir(Utf8CStr::from_string(&mut target));
|
||||||
let mut target = info.target.clone();
|
if unsafe { libc::getuid() } == 0
|
||||||
let mut preinit_dir = resolve_preinit_dir(Utf8CStr::from_string(&mut target));
|
&& let Ok(tmp) = std::env::var("MAGISKTMP")
|
||||||
if mount && let Ok(tmp) = std::env::var("MAGISKTMP") {
|
&& !tmp.is_empty()
|
||||||
let mut buf = Utf8CStrBufArr::default();
|
{
|
||||||
let mirror_dir = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITMIRR);
|
let mut buf = Utf8CStrBufArr::default();
|
||||||
let preinit_dir = FsPath::from(Utf8CStr::from_string(&mut preinit_dir));
|
let mirror_dir = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITMIRR);
|
||||||
let _: LoggedResult<()> = try {
|
let preinit_dir = FsPath::from(Utf8CStr::from_string(&mut preinit_dir));
|
||||||
preinit_dir.mkdirs(0o700)?;
|
let _: LoggedResult<()> = try {
|
||||||
mirror_dir.mkdirs(0o700)?;
|
preinit_dir.mkdirs(0o700)?;
|
||||||
unsafe {
|
let mut buf = Utf8CStrBufArr::default();
|
||||||
libc::mount(
|
if mirror_dir.parent(&mut buf) {
|
||||||
preinit_dir.as_ptr(),
|
FsPath::from(&buf).mkdirs(0o755)?;
|
||||||
mirror_dir.as_ptr(),
|
}
|
||||||
ptr::null(),
|
mirror_dir.remove().ok();
|
||||||
libc::MS_BIND,
|
unsafe {
|
||||||
ptr::null(),
|
libc::umount2(mirror_dir.as_ptr(), libc::MNT_DETACH)
|
||||||
)
|
.as_os_err()
|
||||||
.as_os_err()?;
|
.ok(); // ignore error
|
||||||
}
|
libc::symlink(preinit_dir.as_ptr(), mirror_dir.as_ptr()).as_os_err()?;
|
||||||
};
|
}
|
||||||
if make_dev {
|
};
|
||||||
let dev_path = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITDEV);
|
if std::env::var_os("MAKEDEV").is_some() {
|
||||||
unsafe {
|
let dev_path = FsPathBuf::new(&mut buf).join(&tmp).join(PREINITDEV);
|
||||||
libc::mknod(
|
unsafe {
|
||||||
dev_path.as_ptr(),
|
libc::mknod(
|
||||||
libc::S_IFBLK | 0o600,
|
dev_path.as_ptr(),
|
||||||
info.device as dev_t,
|
libc::S_IFBLK | 0o600,
|
||||||
)
|
info.device as dev_t,
|
||||||
.as_os_err()
|
)
|
||||||
.log()
|
.as_os_err()
|
||||||
.ok();
|
.log()
|
||||||
}
|
.ok();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&info.source
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
Path::new(&preinit_source)
|
Path::new(&info.source)
|
||||||
.file_name()
|
.file_name()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_str()
|
.to_str()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user