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