e2e_tests: pmem_ext2: Add a test case for many files

BUG=b:33033395
TEST=CQ

Change-Id: I276ba8276da0e39a5b6c15a903d7707ba7e79f61
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5677674
Reviewed-by: Junichi Uekawa <uekawa@chromium.org>
Reviewed-by: Takaya Saeki <takayas@chromium.org>
Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
This commit is contained in:
Keiichi Watanabe 2024-07-04 17:05:53 +09:00 committed by crosvm LUCI
parent 737432fcb8
commit 0a8717d86e

View file

@ -8,6 +8,7 @@
use std::os::unix::fs::symlink;
use anyhow::bail;
use fixture::vm::Config;
use fixture::vm::TestVm;
@ -93,3 +94,64 @@ fn pmem_ext2() -> anyhow::Result<()> {
Ok(())
}
fn set_num_files_limit(num_files: u64) -> anyhow::Result<()> {
let mut buf = std::mem::MaybeUninit::<libc::rlimit64>::zeroed();
// SAFETY: Safe because this will only modify `buf` and we check the return value.
let res =
unsafe { libc::prlimit64(0, libc::RLIMIT_NOFILE, std::ptr::null(), buf.as_mut_ptr()) };
if res != 0 {
bail!("failed to call prlimit64");
}
// SAFETY: Safe because the kernel guarantees that the struct is fully initialized.
let mut limit = unsafe { buf.assume_init() };
if limit.rlim_max < num_files {
bail!("rlim_max < num_files: {} < {}", limit.rlim_max, num_files);
}
limit.rlim_cur = num_files;
// SAFETY: Safe because limit is properly initialized.
let res = unsafe { libc::setrlimit64(libc::RLIMIT_NOFILE, &limit) };
if res != 0 {
bail!("failed to call setrlimit64");
}
Ok(())
}
/// Check a case with 1000 files in a directory.
#[test]
fn pmem_ext2_manyfiles() -> anyhow::Result<()> {
// /temp_dir/
// ├── 0.txt
// ...
// └── 999.txt
// TODO(crrev.com/c/5644847): Remove `set_num_files_limi` once we add a logic to fork a separate
// process for ext2 creation with larger files limit.
set_num_files_limit(2048)?;
let temp_dir = tempfile::tempdir()?;
for i in 0..1000 {
let f = temp_dir.path().join(&format!("{i}.txt"));
std::fs::write(f, &format!("{i}"))?;
}
let config = Config::new().extra_args(vec![
"--pmem-ext2".to_string(),
temp_dir.path().to_str().unwrap().to_string(),
]);
let mut vm = TestVm::new(config)?;
vm.exec_in_guest("mount -t ext2 /dev/pmem0 /mnt/")?;
// `ls -l` returns 1002 lines because 1000 files + 'lost+found' and the total line.
let ls_result = vm
.exec_in_guest_async("ls -l /mnt/ | wc -l")?
.with_timeout(std::time::Duration::from_secs(1))
.wait_ok(&mut vm)?;
assert_eq!(ls_result.stdout.trim(), "1002");
Ok(())
}