ksud: auto resize image based on module size

This commit is contained in:
tiann
2023-01-24 15:00:31 +08:00
parent 780a42d823
commit b4bc2e66e6
4 changed files with 35 additions and 15 deletions

View File

@@ -371,6 +371,15 @@ dependencies = [
"digest",
]
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
dependencies = [
"libm",
]
[[package]]
name = "humantime"
version = "2.1.0"
@@ -434,6 +443,7 @@ dependencies = [
"const_format",
"encoding",
"env_logger",
"humansize",
"java-properties",
"log",
"regex",
@@ -457,6 +467,12 @@ version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libm"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb"
[[package]]
name = "linux-raw-sys"
version = "0.1.4"

View File

@@ -21,6 +21,7 @@ serde_json = "1.0"
regex = "1.5.4"
encoding = "0.2.33"
retry = "2.0.0"
humansize = "2.0.0"
[profile.release]
strip = true

View File

@@ -120,8 +120,8 @@ fn grow_image_size(img: &str, extra_size: u64) -> Result<()> {
// check image
check_image(img)?;
println!("- Target image size: {}", humansize::format_size(target_size, humansize::DECIMAL));
let target_size = target_size / 1024 + 1;
println!("- Target size: {}K", target_size);
let result = Exec::shell(format!("resize2fs {} {}K", img, target_size))
.stdout(subprocess::NullFile)
@@ -315,13 +315,6 @@ pub fn install_module(zip: String) -> Result<()> {
let modules_update_img = Path::new(defs::MODULE_UPDATE_IMG);
let module_update_tmp_dir = defs::MODULE_UPDATE_TMP_DIR;
let current_img_size = std::cmp::max(
modules_img.metadata().map_or(0, |meta| meta.len()),
modules_update_img.metadata().map_or(0, |meta| meta.len()),
);
let img_size_per_m = current_img_size / 1024 / 1024 + 256;
let modules_img_exist = modules_img.exists();
let modules_update_img_exist = modules_update_img.exists();
@@ -332,16 +325,20 @@ pub fn install_module(zip: String) -> Result<()> {
std::fs::remove_file(tmp_module_path)?;
}
let default_grow_size = 128 * 1024 * 1024;
let default_reserve_size = 64 * 1024 * 1024;
let zip_uncompressed_size = get_zip_uncompressed_size(&zip)?;
let grow_size = default_reserve_size + zip_uncompressed_size;
let grow_size_per_m = grow_size / 1024 / 1024 + 1;
println!("- Preparing image");
println!("- Module size: {}", humansize::format_size(zip_uncompressed_size, humansize::DECIMAL));
if !modules_img_exist && !modules_update_img_exist {
// if no modules and modules_update, it is brand new installation, we should create a new img
// create a tmp module img and mount it to modules_update
let result = Exec::shell(format!(
"dd if=/dev/zero of={} bs=1M count={}",
tmp_module_img, img_size_per_m
tmp_module_img, grow_size_per_m
))
.stdout(subprocess::NullFile)
.stderr(subprocess::Redirection::Merge)
@@ -366,7 +363,7 @@ pub fn install_module(zip: String) -> Result<()> {
)
})?;
// grow size of the tmp image
grow_image_size(tmp_module_img, default_grow_size)?;
grow_image_size(tmp_module_img, grow_size)?;
} else {
// modules.img exists, we should use it as tmp img
std::fs::copy(modules_img, tmp_module_img).with_context(|| {
@@ -377,7 +374,7 @@ pub fn install_module(zip: String) -> Result<()> {
)
})?;
// grow size of the tmp image
grow_image_size(tmp_module_img, default_grow_size)?;
grow_image_size(tmp_module_img, grow_size)?;
}
// ensure modules_update exists

View File

@@ -16,9 +16,7 @@ fn do_mount_image(src: &str, target: &str) -> Result<()> {
pub fn mount_image(src: &str, target: &str) -> Result<()> {
// umount target first.
let _ = umount_dir(target);
let result = retry::retry(NoDelay.take(3), || {
do_mount_image(src, target)
});
let result = retry::retry(NoDelay.take(3), || do_mount_image(src, target));
ensure!(result.is_ok(), "mount: {} -> {} failed.", src, target);
Ok(())
}
@@ -52,3 +50,11 @@ pub fn getprop(prop: &str) -> Result<String> {
pub fn is_safe_mode() -> Result<bool> {
Ok(getprop("persist.sys.safemode")?.eq("1") || getprop("ro.sys.safemode")?.eq("1"))
}
pub fn get_zip_uncompressed_size(zip_path: &str) -> Result<u64> {
let mut zip = zip::ZipArchive::new(std::fs::File::open(zip_path)?)?;
let total: u64 = (0..zip.len())
.map(|i| zip.by_index(i).unwrap().size())
.sum();
Ok(total)
}