77
88use std:: borrow:: Cow ;
99use std:: fmt:: Display ;
10+ use std:: fmt:: Write as _;
1011use std:: io:: Write ;
11- use std:: process:: Command ;
1212use std:: process:: Stdio ;
1313
1414use anyhow:: Ok ;
@@ -103,23 +103,6 @@ impl BlockSetup {
103103 }
104104}
105105
106- fn sgdisk_partition (
107- sgdisk : & mut Command ,
108- n : u32 ,
109- part : impl AsRef < str > ,
110- name : impl AsRef < str > ,
111- typecode : Option < & str > ,
112- ) {
113- sgdisk. arg ( "-n" ) ;
114- sgdisk. arg ( format ! ( "{n}:{}" , part. as_ref( ) ) ) ;
115- sgdisk. arg ( "-c" ) ;
116- sgdisk. arg ( format ! ( "{n}:{}" , name. as_ref( ) ) ) ;
117- if let Some ( typecode) = typecode {
118- sgdisk. arg ( "-t" ) ;
119- sgdisk. arg ( format ! ( "{n}:{typecode}" ) ) ;
120- }
121- }
122-
123106fn mkfs < ' a > (
124107 dev : & str ,
125108 fs : Filesystem ,
@@ -239,35 +222,27 @@ pub(crate) fn install_create_rootfs(
239222 let bootfs = mntdir. join ( "boot" ) ;
240223 std:: fs:: create_dir_all ( bootfs) ?;
241224
225+ // Generate partitioning spec as input to sfdisk
242226 let mut partno = 0 ;
243-
244- // Run sgdisk to create partitions.
245- let mut sgdisk = Task :: new ( "Initializing partitions" , "sgdisk" ) ;
246- // sgdisk is too verbose
247- sgdisk. cmd . stdout ( Stdio :: null ( ) ) ;
248- sgdisk. cmd . arg ( "-Z" ) ;
249- sgdisk. cmd . arg ( device. path ( ) ) ;
250- sgdisk. cmd . args ( [ "-U" , "R" ] ) ;
227+ let mut partitioning_buf = String :: new ( ) ;
228+ writeln ! ( partitioning_buf, "label: gpt" ) ?;
229+ let random_label = uuid:: Uuid :: new_v4 ( ) ;
230+ writeln ! ( & mut partitioning_buf, "label-id: {random_label}" ) ?;
251231 if cfg ! ( target_arch = "x86_64" ) {
252- // BIOS-BOOT
253232 partno += 1 ;
254- sgdisk_partition (
255- & mut sgdisk. cmd ,
256- partno,
257- "0:+1M" ,
258- "BIOS-BOOT" ,
259- Some ( "21686148-6449-6E6F-744E-656564454649" ) ,
260- ) ;
233+ writeln ! (
234+ & mut partitioning_buf,
235+ r#"size=1MiB, bootable, type=21686148-6449-6E6F-744E-656564454649, name="BIOS-BOOT""#
236+ ) ?;
261237 } else if cfg ! ( target_arch = "powerpc64" ) {
262238 // PowerPC-PReP-boot
263239 partno += 1 ;
264- sgdisk_partition (
265- & mut sgdisk. cmd ,
266- partno,
267- "0:+4M" ,
268- crate :: bootloader:: PREPBOOT_LABEL ,
269- Some ( crate :: bootloader:: PREPBOOT_GUID ) ,
270- ) ;
240+ let label = crate :: bootloader:: PREPBOOT_LABEL ;
241+ let uuid = crate :: bootloader:: PREPBOOT_GUID ;
242+ writeln ! (
243+ & mut partitioning_buf,
244+ r#"size=4MiB, bootable, type={uuid}, name="{label}""#
245+ ) ?;
271246 } else if cfg ! ( any( target_arch = "aarch64" , target_arch = "s390x" ) ) {
272247 // No bootloader partition is necessary
273248 } else {
@@ -276,13 +251,10 @@ pub(crate) fn install_create_rootfs(
276251
277252 let esp_partno = if super :: ARCH_USES_EFI {
278253 partno += 1 ;
279- sgdisk_partition (
280- & mut sgdisk. cmd ,
281- partno,
282- format ! ( "0:+{EFIPN_SIZE_MB}M" ) ,
283- "EFI-SYSTEM" ,
284- Some ( "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ) ,
285- ) ;
254+ writeln ! (
255+ & mut partitioning_buf,
256+ r#"size={EFIPN_SIZE_MB}MiB, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name="EFI-SYSTEM""#
257+ ) ?;
286258 Some ( partno)
287259 } else {
288260 None
@@ -293,37 +265,31 @@ pub(crate) fn install_create_rootfs(
293265 // it would aid systemd-boot.
294266 let boot_partno = if block_setup. requires_bootpart ( ) {
295267 partno += 1 ;
296- sgdisk_partition (
297- & mut sgdisk. cmd ,
298- partno,
299- format ! ( "0:+{BOOTPN_SIZE_MB}M" ) ,
300- "boot" ,
301- None ,
302- ) ;
268+ writeln ! (
269+ & mut partitioning_buf,
270+ r#"size={BOOTPN_SIZE_MB}MiB, name="boot""#
271+ ) ?;
303272 Some ( partno)
304273 } else {
305274 None
306275 } ;
307276 let rootpn = partno + 1 ;
308277 let root_size = root_size
309- . map ( |v| Cow :: Owned ( format ! ( "0:{v}M" ) ) )
310- . unwrap_or_else ( || Cow :: Borrowed ( "0:0" ) ) ;
311- sgdisk_partition (
312- & mut sgdisk. cmd ,
313- rootpn,
314- root_size,
315- "root" ,
316- Some ( LINUX_PARTTYPE ) ,
317- ) ;
318- sgdisk. run ( ) . context ( "Failed to run sgdisk" ) ?;
278+ . map ( |v| Cow :: Owned ( format ! ( "size={v}MiB, " ) ) )
279+ . unwrap_or_else ( || Cow :: Borrowed ( "" ) ) ;
280+ writeln ! (
281+ & mut partitioning_buf,
282+ r#"{root_size}type={LINUX_PARTTYPE}, name="root""#
283+ ) ?;
284+ tracing:: debug!( "Partitioning: {partitioning_buf}" ) ;
285+ Task :: new ( "Initializing partitions" , "sfdisk" )
286+ . arg ( "--wipe=always" )
287+ . arg ( device. path ( ) )
288+ . quiet ( )
289+ . run_with_stdin_buf ( Some ( partitioning_buf. as_bytes ( ) ) )
290+ . context ( "Failed to run sfdisk" ) ?;
319291 tracing:: debug!( "Created partition table" ) ;
320292
321- // Reread the partition table
322- Task :: new ( "Reread partition table" , "blockdev" )
323- . arg ( "--rereadpt" )
324- . arg ( devpath. as_str ( ) )
325- . run ( ) ?;
326-
327293 // Full udev sync; it'd obviously be better to await just the devices
328294 // we're targeting, but this is a simple coarse hammer.
329295 crate :: blockdev:: udev_settle ( ) ?;
0 commit comments