blob: 8621c23cffc8b5c03bc5284493380a33274d3f93 [file] [edit]
// 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<String>,
/// 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(())
}