22//
33// SPDX-License-Identifier: MPL-2.0
44
5- use std:: fs;
5+ use log:: { debug, info} ;
6+ use std:: { fs, path:: Path } ;
67
78use disks:: BlockDevice ;
8- use partitioning:: { loopback, sparsefile} ;
9+ use partitioning:: {
10+ gpt:: { disk:: LogicalBlockSize , mbr:: ProtectiveMBR , partition_types, GptConfig } ,
11+ loopback, sparsefile, sync_gpt_partitions,
12+ } ;
913
10- // Demo of various disk APIs, enumeration, loopback and sparse.
14+ /// Creates a protective MBR on the specified disk
15+ ///
16+ /// # Arguments
17+ ///
18+ /// * `disk_size` - Size of the disk in bytes
19+ /// * `path` - Path to the disk device
20+ ///
21+ /// # Returns
22+ ///
23+ /// Result indicating success or error
24+ fn create_protective_mbr < P > ( disk_size : u64 , path : P ) -> Result < ( ) , Box < dyn std:: error:: Error > >
25+ where
26+ P : AsRef < Path > ,
27+ {
28+ debug ! ( "🛡️ Creating protective MBR for disk of size {} bytes" , disk_size) ;
29+ let mut gpt_device = fs:: File :: options ( ) . write ( true ) . open ( & path) ?;
30+ let lb_size = ( disk_size / 512 ) as u32 ;
31+ let lb_size = lb_size. saturating_sub ( 1 ) ; // subtract 1 for the MBR
32+ let mbr = ProtectiveMBR :: with_lb_size ( lb_size) ;
33+ mbr. overwrite_lba0 ( & mut gpt_device) ?;
34+ info ! ( "✅ Successfully created protective MBR at {:?}" , path. as_ref( ) ) ;
35+ Ok ( ( ) )
36+ }
37+
38+ /// Creates a default GPT partition scheme on the disk with:
39+ /// - 256MB EFI System Partition
40+ /// - 2GB Boot Partition
41+ /// - 4GB Swap Partition
42+ /// - Remaining space as Linux filesystem
43+ ///
44+ /// # Arguments
45+ ///
46+ /// * `path` - Path to the disk device
47+ ///
48+ /// # Returns
49+ ///
50+ /// Result indicating success or error
51+ fn create_default_partition_scheme < P > ( path : P ) -> Result < ( ) , Box < dyn std:: error:: Error > >
52+ where
53+ P : AsRef < Path > ,
54+ {
55+ info ! ( "💽 Creating default GPT partition scheme on {:?}" , path. as_ref( ) ) ;
56+
57+ // Configure and create GPT disk
58+ let gpt_config = GptConfig :: new ( )
59+ . writable ( true )
60+ . logical_block_size ( LogicalBlockSize :: Lb512 ) ;
61+
62+ let mut gpt_disk = gpt_config. create ( & path) ?;
63+
64+ debug ! ( "📝 Creating EFI System Partition (256MB)" ) ;
65+ gpt_disk. add_partition ( "" , 256 * 1024 * 1024 , partition_types:: EFI , 0 , None ) ?;
66+
67+ debug ! ( "📝 Creating Boot Partition (2GB)" ) ;
68+ gpt_disk. add_partition ( "" , 2 * 1024 * 1024 * 1024 , partition_types:: FREEDESK_BOOT , 0 , None ) ?;
69+
70+ debug ! ( "📝 Creating Swap Partition (4GB)" ) ;
71+ gpt_disk. add_partition ( "" , 4 * 1024 * 1024 * 1024 , partition_types:: LINUX_SWAP , 0 , None ) ?;
72+
73+ // Use remaining space for root partition
74+ let sectors = gpt_disk. find_free_sectors ( ) ;
75+ debug ! ( "📊 Available sectors: {sectors:?}" ) ;
76+ let ( _, length) = sectors. iter ( ) . find ( |( _, l) | * l > 0 ) . unwrap ( ) ;
77+ debug ! ( "📝 Creating Root Partition ({}MB)" , ( length * 512 ) / ( 1024 * 1024 ) ) ;
78+ gpt_disk. add_partition ( "" , * length * 512 , partition_types:: LINUX_FS , 0 , None ) ?;
79+ let _ = gpt_disk. write ( ) ?;
80+
81+ info ! ( "✅ Successfully created partition scheme" ) ;
82+ Ok ( ( ) )
83+ }
84+
85+ /// Demonstrates usage of disk APIs including:
86+ /// - Creating sparse files
87+ /// - Setting up loopback devices
88+ /// - Partitioning with GPT
89+ /// - Enumerating block devices
1190fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
12- // create 35GB img, attach loopback
13- sparsefile:: create ( "hello.world" , 35 * 1024 * 1024 * 1024 ) ?;
91+ pretty_env_logger:: formatted_builder ( )
92+ . filter_level ( log:: LevelFilter :: Trace )
93+ . init ( ) ;
94+ info ! ( "🚀 Starting disk partitioning demo" ) ;
95+
96+ // Create 35GB sparse image file and attach to loopback device
97+ let image_size = 35 * 1024 * 1024 * 1024 ;
98+ info ! ( "📁 Creating {}GB sparse image file" , image_size / ( 1024 * 1024 * 1024 ) ) ;
99+ sparsefile:: create ( "hello.world" , image_size) ?;
100+
101+ debug ! ( "🔄 Setting up loopback device" ) ;
14102 let device = loopback:: LoopDevice :: create ( ) ?;
15103 device. attach ( "hello.world" ) ?;
16- eprintln ! ( "loop device: {}" , & device. path) ;
104+ info ! ( "💫 Loop device created at: {}" , & device. path) ;
105+
106+ // Initialize disk with protective MBR and partition scheme
107+ create_protective_mbr ( image_size, "hello.world" ) ?;
108+ create_default_partition_scheme ( "hello.world" ) ?;
109+
110+ // Notify kernel of partition table changes
111+ debug ! ( "🔄 Syncing partition table changes" ) ;
112+ sync_gpt_partitions ( & device. path ) ?;
17113
18- // discover all loop devices
114+ // Get list of all loopback devices
115+ info ! ( "🔍 Discovering block devices" ) ;
19116 let loop_devices = BlockDevice :: discover ( ) ?
20117 . into_iter ( )
21118 . filter_map ( |device| {
@@ -27,26 +124,29 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
27124 } )
28125 . collect :: < Vec < _ > > ( ) ;
29126
30- // print loop devices
127+ // Display information about discovered devices
128+ info ! ( "📋 Device information:" ) ;
31129 for loop_device in loop_devices {
32130 if let Some ( file) = loop_device. file_path ( ) {
33131 if let Some ( disk) = loop_device. disk ( ) {
34- println ! (
35- "Loopback device: {} (backing file: {})" ,
132+ info ! (
133+ "💾 Loopback device: {} (backing file: {})" ,
36134 loop_device. name( ) ,
37135 file. display( )
38136 ) ;
39- println ! ( "└─Disk: {} ({})" , disk. name( ) , disk. model( ) . unwrap_or( "Unknown" ) ) ;
137+ info ! ( " └─Disk: {} ({})" , disk. name( ) , disk. model( ) . unwrap_or( "Unknown" ) ) ;
40138 for partition in disk. partitions ( ) {
41- println ! ( " ├─{} {partition}" , partition. name) ;
139+ info ! ( " ├─{} {partition}" , partition. name) ;
42140 }
43141 }
44142 }
45143 }
46144
47- // detach loopback, remove img
145+ // Clean up resources
146+ debug ! ( "🧹 Cleaning up resources" ) ;
48147 device. detach ( ) ?;
49- fs:: remove_file ( "hello.world" ) ?;
148+ // fs::remove_file("hello.world")?;
50149
150+ info ! ( "✨ Demo completed successfully" ) ;
51151 Ok ( ( ) )
52152}
0 commit comments