diff --git a/src/dracut-cpio/src/main.rs b/src/dracut-cpio/src/main.rs index b3cc5144..a1994b96 100644 --- a/src/dracut-cpio/src/main.rs +++ b/src/dracut-cpio/src/main.rs @@ -810,7 +810,8 @@ fn main() -> std::io::Result<()> { Ok(()) } -// tests change working directory, so need to be run with --test-threads=1 +// tests change working directory, so need to be run with: +// cargo test -- --test-threads=1 --nocapture #[cfg(test)] mod tests { use super::*; @@ -1733,4 +1734,77 @@ mod tests { assert_eq!(src_md.uid(), ex_md.uid()); assert_eq!(src_md.gid(), ex_md.gid()); } + + #[test] + fn test_archive_dev_maj_min() { + let mut twd = TempWorkDir::new(); + twd.create_tmp_file("file1", 0); + + let md = fs::symlink_metadata("file1").unwrap(); + if md.uid() != 0 { + println!("SKIPPED: this test requires root"); + return; + } + + twd.create_tmp_mknod("bdev1", 'b', Some((0x01, 0x01))); + twd.create_tmp_mknod("bdev2", 'b', Some((0x02, 0x100))); + twd.create_tmp_mknod("bdev3", 'b', Some((0x03, 0x1000))); + twd.create_tmp_mknod("bdev4", 'b', Some((0x04, 0x10000))); + twd.create_tmp_mknod("bdev5", 'b', Some((0x100, 0x05))); + twd.create_tmp_mknod("bdev6", 'b', Some((0x100, 0x06))); + let file_list: &str = "file1\nbdev1\nbdev2\nbdev3\nbdev4\nbdev5\nbdev6\n"; + + // create GNU cpio archive + twd.create_tmp_dir("gnucpio_xtr"); + gnu_cpio_create(file_list.as_bytes(), "gnucpio_xtr/gnu.cpio"); + twd.cleanup_files.push(PathBuf::from("gnucpio_xtr/gnu.cpio")); + + // create Dracut cpio archive + twd.create_tmp_dir("dracut_xtr"); + let f = fs::File::create("dracut_xtr/dracut.cpio").unwrap(); + let mut writer = io::BufWriter::new(f); + let mut reader = io::BufReader::new(file_list.as_bytes()); + let wrote = archive_loop( + &mut reader, + &mut writer, + &ArchiveProperties::default() + ) + .unwrap(); + twd.cleanup_files.push(PathBuf::from("dracut_xtr/dracut.cpio")); + + let file_list_count = file_list.split_terminator('\n').count() as u64; + assert!(wrote >= NEWC_HDR_LEN * file_list_count + + (file_list.len() as u64)); + + let status = Command::new("cpio") + .current_dir("gnucpio_xtr") + .args(&["--quiet", "-i", "-H", "newc", "-F", "gnu.cpio"]) + .status() + .expect("GNU cpio failed to start"); + assert!(status.success()); + for s in file_list.split_terminator('\n') { + let p = PathBuf::from("gnucpio_xtr/".to_owned() + s); + twd.cleanup_files.push(p); + } + + let status = Command::new("cpio") + .current_dir("dracut_xtr") + .args(&["--quiet", "-i", "-H", "newc", "-F", "dracut.cpio"]) + .status() + .expect("GNU cpio failed to start"); + assert!(status.success()); + for s in file_list.split_terminator('\n') { + let dp = PathBuf::from("dracut_xtr/".to_owned() + s); + twd.cleanup_files.push(dp); + } + + // diff extracted major/minor between dracut and GNU cpio created archives + for s in file_list.split_terminator('\n') { + let gmd = fs::symlink_metadata("gnucpio_xtr/".to_owned() + s).unwrap(); + let dmd = fs::symlink_metadata("dracut_xtr/".to_owned() + s).unwrap(); + print!("{}: cpio extracted dev_t gnu: {:#x}, dracut: {:#x}\n", + s, gmd.rdev(), dmd.rdev()); + assert!(gmd.rdev() == dmd.rdev()); + } + } }