xref: /aosp_15_r20/external/crosvm/ext2/examples/mkfs.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2024 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker // To allow compiling this file on non-Linux platforms, main logic is
6*bb4ee6a4SAndroid Build Coastguard Worker // behind the `linux` module.
7*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_os = "linux")]
8*bb4ee6a4SAndroid Build Coastguard Worker mod linux {
9*bb4ee6a4SAndroid Build Coastguard Worker     use std::fs::OpenOptions;
10*bb4ee6a4SAndroid Build Coastguard Worker     use std::io::Write;
11*bb4ee6a4SAndroid Build Coastguard Worker     use std::path::PathBuf;
12*bb4ee6a4SAndroid Build Coastguard Worker 
13*bb4ee6a4SAndroid Build Coastguard Worker     use argh::FromArgs;
14*bb4ee6a4SAndroid Build Coastguard Worker     use base::MappedRegion;
15*bb4ee6a4SAndroid Build Coastguard Worker 
16*bb4ee6a4SAndroid Build Coastguard Worker     #[derive(FromArgs)]
17*bb4ee6a4SAndroid Build Coastguard Worker     /// Create ext2 filesystem.
18*bb4ee6a4SAndroid Build Coastguard Worker     struct Args {
19*bb4ee6a4SAndroid Build Coastguard Worker         /// path to the disk,
20*bb4ee6a4SAndroid Build Coastguard Worker         #[argh(option)]
21*bb4ee6a4SAndroid Build Coastguard Worker         output: String,
22*bb4ee6a4SAndroid Build Coastguard Worker 
23*bb4ee6a4SAndroid Build Coastguard Worker         /// path to the source directory to copy files from,
24*bb4ee6a4SAndroid Build Coastguard Worker         #[argh(option)]
25*bb4ee6a4SAndroid Build Coastguard Worker         src: Option<String>,
26*bb4ee6a4SAndroid Build Coastguard Worker 
27*bb4ee6a4SAndroid Build Coastguard Worker         /// number of blocks for each group
28*bb4ee6a4SAndroid Build Coastguard Worker         #[argh(option, default = "1024")]
29*bb4ee6a4SAndroid Build Coastguard Worker         blocks_per_group: u32,
30*bb4ee6a4SAndroid Build Coastguard Worker 
31*bb4ee6a4SAndroid Build Coastguard Worker         /// number of inodes for each group
32*bb4ee6a4SAndroid Build Coastguard Worker         #[argh(option, default = "1024")]
33*bb4ee6a4SAndroid Build Coastguard Worker         inodes_per_group: u32,
34*bb4ee6a4SAndroid Build Coastguard Worker 
35*bb4ee6a4SAndroid Build Coastguard Worker         /// size of memory region in bytes.
36*bb4ee6a4SAndroid Build Coastguard Worker         /// If it's not a multiple of 4096, it will be rounded up to the next multiple of 4096.
37*bb4ee6a4SAndroid Build Coastguard Worker         #[argh(option, default = "4194304")]
38*bb4ee6a4SAndroid Build Coastguard Worker         size: u32,
39*bb4ee6a4SAndroid Build Coastguard Worker 
40*bb4ee6a4SAndroid Build Coastguard Worker         /// if sepecified, create a file systeon on RAM, but do not write to disk.
41*bb4ee6a4SAndroid Build Coastguard Worker         #[argh(switch, short = 'j')]
42*bb4ee6a4SAndroid Build Coastguard Worker         dry_run: bool,
43*bb4ee6a4SAndroid Build Coastguard Worker     }
44*bb4ee6a4SAndroid Build Coastguard Worker 
main() -> anyhow::Result<()>45*bb4ee6a4SAndroid Build Coastguard Worker     pub fn main() -> anyhow::Result<()> {
46*bb4ee6a4SAndroid Build Coastguard Worker         let args: Args = argh::from_env();
47*bb4ee6a4SAndroid Build Coastguard Worker         let src_dir = args.src.as_ref().map(|s| PathBuf::new().join(s));
48*bb4ee6a4SAndroid Build Coastguard Worker         let builder = ext2::Builder {
49*bb4ee6a4SAndroid Build Coastguard Worker             blocks_per_group: args.blocks_per_group,
50*bb4ee6a4SAndroid Build Coastguard Worker             inodes_per_group: args.inodes_per_group,
51*bb4ee6a4SAndroid Build Coastguard Worker             size: args.size,
52*bb4ee6a4SAndroid Build Coastguard Worker             root_dir: src_dir,
53*bb4ee6a4SAndroid Build Coastguard Worker         };
54*bb4ee6a4SAndroid Build Coastguard Worker         let mem = builder.allocate_memory()?.build_mmap_info()?.do_mmap()?;
55*bb4ee6a4SAndroid Build Coastguard Worker         if args.dry_run {
56*bb4ee6a4SAndroid Build Coastguard Worker             println!("Done!");
57*bb4ee6a4SAndroid Build Coastguard Worker             return Ok(());
58*bb4ee6a4SAndroid Build Coastguard Worker         }
59*bb4ee6a4SAndroid Build Coastguard Worker 
60*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY: `mem` has a valid pointer and its size.
61*bb4ee6a4SAndroid Build Coastguard Worker         let buf = unsafe { std::slice::from_raw_parts(mem.as_ptr(), mem.size()) };
62*bb4ee6a4SAndroid Build Coastguard Worker         let mut file = OpenOptions::new()
63*bb4ee6a4SAndroid Build Coastguard Worker             .write(true)
64*bb4ee6a4SAndroid Build Coastguard Worker             .create(true)
65*bb4ee6a4SAndroid Build Coastguard Worker             .truncate(true)
66*bb4ee6a4SAndroid Build Coastguard Worker             .open(&args.output)
67*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap();
68*bb4ee6a4SAndroid Build Coastguard Worker 
69*bb4ee6a4SAndroid Build Coastguard Worker         file.write_all(buf).unwrap();
70*bb4ee6a4SAndroid Build Coastguard Worker 
71*bb4ee6a4SAndroid Build Coastguard Worker         println!("{} is written!", args.output);
72*bb4ee6a4SAndroid Build Coastguard Worker 
73*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
74*bb4ee6a4SAndroid Build Coastguard Worker     }
75*bb4ee6a4SAndroid Build Coastguard Worker }
76*bb4ee6a4SAndroid Build Coastguard Worker 
main() -> anyhow::Result<()>77*bb4ee6a4SAndroid Build Coastguard Worker fn main() -> anyhow::Result<()> {
78*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(target_os = "linux")]
79*bb4ee6a4SAndroid Build Coastguard Worker     linux::main()?;
80*bb4ee6a4SAndroid Build Coastguard Worker 
81*bb4ee6a4SAndroid Build Coastguard Worker     #[cfg(not(target_os = "linux"))]
82*bb4ee6a4SAndroid Build Coastguard Worker     println!("Not supported on non-Linux platforms");
83*bb4ee6a4SAndroid Build Coastguard Worker 
84*bb4ee6a4SAndroid Build Coastguard Worker     Ok(())
85*bb4ee6a4SAndroid Build Coastguard Worker }
86