1+ //! Block device utilities for bootc.
2+ //!
3+ //! This module provides utilities for querying and managing block devices,
4+ //! partitions, and filesystems during bootc installation and operation.
5+
6+ // Allow unsafe code for prctl FFI declaration
7+ #![ allow( unsafe_code) ]
8+
19use std:: env;
210use std:: path:: Path ;
311use std:: process:: { Command , Stdio } ;
@@ -10,6 +18,14 @@ use serde::Deserialize;
1018
1119use bootc_utils:: CommandRunExt ;
1220
21+ // prctl constants and extern declaration for parent death signal
22+ // PR_SET_PDEATHSIG = 1
23+ const PR_SET_PDEATHSIG : libc:: c_int = 1 ;
24+
25+ unsafe extern "C" {
26+ fn prctl ( option : libc:: c_int , arg2 : libc:: c_ulong ) -> libc:: c_int ;
27+ }
28+
1329/// MBR partition type IDs that indicate an EFI System Partition.
1430 /// 0x06 is FAT16 ( used as ESP on some MBR systems ) , 0xEF is the
1531/// explicit EFI System Partition type.
@@ -26,27 +42,41 @@ struct DevicesOutput {
2642
2743#[ allow( dead_code) ]
2844#[ derive( Debug , Clone , Deserialize ) ]
45+ /// Information about a block device.
2946pub struct Device {
47+ /// Device name (e.g., "sda", "sda1").
3048 pub name : String ,
49+ /// Device serial number.
3150 pub serial : Option < String > ,
51+ /// Device model.
3252 pub model : Option < String > ,
53+ /// Partition label.
3354 pub partlabel : Option < String > ,
55+ /// Partition type.
3456 pub parttype : Option < String > ,
57+ /// Partition UUID.
3558 pub partuuid : Option < String > ,
3659 /// Partition number (1-indexed). None for whole disk devices.
3760 pub partn : Option < u32 > ,
61+ /// Child devices (partitions for a disk).
3862 pub children : Option < Vec < Device > > ,
63+ /// Device size in bytes.
3964 pub size : u64 ,
65+ /// Major:minor device numbers.
4066 #[ serde( rename = "maj:min" ) ]
4167 pub maj_min : Option < String > ,
4268 // NOTE this one is not available on older util-linux, and
4369 // will also not exist for whole blockdevs (as opposed to partitions).
4470 pub start : Option < u64 > ,
4571
4672 // Filesystem-related properties
73+ /// Filesystem label.
4774 pub label : Option < String > ,
75+ /// Filesystem type.
4876 pub fstype : Option < String > ,
77+ /// Filesystem UUID.
4978 pub uuid : Option < String > ,
79+ /// Device path.
5080 pub path : Option < String > ,
5181 /// Partition table type (e.g., "gpt", "dos"). Only present on whole disk devices.
5282 pub pttype : Option < String > ,
@@ -234,6 +264,7 @@ impl Device {
234264 }
235265}
236266
267+ /// List information about a block device.
237268#[ context( "Listing device {dev}" ) ]
238269pub fn list_dev ( dev : & Utf8Path ) -> Result < Device > {
239270 let mut devs: DevicesOutput = Command :: new ( "lsblk" )
@@ -256,7 +287,9 @@ pub fn list_dev_by_dir(dir: &Dir) -> Result<Device> {
256287 list_dev ( & Utf8PathBuf :: from ( & fsinfo. source ) )
257288}
258289
290+ /// A loopback block device backed by a file.
259291pub struct LoopbackDevice {
292+ /// The loopback device path (e.g., "/dev/loop0").
260293 pub dev : Option < Utf8PathBuf > ,
261294 // Handle to the cleanup helper process
262295 cleanup_handle : Option < LoopbackCleanupHandle > ,
@@ -384,17 +417,25 @@ impl Drop for LoopbackDevice {
384417 }
385418}
386419
387- /// Main function for the loopback cleanup helper process
388- /// This function does not return - it either exits normally or via signal
420+ /// Run the loopback cleanup helper process.
421+ ///
422+ /// This function does not return - it either exits normally or via signal.
423+ /// It is used to clean up loopback devices when the parent process dies.
389424pub async fn run_loopback_cleanup_helper ( device_path : & str ) -> Result < ( ) > {
390425 // Check if we're running as a cleanup helper
391426 if std:: env:: var ( "BOOTC_LOOPBACK_CLEANUP_HELPER" ) . is_err ( ) {
392427 anyhow:: bail!( "This function should only be called as a cleanup helper" ) ;
393428 }
394429
395430 // Set up death signal notification - we want to be notified when parent dies
396- rustix:: process:: set_parent_process_death_signal ( Some ( rustix:: process:: Signal :: TERM ) )
397- . context ( "Failed to set parent death signal" ) ?;
431+ // Use prctl directly via libc since rustix removed this API
432+ unsafe {
433+ // SIGTERM = 15
434+ let ret = prctl ( PR_SET_PDEATHSIG , libc:: SIGTERM as libc:: c_ulong ) ;
435+ if ret != 0 {
436+ return Err ( std:: io:: Error :: last_os_error ( ) ) . context ( "Failed to set parent death signal" ) ;
437+ }
438+ }
398439
399440 // Wait for SIGTERM (either from parent death or normal cleanup)
400441 tokio:: signal:: unix:: signal ( tokio:: signal:: unix:: SignalKind :: terminate ( ) )
@@ -434,7 +475,9 @@ pub async fn run_loopback_cleanup_helper(device_path: &str) -> Result<()> {
434475 }
435476}
436477
437- /// Parse a string into mibibytes
478+ /// Parse a size string into mebibytes.
479+ ///
480+ /// Supports suffixes: MiB/M, GiB/G, TiB/T.
438481pub fn parse_size_mib ( mut s : & str ) -> Result < u64 > {
439482 let suffixes = [
440483 ( "MiB" , 1u64 ) ,
0 commit comments