// Copyright 2024 The ChromiumOS Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // To allow compiling this file on non-Linux platforms, main logic is // behind the `linux` module. #[cfg(target_os = "linux")] mod linux { use std::fs::OpenOptions; use std::io::Write; use std::path::PathBuf; use argh::FromArgs; use base::MappedRegion; #[derive(FromArgs)] /// Create ext2 filesystem. struct Args { /// path to the disk, #[argh(option)] output: String, /// path to the source directory to copy files from, #[argh(option)] src: Option, /// number of blocks for each group #[argh(option, default = "1024")] blocks_per_group: u32, /// number of inodes for each group #[argh(option, default = "1024")] inodes_per_group: u32, /// size of memory region in bytes. /// If it's not a multiple of 4096, it will be rounded up to the next multiple of 4096. #[argh(option, default = "4194304")] size: u32, /// if sepecified, create a file systeon on RAM, but do not write to disk. #[argh(switch, short = 'j')] dry_run: bool, } pub fn main() -> anyhow::Result<()> { let args: Args = argh::from_env(); let src_dir = args.src.as_ref().map(|s| PathBuf::new().join(s)); let builder = ext2::Builder { blocks_per_group: args.blocks_per_group, inodes_per_group: args.inodes_per_group, size: args.size, root_dir: src_dir, }; let mem = builder.allocate_memory()?.build_mmap_info()?.do_mmap()?; if args.dry_run { println!("Done!"); return Ok(()); } // SAFETY: `mem` has a valid pointer and its size. let buf = unsafe { std::slice::from_raw_parts(mem.as_ptr(), mem.size()) }; let mut file = OpenOptions::new() .write(true) .create(true) .truncate(true) .open(&args.output) .unwrap(); file.write_all(buf).unwrap(); println!("{} is written!", args.output); Ok(()) } } fn main() -> anyhow::Result<()> { #[cfg(target_os = "linux")] linux::main()?; #[cfg(not(target_os = "linux"))] println!("Not supported on non-Linux platforms"); Ok(()) }