ksud: allow to set upperdir and workdir for overlayfs
This commit is contained in:
@@ -25,6 +25,8 @@ pub const MODULE_UPDATE_TMP_IMG: &str = concatcp!(WORKING_DIR, "update_tmp.img")
|
|||||||
// warning: this directory should not change, or you need to change the code in module_installer.sh!!!
|
// warning: this directory should not change, or you need to change the code in module_installer.sh!!!
|
||||||
pub const MODULE_UPDATE_TMP_DIR: &str = concatcp!(ADB_DIR, "modules_update/");
|
pub const MODULE_UPDATE_TMP_DIR: &str = concatcp!(ADB_DIR, "modules_update/");
|
||||||
|
|
||||||
|
pub const SYSTEM_RW_DIR: &str = concatcp!(MODULE_DIR, ".rw/");
|
||||||
|
|
||||||
pub const TEMP_DIR: &str = "/debug_ramdisk";
|
pub const TEMP_DIR: &str = "/debug_ramdisk";
|
||||||
pub const TEMP_DIR_LEGACY: &str = "/sbin";
|
pub const TEMP_DIR_LEGACY: &str = "/sbin";
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ use crate::{
|
|||||||
utils::{self, ensure_clean_dir, ensure_dir_exists},
|
utils::{self, ensure_clean_dir, ensure_dir_exists},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn mount_partition(partition: &str, lowerdir: &Vec<String>) -> Result<()> {
|
fn mount_partition(partition_name: &str, lowerdir: &Vec<String>) -> Result<()> {
|
||||||
if lowerdir.is_empty() {
|
if lowerdir.is_empty() {
|
||||||
warn!("partition: {partition} lowerdir is empty");
|
warn!("partition: {partition_name} lowerdir is empty");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let partition = format!("/{partition}");
|
let partition = format!("/{partition_name}");
|
||||||
|
|
||||||
// if /partition is a symlink and linked to /system/partition, then we don't need to overlay it separately
|
// if /partition is a symlink and linked to /system/partition, then we don't need to overlay it separately
|
||||||
if Path::new(&partition).read_link().is_ok() {
|
if Path::new(&partition).read_link().is_ok() {
|
||||||
@@ -24,7 +24,15 @@ fn mount_partition(partition: &str, lowerdir: &Vec<String>) -> Result<()> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
mount::mount_overlay(&partition, lowerdir)
|
let mut workdir = None;
|
||||||
|
let mut upperdir = None;
|
||||||
|
let system_rw_dir = Path::new(defs::SYSTEM_RW_DIR);
|
||||||
|
if system_rw_dir.exists() {
|
||||||
|
workdir = Some(system_rw_dir.join(partition_name).join("workdir"));
|
||||||
|
upperdir = Some(system_rw_dir.join(partition_name).join("upperdir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
mount::mount_overlay(&partition, lowerdir, workdir, upperdir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mount_systemlessly(module_dir: &str) -> Result<()> {
|
pub fn mount_systemlessly(module_dir: &str) -> Result<()> {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use log::{info, warn};
|
|||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
use procfs::process::Process;
|
use procfs::process::Process;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub struct AutoMountExt4 {
|
pub struct AutoMountExt4 {
|
||||||
target: String,
|
target: String,
|
||||||
@@ -81,7 +82,13 @@ pub fn umount_dir(src: impl AsRef<Path>) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub fn mount_overlayfs(lower_dirs: &[String], lowest: &str, dest: impl AsRef<Path>) -> Result<()> {
|
pub fn mount_overlayfs(
|
||||||
|
lower_dirs: &[String],
|
||||||
|
lowest: &str,
|
||||||
|
upperdir: Option<PathBuf>,
|
||||||
|
workdir: Option<PathBuf>,
|
||||||
|
dest: impl AsRef<Path>,
|
||||||
|
) -> Result<()> {
|
||||||
let lowerdir_config = lower_dirs
|
let lowerdir_config = lower_dirs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| s.as_ref())
|
.map(|s| s.as_ref())
|
||||||
@@ -89,13 +96,21 @@ pub fn mount_overlayfs(lower_dirs: &[String], lowest: &str, dest: impl AsRef<Pat
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(":");
|
.join(":");
|
||||||
info!(
|
info!(
|
||||||
"mount overlayfs on {}, options={}",
|
"mount overlayfs on {:?}, lowerdir={}, upperdir={:?}, workdir={:?}",
|
||||||
dest.as_ref().display(),
|
dest.as_ref(),
|
||||||
lowerdir_config
|
lowerdir_config,
|
||||||
|
upperdir,
|
||||||
|
workdir
|
||||||
);
|
);
|
||||||
let fs = fsopen("overlay", FsOpenFlags::FSOPEN_CLOEXEC)?;
|
let fs = fsopen("overlay", FsOpenFlags::FSOPEN_CLOEXEC)?;
|
||||||
let fs = fs.as_fd();
|
let fs = fs.as_fd();
|
||||||
fsconfig_set_string(fs, "lowerdir", lowerdir_config)?;
|
fsconfig_set_string(fs, "lowerdir", lowerdir_config)?;
|
||||||
|
if let (Some(upperdir), Some(workdir)) = (upperdir, workdir) {
|
||||||
|
if upperdir.exists() && workdir.exists() {
|
||||||
|
fsconfig_set_string(fs, "upperdir", upperdir.display().to_string())?;
|
||||||
|
fsconfig_set_string(fs, "workdir", workdir.display().to_string())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
fsconfig_set_string(fs, "source", KSU_OVERLAY_SOURCE)?;
|
fsconfig_set_string(fs, "source", KSU_OVERLAY_SOURCE)?;
|
||||||
fsconfig_create(fs)?;
|
fsconfig_create(fs)?;
|
||||||
let mount = fsmount(fs, FsMountFlags::FSMOUNT_CLOEXEC, MountAttrFlags::empty())?;
|
let mount = fsmount(fs, FsMountFlags::FSMOUNT_CLOEXEC, MountAttrFlags::empty())?;
|
||||||
@@ -180,7 +195,7 @@ fn mount_overlay_child(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
// merge modules and stock
|
// merge modules and stock
|
||||||
if let Err(e) = mount_overlayfs(&lower_dirs, stock_root, mount_point) {
|
if let Err(e) = mount_overlayfs(&lower_dirs, stock_root, None, None, mount_point) {
|
||||||
warn!("failed: {:#}, fallback to bind mount", e);
|
warn!("failed: {:#}, fallback to bind mount", e);
|
||||||
bind_mount(stock_root, mount_point)?;
|
bind_mount(stock_root, mount_point)?;
|
||||||
}
|
}
|
||||||
@@ -188,7 +203,12 @@ fn mount_overlay_child(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
pub fn mount_overlay(root: &String, module_roots: &Vec<String>) -> Result<()> {
|
pub fn mount_overlay(
|
||||||
|
root: &String,
|
||||||
|
module_roots: &Vec<String>,
|
||||||
|
workdir: Option<PathBuf>,
|
||||||
|
upperdir: Option<PathBuf>,
|
||||||
|
) -> Result<()> {
|
||||||
info!("mount overlay for {}", root);
|
info!("mount overlay for {}", root);
|
||||||
std::env::set_current_dir(root).with_context(|| format!("failed to chdir to {root}"))?;
|
std::env::set_current_dir(root).with_context(|| format!("failed to chdir to {root}"))?;
|
||||||
let stock_root = ".";
|
let stock_root = ".";
|
||||||
@@ -208,7 +228,8 @@ pub fn mount_overlay(root: &String, module_roots: &Vec<String>) -> Result<()> {
|
|||||||
mount_seq.sort();
|
mount_seq.sort();
|
||||||
mount_seq.dedup();
|
mount_seq.dedup();
|
||||||
|
|
||||||
mount_overlayfs(module_roots, root, root).with_context(|| "mount overlayfs for root failed")?;
|
mount_overlayfs(module_roots, root, upperdir, workdir, root)
|
||||||
|
.with_context(|| "mount overlayfs for root failed")?;
|
||||||
for mount_point in mount_seq.iter() {
|
for mount_point in mount_seq.iter() {
|
||||||
let Some(mount_point) = mount_point else {
|
let Some(mount_point) = mount_point else {
|
||||||
continue;
|
continue;
|
||||||
@@ -241,7 +262,12 @@ pub fn umount_dir(_src: &str) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||||
pub fn mount_overlay(_dest: &String, _lower_dirs: &Vec<String>) -> Result<()> {
|
pub fn mount_overlay(
|
||||||
|
_root: &String,
|
||||||
|
_module_roots: &Vec<String>,
|
||||||
|
_workdir: Option<PathBuf>,
|
||||||
|
_upperdir: Option<PathBuf>,
|
||||||
|
) -> Result<()> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user