@@ -8,7 +8,10 @@ use std::{fs, path::Path};
8
8
use disks:: BlockDevice ;
9
9
use partitioning:: {
10
10
gpt:: { disk:: LogicalBlockSize , mbr:: ProtectiveMBR , partition_types, GptConfig } ,
11
- loopback, sparsefile,
11
+ loopback,
12
+ planner:: Planner ,
13
+ sparsefile,
14
+ strategy:: { AllocationStrategy , PartitionRequest , SizeRequirement , Strategy } ,
12
15
} ;
13
16
14
17
use partitioning:: blkpg;
@@ -54,30 +57,70 @@ fn create_default_partition_scheme<P>(path: P) -> Result<(), Box<dyn std::error:
54
57
where
55
58
P : AsRef < Path > ,
56
59
{
57
- info ! ( "Creating default GPT partition scheme on {:?}" , path. as_ref( ) ) ;
60
+ let path = path. as_ref ( ) ;
61
+ info ! ( "Creating default GPT partition scheme on {:?}" , path) ;
58
62
59
63
// Configure and create GPT disk
60
64
let gpt_config = GptConfig :: new ( )
61
65
. writable ( true )
62
66
. logical_block_size ( LogicalBlockSize :: Lb512 ) ;
63
67
64
68
let mut gpt_disk = gpt_config. create ( & path) ?;
69
+ gpt_disk. write_inplace ( ) ?;
70
+
71
+ // Connect the planner.
72
+ let disk = disks:: loopback:: Device :: from_device_path ( path) . unwrap ( ) ;
73
+ let block = BlockDevice :: loopback_device ( disk) ;
74
+ let mut planner = Planner :: new ( block) ;
75
+ let mut strategy = Strategy :: new ( AllocationStrategy :: InitializeWholeDisk ) ;
76
+
77
+ // efi
78
+ strategy. add_request ( PartitionRequest {
79
+ size : SizeRequirement :: Range {
80
+ min : 256 * 1024 * 1024 ,
81
+ max : 1 * 1024 * 1024 * 1024 ,
82
+ } ,
83
+ alignment : None ,
84
+ } ) ;
85
+ // xbootldr
86
+ strategy. add_request ( PartitionRequest {
87
+ size : SizeRequirement :: Range {
88
+ min : 2 * 1024 * 1024 * 1024 ,
89
+ max : 4 * 1024 * 1024 * 1024 ,
90
+ } ,
91
+ alignment : None ,
92
+ } ) ;
93
+ // swap
94
+ strategy. add_request ( PartitionRequest {
95
+ size : SizeRequirement :: Range {
96
+ min : 1 * 1024 * 1024 * 1024 ,
97
+ max : 4 * 1024 * 1024 * 1024 ,
98
+ } ,
99
+ alignment : None ,
100
+ } ) ;
101
+ // root
102
+ strategy. add_request ( PartitionRequest {
103
+ size : SizeRequirement :: Range {
104
+ min : 30 * 1024 * 1024 * 1024 ,
105
+ max : 120 * 1024 * 1024 * 1024 ,
106
+ } ,
107
+ alignment : None ,
108
+ } ) ;
109
+ // home
110
+ strategy. add_request ( PartitionRequest {
111
+ size : SizeRequirement :: AtLeast ( 50 * 1024 * 1024 * 1024 ) ,
112
+ alignment : None ,
113
+ } ) ;
114
+ info ! ( "Applying strategy: {}" , strategy. describe( ) ) ;
115
+ strategy. apply ( & mut planner) ?;
116
+ info ! ( "Computed: {}" , planner. describe_changes( ) ) ;
117
+
118
+ // TODO: Track the types in the API and use them here
119
+ for partition in planner. current_layout ( ) {
120
+ info ! ( "Adding partition: {:?}" , & partition) ;
121
+ gpt_disk. add_partition ( "" , partition. size ( ) , partition_types:: LINUX_FS , 0 , None ) ?;
122
+ }
65
123
66
- info ! ( "Creating EFI System Partition (256MB)" ) ;
67
- gpt_disk. add_partition ( "" , 256 * 1024 * 1024 , partition_types:: EFI , 0 , None ) ?;
68
-
69
- info ! ( "Creating Boot Partition (2GB)" ) ;
70
- gpt_disk. add_partition ( "" , 2 * 1024 * 1024 * 1024 , partition_types:: FREEDESK_BOOT , 0 , None ) ?;
71
-
72
- info ! ( "Creating Swap Partition (4GB)" ) ;
73
- gpt_disk. add_partition ( "" , 4 * 1024 * 1024 * 1024 , partition_types:: LINUX_SWAP , 0 , None ) ?;
74
-
75
- // Use remaining space for root partition
76
- let sectors = gpt_disk. find_free_sectors ( ) ;
77
- debug ! ( "Available sectors: {sectors:?}" ) ;
78
- let ( _, length) = sectors. iter ( ) . find ( |( _, l) | * l > 0 ) . unwrap ( ) ;
79
- info ! ( "Creating Root Partition ({}MB)" , ( length * 512 ) / ( 1024 * 1024 ) ) ;
80
- gpt_disk. add_partition ( "" , * length * 512 , partition_types:: LINUX_FS , 0 , None ) ?;
81
124
let _ = gpt_disk. write ( ) ?;
82
125
83
126
info ! ( "Successfully created partition scheme" ) ;
@@ -91,12 +134,12 @@ where
91
134
/// - Enumerating block devices
92
135
fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
93
136
pretty_env_logger:: formatted_timed_builder ( )
94
- . filter_level ( log:: LevelFilter :: Info )
137
+ . filter_level ( log:: LevelFilter :: Debug )
95
138
. init ( ) ;
96
139
info ! ( "Starting disk partitioning demo" ) ;
97
140
98
- // Create 35GB sparse image file and attach to loopback device
99
- let image_size = 35 * 1024 * 1024 * 1024 ;
141
+ // Create 100GB sparse image file and attach to loopback device
142
+ let image_size = 100 * 1024 * 1024 * 1024 ;
100
143
info ! ( "Creating {}GB sparse image file" , image_size / ( 1024 * 1024 * 1024 ) ) ;
101
144
sparsefile:: create ( "hello.world" , image_size) ?;
102
145
@@ -106,8 +149,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
106
149
info ! ( "Loop device created at: {}" , & device. path) ;
107
150
108
151
// Initialize disk with protective MBR and partition scheme
109
- create_protective_mbr ( image_size, "hello.world" ) ?;
110
- create_default_partition_scheme ( "hello.world" ) ?;
152
+ create_protective_mbr ( image_size, & device . path ) ?;
153
+ create_default_partition_scheme ( & device . path ) ?;
111
154
112
155
// Notify kernel of partition table changes
113
156
debug ! ( "Syncing partition table changes" ) ;
0 commit comments