From d7bc853bfc8ad44ba59927689efc12e131331d02 Mon Sep 17 00:00:00 2001 From: weishu Date: Mon, 29 Jan 2024 18:50:19 +0800 Subject: [PATCH] ksud: use sparse image to avoiding resize image. close #1220 --- userspace/ksud/Cargo.lock | 236 +++++++++++++++++++++++------------ userspace/ksud/Cargo.toml | 1 + userspace/ksud/src/module.rs | 95 +++++--------- userspace/ksud/src/utils.rs | 44 +++++++ 4 files changed, 229 insertions(+), 147 deletions(-) diff --git a/userspace/ksud/Cargo.lock b/userspace/ksud/Cargo.lock index 0d11992cfbbc..df1810100ee2 100644 --- a/userspace/ksud/Cargo.lock +++ b/userspace/ksud/Cargo.lock @@ -29,7 +29,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cipher", "cpufeatures", "opaque-debug", @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.68" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "async-trait" @@ -91,7 +91,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.48", ] [[package]] @@ -108,7 +108,7 @@ checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", - "cfg-if", + "cfg-if 1.0.0", "libc", "miniz_oxide", "object", @@ -218,6 +218,12 @@ dependencies = [ "nom", ] +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "cfg-if" version = "1.0.0" @@ -353,7 +359,7 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -362,7 +368,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -372,36 +378,30 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] @@ -410,18 +410,15 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -511,7 +508,7 @@ version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -540,12 +537,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -610,7 +607,7 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "libc", "wasi 0.11.0+wasi-snapshot-preview1", ] @@ -642,6 +639,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" + [[package]] name = "hex" version = "0.4.3" @@ -657,6 +660,19 @@ dependencies = [ "digest", ] +[[package]] +name = "hole-punch" +version = "0.0.4-alpha.0" +source = "git+https://github.com/tiann/hole-punch#11ab7a61bfb98682b72fd7f58a47d8e5d997328e" +dependencies = [ + "cfg-if 0.1.10", + "errno 0.2.8", + "libc", + "memmap", + "thiserror", + "winapi", +] + [[package]] name = "home" version = "0.5.5" @@ -755,7 +771,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "io-lifetimes", "rustix 0.36.7", "windows-sys 0.42.0", @@ -830,6 +846,7 @@ dependencies = [ "env_logger", "extattr", "getopts", + "hole-punch", "humansize", "is_executable", "java-properties", @@ -865,9 +882,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libflate" @@ -895,7 +912,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "winapi", ] @@ -922,18 +939,15 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "loopdev" @@ -947,17 +961,18 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] -name = "memoffset" -version = "0.7.1" +name = "memmap" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ - "autocfg", + "libc", + "winapi", ] [[package]] @@ -1006,11 +1021,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.4", "libc", ] @@ -1120,9 +1135,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1139,7 +1154,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.21", + "rustix 0.38.30", ] [[package]] @@ -1155,9 +1170,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1355,15 +1370,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ "bitflags 2.4.1", - "errno 0.3.5", + "errno 0.3.8", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", ] [[package]] @@ -1381,12 +1396,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "scratch" version = "1.0.3" @@ -1416,7 +1425,7 @@ version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -1427,7 +1436,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "cpufeatures", "digest", ] @@ -1487,9 +1496,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -1530,22 +1539,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 1.0.107", + "syn 2.0.48", ] [[package]] @@ -1593,7 +1602,7 @@ version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1651,12 +1660,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -1678,7 +1686,7 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "wasm-bindgen-macro", ] @@ -1735,7 +1743,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.21", + "rustix 0.38.30", "windows-sys 0.48.0", ] @@ -1803,6 +1811,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.1" @@ -1833,6 +1850,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.1" @@ -1845,6 +1877,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" @@ -1857,6 +1895,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.1" @@ -1869,6 +1913,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.1" @@ -1881,6 +1931,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" @@ -1893,6 +1949,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" @@ -1905,6 +1967,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" @@ -1917,6 +1985,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "zip" version = "0.5.13" diff --git a/userspace/ksud/Cargo.toml b/userspace/ksud/Cargo.toml index cd5961a8a654..2eaf2d065fe9 100644 --- a/userspace/ksud/Cargo.toml +++ b/userspace/ksud/Cargo.toml @@ -36,6 +36,7 @@ getopts = "0.2" sha256 = "1" tempdir = "0.3" chrono = "0.4" +hole-punch = { git = "https://github.com/tiann/hole-punch" } [target.'cfg(any(target_os = "android", target_os = "linux"))'.dependencies] sys-mount = { git = "https://github.com/tiann/sys-mount", branch = "loopfix" } diff --git a/userspace/ksud/src/module.rs b/userspace/ksud/src/module.rs index d978db891d32..3a500af53c91 100644 --- a/userspace/ksud/src/module.rs +++ b/userspace/ksud/src/module.rs @@ -3,7 +3,7 @@ use crate::utils::*; use crate::{ assets, defs, mount, restorecon::{restore_syscon, setsyscon}, - sepolicy, + sepolicy, utils, }; use anyhow::{anyhow, bail, ensure, Context, Result}; @@ -14,7 +14,7 @@ use log::{info, warn}; use std::{ collections::HashMap, env::var as env_var, - fs::{remove_dir_all, remove_file, set_permissions, File, Permissions}, + fs::{remove_dir_all, remove_file, set_permissions, File, OpenOptions, Permissions}, io::Cursor, path::{Path, PathBuf}, process::{Command, Stdio}, @@ -118,25 +118,6 @@ fn foreach_active_module(f: impl FnMut(&Path) -> Result<()>) -> Result<()> { foreach_module(true, f) } -fn get_minimal_image_size(img: &str) -> Result { - check_image(img)?; - - let output = Command::new("resize2fs") - .args(["-P", img]) - .stdout(Stdio::piped()) - .output()?; - - let output = String::from_utf8_lossy(&output.stdout); - println!("- {}", output.trim()); - let regex = regex::Regex::new(r"filesystem: (\d+)")?; - let result = regex - .captures(&output) - .ok_or(anyhow::anyhow!("regex not match"))?; - let result = &result[1]; - let result = u64::from_str(result)?; - Ok(result) -} - fn check_image(img: &str) -> Result<()> { let result = Command::new("e2fsck") .args(["-yf", img]) @@ -157,31 +138,6 @@ fn check_image(img: &str) -> Result<()> { Ok(()) } -fn grow_image_size(img: &str, extra_size: u64) -> Result<()> { - let minimal_size = get_minimal_image_size(img)?; // the minimal size is in KB - let target_size = minimal_size * 1024 + extra_size; - - // check image - check_image(img)?; - - println!( - "- Target image size: {}", - humansize::format_size(target_size, humansize::DECIMAL) - ); - let target_size = target_size / 1024 + 1024; - info!("resize image to {target_size}K, minimal size is {minimal_size}K"); - let result = Command::new("resize2fs") - .args([img, &format!("{target_size}K")]) - .stdout(Stdio::piped()) - .status() - .with_context(|| format!("Failed to exec resize2fs {img}"))?; - ensure!(result.success(), "Failed to resize2fs: {}", result); - - check_image(img)?; - - Ok(()) -} - pub fn load_sepolicy_rule() -> Result<()> { foreach_active_module(|path| { let rule_file = path.join("sepolicy.rule"); @@ -370,18 +326,12 @@ fn _install_module(zip: &str) -> Result<()> { std::fs::remove_file(tmp_module_path)?; } - let default_reserve_size = 256 * 1024 * 1024; let zip_uncompressed_size = get_zip_uncompressed_size(zip)?; - let grow_size = default_reserve_size + zip_uncompressed_size; info!( "zip uncompressed size: {}", humansize::format_size(zip_uncompressed_size, humansize::DECIMAL) ); - info!( - "grow size: {}", - humansize::format_size(grow_size, humansize::DECIMAL) - ); println!("- Preparing image"); println!( @@ -389,14 +339,15 @@ fn _install_module(zip: &str) -> Result<()> { humansize::format_size(zip_uncompressed_size, humansize::DECIMAL) ); + let sparse_image_size = 256 * (1 << 30); // 256G 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 info!("Creating brand new module image"); File::create(tmp_module_img) .context("Failed to create ext4 image file")? - .set_len(grow_size) - .context("Failed to extend ext4 image")?; + .set_len(sparse_image_size) + .context("Failed to truncate ext4 image")?; // format the img to ext4 filesystem let result = Command::new("mkfs.ext4") @@ -410,33 +361,45 @@ fn _install_module(zip: &str) -> Result<()> { "Failed to format ext4 image: {}", String::from_utf8(result.stderr).unwrap() ); - - check_image(tmp_module_img)?; } else if modules_update_img_exist { // modules_update.img exists, we should use it as tmp img info!("Using existing modules_update.img as tmp image"); - std::fs::copy(modules_update_img, tmp_module_img).with_context(|| { + utils::copy_sparse_file(modules_update_img, tmp_module_img).with_context(|| { format!( "Failed to copy {} to {}", modules_update_img.display(), tmp_module_img ) })?; - // grow size of the tmp image - grow_image_size(tmp_module_img, grow_size)?; } else { // modules.img exists, we should use it as tmp img info!("Using existing modules.img as tmp image"); - std::fs::copy(modules_img, tmp_module_img).with_context(|| { + utils::copy_sparse_file(modules_img, tmp_module_img).with_context(|| { format!( "Failed to copy {} to {}", modules_img.display(), tmp_module_img ) })?; - // grow size of the tmp image - grow_image_size(tmp_module_img, grow_size)?; + + // legacy image, truncate it to new size. + if std::fs::metadata(modules_img)?.len() < sparse_image_size { + println!("- Truncate legacy image to new size"); + OpenOptions::new() + .write(true) + .open(tmp_module_img) + .context("Failed to open ext4 image")? + .set_len(sparse_image_size) + .context("Failed to truncate ext4 image")?; + + check_image(tmp_module_img)?; + Command::new("resize2fs") + .arg(tmp_module_img) + .stdout(Stdio::piped()) + .status()?; + } } + check_image(tmp_module_img)?; // ensure modules_update exists ensure_dir_exists(module_update_tmp_dir)?; @@ -473,7 +436,7 @@ fn _install_module(zip: &str) -> Result<()> { // all done, rename the tmp image to modules_update.img if std::fs::rename(tmp_module_img, defs::MODULE_UPDATE_IMG).is_err() { warn!("Rename image failed, try copy it."); - std::fs::copy(tmp_module_img, defs::MODULE_UPDATE_IMG) + utils::copy_sparse_file(tmp_module_img, defs::MODULE_UPDATE_IMG) .with_context(|| "Failed to copy image.".to_string())?; let _ = std::fs::remove_file(tmp_module_img); } @@ -513,14 +476,14 @@ where modules_update_img.display(), modules_update_tmp_img.display() ); - std::fs::copy(modules_update_img, modules_update_tmp_img)?; + utils::copy_sparse_file(modules_update_img, modules_update_tmp_img)?; } else { info!( "copy {} to {}", modules_img.display(), modules_update_tmp_img.display() ); - std::fs::copy(modules_img, modules_update_tmp_img)?; + utils::copy_sparse_file(modules_img, modules_update_tmp_img)?; } // ensure modules_update dir exist @@ -534,7 +497,7 @@ where if let Err(e) = std::fs::rename(modules_update_tmp_img, defs::MODULE_UPDATE_IMG) { warn!("Rename image failed: {e}, try copy it."); - std::fs::copy(modules_update_tmp_img, defs::MODULE_UPDATE_IMG) + utils::copy_sparse_file(modules_update_tmp_img, defs::MODULE_UPDATE_IMG) .with_context(|| "Failed to copy image.".to_string())?; let _ = std::fs::remove_file(modules_update_tmp_img); } diff --git a/userspace/ksud/src/utils.rs b/userspace/ksud/src/utils.rs index aa870e4ba40f..77b1aa75bd8c 100644 --- a/userspace/ksud/src/utils.rs +++ b/userspace/ksud/src/utils.rs @@ -12,6 +12,9 @@ use std::fs::{set_permissions, Permissions}; #[cfg(unix)] use std::os::unix::prelude::PermissionsExt; +use hole_punch::*; +use std::io::{Read, Seek, SeekFrom}; + pub fn ensure_clean_dir(dir: &str) -> Result<()> { let path = Path::new(dir); log::debug!("ensure_clean_dir: {}", path.display()); @@ -182,3 +185,44 @@ pub fn get_tmp_path() -> &'static str { } "" } + +// TODO: use libxcp to improve the speed if cross's MSRV is 1.70 +pub fn copy_sparse_file, Q: AsRef>(src: P, dst: Q) -> Result<()> { + let mut src_file = File::open(src.as_ref())?; + let mut dst_file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(dst.as_ref())?; + + dst_file.set_len(src_file.metadata()?.len())?; + + let segments = src_file.scan_chunks()?; + for segment in segments { + if let SegmentType::Data = segment.segment_type { + let start = segment.start; + let end = segment.end; + + src_file.seek(SeekFrom::Start(start))?; + dst_file.seek(SeekFrom::Start(start))?; + + let mut buffer = [0; 4096]; + let mut total_bytes_copied = 0; + + while total_bytes_copied < end - start { + let bytes_to_read = + std::cmp::min(buffer.len() as u64, end - start - total_bytes_copied); + let bytes_read = src_file.read(&mut buffer[..bytes_to_read as usize])?; + + if bytes_read == 0 { + break; + } + + dst_file.write_all(&buffer[..bytes_read])?; + total_bytes_copied += bytes_read as u64; + } + } + } + + Ok(()) +}