Use new mount api
This commit is contained in:
57
userspace/ksud/Cargo.lock
generated
57
userspace/ksud/Cargo.lock
generated
@@ -853,6 +853,7 @@ dependencies = [
|
|||||||
"jwalk",
|
"jwalk",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
"loopdev",
|
||||||
"nom",
|
"nom",
|
||||||
"procfs",
|
"procfs",
|
||||||
"regex",
|
"regex",
|
||||||
@@ -862,7 +863,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha256",
|
"sha256",
|
||||||
"sys-mount",
|
|
||||||
"tempdir",
|
"tempdir",
|
||||||
"which",
|
"which",
|
||||||
"zip 0.6.4",
|
"zip 0.6.4",
|
||||||
@@ -1463,17 +1463,6 @@ version = "1.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smart-default"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.107",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
@@ -1508,19 +1497,6 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sys-mount"
|
|
||||||
version = "2.0.2"
|
|
||||||
source = "git+https://github.com/tiann/sys-mount?branch=loopfix#c7c4048e4a4ffdf8b108a85956363a75f2c554f0"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 1.3.2",
|
|
||||||
"libc",
|
|
||||||
"loopdev",
|
|
||||||
"smart-default",
|
|
||||||
"thiserror",
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempdir"
|
name = "tempdir"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@@ -1599,37 +1575,6 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing"
|
|
||||||
version = "0.1.40"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
|
||||||
dependencies = [
|
|
||||||
"pin-project-lite",
|
|
||||||
"tracing-attributes",
|
|
||||||
"tracing-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-attributes"
|
|
||||||
version = "0.1.27"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.48",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tracing-core"
|
|
||||||
version = "0.1.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
|
||||||
dependencies = [
|
|
||||||
"once_cell",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ chrono = "0.4"
|
|||||||
hole-punch = { git = "https://github.com/tiann/hole-punch" }
|
hole-punch = { git = "https://github.com/tiann/hole-punch" }
|
||||||
|
|
||||||
[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", branch = "loopfix" }
|
|
||||||
rustix = { version = "0.38", features = ["all-apis"] }
|
rustix = { version = "0.38", features = ["all-apis"] }
|
||||||
# some android specific dependencies which compiles under unix are also listed here for convenience of coding
|
# some android specific dependencies which compiles under unix are also listed here for convenience of coding
|
||||||
android-properties = { version = "0.2.2", features = ["bionic-deprecated"] }
|
android-properties = { version = "0.2.2", features = ["bionic-deprecated"] }
|
||||||
procfs = "0.16"
|
procfs = "0.16"
|
||||||
|
loopdev = { git = "https://github.com/tiann/loopdev", branch = "loopfix" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
android_logger = "0.13"
|
android_logger = "0.13"
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use std::path::PathBuf;
|
||||||
use std::{collections::HashMap, path::Path};
|
use std::{collections::HashMap, path::Path};
|
||||||
|
|
||||||
use crate::module::prune_modules;
|
use crate::module::prune_modules;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use anyhow::{bail, Ok, Result};
|
use anyhow::{anyhow, bail, Ok, Result};
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
use retry::delay::NoDelay;
|
use retry::delay::NoDelay;
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
use sys_mount::{unmount, FilesystemType, Mount, MountFlags, Unmount, UnmountFlags};
|
use rustix::{fd::AsFd, fs::CWD, mount::*};
|
||||||
|
|
||||||
use crate::defs::KSU_OVERLAY_SOURCE;
|
use crate::defs::KSU_OVERLAY_SOURCE;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
@@ -14,49 +14,32 @@ use procfs::process::Process;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub struct AutoMountExt4 {
|
pub struct AutoMountExt4 {
|
||||||
mnt: String,
|
target: String,
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
|
||||||
mount: Option<Mount>,
|
|
||||||
auto_umount: bool,
|
auto_umount: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AutoMountExt4 {
|
impl AutoMountExt4 {
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub fn try_new(src: &str, mnt: &str, auto_umount: bool) -> Result<Self> {
|
pub fn try_new(source: &str, target: &str, auto_umount: bool) -> Result<Self> {
|
||||||
let result = Mount::builder()
|
let new_loopback = loopdev::LoopControl::open()?.next_free()?;
|
||||||
.fstype(FilesystemType::from("ext4"))
|
new_loopback.with().attach(source)?;
|
||||||
.flags(MountFlags::empty())
|
let lo = new_loopback.path().ok_or(anyhow!("no loop"))?;
|
||||||
.create_loop(true)
|
let fs = fsopen("ext4", FsOpenFlags::FSOPEN_CLOEXEC)?;
|
||||||
.mount(src, mnt)
|
let fs = fs.as_fd();
|
||||||
.map(|mount| {
|
fsconfig_set_string(fs, "source", lo)?;
|
||||||
|
fsconfig_create(fs)?;
|
||||||
|
let mount = fsmount(fs, FsMountFlags::FSMOUNT_CLOEXEC, MountAttrFlags::empty())?;
|
||||||
|
move_mount(
|
||||||
|
mount.as_fd(),
|
||||||
|
"",
|
||||||
|
CWD,
|
||||||
|
target,
|
||||||
|
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
|
||||||
|
)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
mnt: mnt.to_string(),
|
target: target.to_string(),
|
||||||
mount: Some(mount),
|
|
||||||
auto_umount,
|
auto_umount,
|
||||||
})
|
})
|
||||||
});
|
|
||||||
if let Err(e) = result {
|
|
||||||
println!("- Mount failed: {e}, retry with system mount");
|
|
||||||
let result = std::process::Command::new("mount")
|
|
||||||
.arg("-t")
|
|
||||||
.arg("ext4")
|
|
||||||
.arg(src)
|
|
||||||
.arg(mnt)
|
|
||||||
.status();
|
|
||||||
if let Err(e) = result {
|
|
||||||
Err(anyhow::anyhow!(
|
|
||||||
"mount partition: {src} -> {mnt} failed: {e}"
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Ok(Self {
|
|
||||||
mnt: mnt.to_string(),
|
|
||||||
mount: None,
|
|
||||||
auto_umount,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.unwrap()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||||
@@ -66,27 +49,17 @@ impl AutoMountExt4 {
|
|||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub fn umount(&self) -> Result<()> {
|
pub fn umount(&self) -> Result<()> {
|
||||||
if let Some(ref mount) = self.mount {
|
unmount(self.target.as_str(), UnmountFlags::DETACH)?;
|
||||||
mount
|
|
||||||
.unmount(UnmountFlags::empty())
|
|
||||||
.map_err(|e| anyhow::anyhow!(e))
|
|
||||||
} else {
|
|
||||||
let result = std::process::Command::new("umount").arg(&self.mnt).status();
|
|
||||||
if let Err(e) = result {
|
|
||||||
Err(anyhow::anyhow!("umount: {} failed: {e}", self.mnt))
|
|
||||||
} else {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
impl Drop for AutoMountExt4 {
|
impl Drop for AutoMountExt4 {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
log::info!(
|
log::info!(
|
||||||
"AutoMountExt4 drop: {}, auto_umount: {}",
|
"AutoMountExt4 drop: {}, auto_umount: {}",
|
||||||
self.mnt,
|
self.target,
|
||||||
self.auto_umount
|
self.auto_umount
|
||||||
);
|
);
|
||||||
if self.auto_umount {
|
if self.auto_umount {
|
||||||
@@ -98,18 +71,7 @@ impl Drop for AutoMountExt4 {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
fn mount_image(src: &str, target: &str, autodrop: bool) -> Result<()> {
|
fn mount_image(src: &str, target: &str, autodrop: bool) -> Result<()> {
|
||||||
if autodrop {
|
AutoMountExt4::try_new(src, target, autodrop)?;
|
||||||
Mount::builder()
|
|
||||||
.fstype(FilesystemType::from("ext4"))
|
|
||||||
.create_loop(true)
|
|
||||||
.mount_autodrop(src, target, UnmountFlags::empty())
|
|
||||||
.with_context(|| format!("Failed to do mount: {src} -> {target}"))?;
|
|
||||||
} else {
|
|
||||||
Mount::builder()
|
|
||||||
.fstype(FilesystemType::from("ext4"))
|
|
||||||
.mount(src, target)
|
|
||||||
.with_context(|| format!("Failed to do mount: {src} -> {target}"))?;
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,28 +108,37 @@ fn mount_overlayfs(
|
|||||||
dest.as_ref().display(),
|
dest.as_ref().display(),
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
Mount::builder()
|
let fs = fsopen("overlay", FsOpenFlags::FSOPEN_CLOEXEC)?;
|
||||||
.fstype(FilesystemType::from("overlay"))
|
let fs = fs.as_fd();
|
||||||
.data(&options)
|
fsconfig_set_string(fs, "lowerdir", lower_dirs.join(":"))?;
|
||||||
.flags(MountFlags::RDONLY)
|
fsconfig_set_string(fs, "source", KSU_OVERLAY_SOURCE)?;
|
||||||
.mount(KSU_OVERLAY_SOURCE, dest.as_ref())
|
fsconfig_create(fs)?;
|
||||||
.with_context(|| {
|
let mount = fsmount(fs, FsMountFlags::FSMOUNT_CLOEXEC, MountAttrFlags::empty())?;
|
||||||
format!(
|
move_mount(
|
||||||
"mount overlayfs on {} options {} failed",
|
mount.as_fd(),
|
||||||
dest.as_ref().display(),
|
"",
|
||||||
options
|
CWD,
|
||||||
)
|
dest.as_ref(),
|
||||||
})?;
|
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub fn mount_tmpfs(dest: impl AsRef<Path>) -> Result<()> {
|
pub fn mount_tmpfs(dest: impl AsRef<Path>) -> Result<()> {
|
||||||
info!("mount tmpfs on {}", dest.as_ref().display());
|
info!("mount tmpfs on {}", dest.as_ref().display());
|
||||||
Mount::builder()
|
let fs = fsopen("tmpfs", FsOpenFlags::FSOPEN_CLOEXEC)?;
|
||||||
.fstype(FilesystemType::from("tmpfs"))
|
let fs = fs.as_fd();
|
||||||
.mount(KSU_OVERLAY_SOURCE, dest.as_ref())
|
fsconfig_set_string(fs, "source", KSU_OVERLAY_SOURCE)?;
|
||||||
.with_context(|| format!("mount tmpfs on {} failed", dest.as_ref().display()))?;
|
fsconfig_create(fs)?;
|
||||||
|
let mount = fsmount(fs, FsMountFlags::FSMOUNT_CLOEXEC, MountAttrFlags::empty())?;
|
||||||
|
move_mount(
|
||||||
|
mount.as_fd(),
|
||||||
|
"",
|
||||||
|
CWD,
|
||||||
|
dest.as_ref(),
|
||||||
|
MoveMountFlags::MOVE_MOUNT_F_EMPTY_PATH,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,16 +149,12 @@ fn bind_mount(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<()> {
|
|||||||
from.as_ref().display(),
|
from.as_ref().display(),
|
||||||
to.as_ref().display()
|
to.as_ref().display()
|
||||||
);
|
);
|
||||||
Mount::builder()
|
let tree = open_tree(
|
||||||
.flags(MountFlags::BIND)
|
CWD,
|
||||||
.mount(from.as_ref(), to.as_ref())
|
from.as_ref(),
|
||||||
.with_context(|| {
|
OpenTreeFlags::OPEN_TREE_CLOEXEC | OpenTreeFlags::OPEN_TREE_CLONE,
|
||||||
format!(
|
)?;
|
||||||
"bind mount failed: {} -> {}",
|
move_mount(tree.as_fd(), "", CWD, to.as_ref(), MoveMountFlags::empty())?;
|
||||||
from.as_ref().display(),
|
|
||||||
to.as_ref().display()
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user