You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
ksud: restore stock mount after overlay mount. close #233
This commit is contained in:
19
userspace/ksud/Cargo.lock
generated
19
userspace/ksud/Cargo.lock
generated
@@ -800,6 +800,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"nom",
|
"nom",
|
||||||
|
"proc-mounts",
|
||||||
"procfs",
|
"procfs",
|
||||||
"regex",
|
"regex",
|
||||||
"retry",
|
"retry",
|
||||||
@@ -986,6 +987,15 @@ version = "6.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "partition-identity"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9fa925f9becb532d758b0014b472c576869910929cf4c3f8054b386f19ab9e21"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "password-hash"
|
name = "password-hash"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@@ -1072,6 +1082,15 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-mounts"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d652f8435d0ab70bf4f3590a6a851d59604831a458086541b95238cc51ffcf2"
|
||||||
|
dependencies = [
|
||||||
|
"partition-identity",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "procfs"
|
name = "procfs"
|
||||||
version = "0.15.1"
|
version = "0.15.1"
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ rust-embed = { version = "6.4.2", features = [
|
|||||||
"debug-embed",
|
"debug-embed",
|
||||||
"compression", # must clean build after updating binaries
|
"compression", # must clean build after updating binaries
|
||||||
] }
|
] }
|
||||||
|
proc-mounts = "0.3"
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies]
|
[target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies]
|
||||||
sys-mount = { git = "https://github.com/tiann/sys-mount" }
|
sys-mount = { git = "https://github.com/tiann/sys-mount" }
|
||||||
|
|||||||
@@ -18,6 +18,19 @@ fn mount_partition(partition: &str, lowerdir: &mut Vec<String>) -> Result<()> {
|
|||||||
warn!("partition: {partition} is a symlink");
|
warn!("partition: {partition} is a symlink");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle stock mounts under /partition, we should restore the mount point after overlay
|
||||||
|
let stock_mount = mount::StockMount::new(&format!("/{partition}/"))
|
||||||
|
.with_context(|| format!("get stock mount of partition: {partition} failed"))?;
|
||||||
|
let result = stock_mount.umount();
|
||||||
|
if result.is_err() {
|
||||||
|
let remount_result = stock_mount.remount();
|
||||||
|
if remount_result.is_err() {
|
||||||
|
log::error!("remount stock mount of failed: {:?}", remount_result);
|
||||||
|
}
|
||||||
|
bail!("umount stock mount of failed: {:?}", result);
|
||||||
|
}
|
||||||
|
|
||||||
// add /partition as the lowerest dir
|
// add /partition as the lowerest dir
|
||||||
let lowest_dir = format!("/{partition}");
|
let lowest_dir = format!("/{partition}");
|
||||||
lowerdir.push(lowest_dir.clone());
|
lowerdir.push(lowest_dir.clone());
|
||||||
@@ -25,7 +38,18 @@ fn mount_partition(partition: &str, lowerdir: &mut Vec<String>) -> Result<()> {
|
|||||||
let lowerdir = lowerdir.join(":");
|
let lowerdir = lowerdir.join(":");
|
||||||
info!("partition: {partition} lowerdir: {lowerdir}");
|
info!("partition: {partition} lowerdir: {lowerdir}");
|
||||||
|
|
||||||
mount::mount_overlay(&lowerdir, &lowest_dir)
|
let result = mount::mount_overlay(&lowerdir, &lowest_dir);
|
||||||
|
|
||||||
|
if result.is_ok() && stock_mount.remount().is_err() {
|
||||||
|
// if mount overlay ok but stock remount failed, we should umount overlay
|
||||||
|
warn!("remount stock mount of failed, umount overlay {lowest_dir} now");
|
||||||
|
if mount::umount_dir(&lowest_dir).is_err() {
|
||||||
|
warn!("umount overlay {lowest_dir} failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mount_systemlessly(module_dir: &str) -> Result<()> {
|
pub fn mount_systemlessly(module_dir: &str) -> Result<()> {
|
||||||
|
|||||||
@@ -252,3 +252,73 @@ impl StockOverlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// some ROMs mount device(ext4,exfat) to /vendor, when we do overlay mount, it will overlay
|
||||||
|
// the stock mounts, these mounts include bt_firmware, wifi_firmware, etc.
|
||||||
|
// so we to remount these mounts when we do overlay mount.
|
||||||
|
// this is a workaround, we should find a better way to do this.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StockMount {
|
||||||
|
mnt: String,
|
||||||
|
mountlist: proc_mounts::MountList,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StockMount {
|
||||||
|
pub fn new(mnt: &str) -> Result<Self> {
|
||||||
|
let mountlist = proc_mounts::MountList::new()?;
|
||||||
|
Ok(Self {
|
||||||
|
mnt: mnt.to_string(),
|
||||||
|
mountlist,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_target_mounts(&self) -> Vec<&proc_mounts::MountInfo> {
|
||||||
|
let mounts = self
|
||||||
|
.mountlist
|
||||||
|
.destination_starts_with(&std::path::Path::new(&self.mnt))
|
||||||
|
.filter(|m| m.fstype != "overlay");
|
||||||
|
mounts.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn umount(&self) -> Result<()> {
|
||||||
|
let mounts = self.get_target_mounts();
|
||||||
|
log::info!("stock mount for {} : {:?}", self.mnt, mounts);
|
||||||
|
for m in mounts {
|
||||||
|
let dst = m
|
||||||
|
.dest
|
||||||
|
.to_str()
|
||||||
|
.ok_or(anyhow::anyhow!("Failed to get dst"))?;
|
||||||
|
umount_dir(dst)?;
|
||||||
|
log::info!("umount: {:?}", m);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remount(&self) -> Result<()> {
|
||||||
|
let mounts = self.get_target_mounts();
|
||||||
|
for m in mounts {
|
||||||
|
let src = std::fs::canonicalize(&m.source)?;
|
||||||
|
|
||||||
|
let src = src.to_str().ok_or(anyhow::anyhow!("Failed to get src"))?;
|
||||||
|
let dst = m
|
||||||
|
.dest
|
||||||
|
.to_str()
|
||||||
|
.ok_or(anyhow::anyhow!("Failed to get dst"))?;
|
||||||
|
|
||||||
|
let fstype = m.fstype.as_str();
|
||||||
|
let options = m.options.join(",");
|
||||||
|
|
||||||
|
log::info!("mount: {:?}", m);
|
||||||
|
std::process::Command::new("mount")
|
||||||
|
.arg("-t")
|
||||||
|
.arg(fstype)
|
||||||
|
.arg("-o")
|
||||||
|
.arg(options)
|
||||||
|
.arg(src)
|
||||||
|
.arg(dst)
|
||||||
|
.status()
|
||||||
|
.with_context(|| format!("Failed to mount {:?}", m))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user