@@ -8,10 +8,23 @@ use crate::packagesystem;
88use anyhow:: { bail, Result } ;
99
1010use crate :: util;
11+ use serde:: { Deserialize , Serialize } ;
1112
1213// grub2-install file path
1314pub ( crate ) const GRUB_BIN : & str = "usr/sbin/grub2-install" ;
1415
16+ #[ derive( Serialize , Deserialize , Debug ) ]
17+ struct BlockDevice {
18+ path : String ,
19+ pttype : String ,
20+ parttypename : Option < String > ,
21+ }
22+
23+ #[ derive( Serialize , Deserialize , Debug ) ]
24+ struct Devices {
25+ blockdevices : Vec < BlockDevice > ,
26+ }
27+
1528#[ derive( Default ) ]
1629pub ( crate ) struct Bios { }
1730
@@ -22,12 +35,11 @@ impl Bios {
2235 #[ cfg( target_arch = "x86_64" ) ]
2336 {
2437 // find /boot partition
25- let boot_dir = Path :: new ( "/" ) . join ( "boot" ) ;
2638 cmd = Command :: new ( "findmnt" ) ;
2739 cmd. arg ( "--noheadings" )
2840 . arg ( "--output" )
2941 . arg ( "SOURCE" )
30- . arg ( boot_dir ) ;
42+ . arg ( "/boot" ) ;
3143 let partition = util:: cmd_output ( & mut cmd) ?;
3244
3345 // lsblk to find parent device
@@ -81,6 +93,38 @@ impl Bios {
8193 }
8294 Ok ( ( ) )
8395 }
96+
97+ // check bios_boot partition on gpt type disk
98+ fn get_bios_boot_partition ( & self ) -> Result < Option < String > > {
99+ let target = self . get_device ( ) ?;
100+ // lsblk to list children with bios_boot
101+ let output = Command :: new ( "lsblk" )
102+ . args ( [
103+ "--json" ,
104+ "--output" ,
105+ "PATH,PTTYPE,PARTTYPENAME" ,
106+ target. trim ( ) ,
107+ ] )
108+ . output ( ) ?;
109+ if !output. status . success ( ) {
110+ std:: io:: stderr ( ) . write_all ( & output. stderr ) ?;
111+ bail ! ( "Failed to run lsblk" ) ;
112+ }
113+
114+ let output = String :: from_utf8 ( output. stdout ) ?;
115+ // Parse the JSON string into the `Devices` struct
116+ let devices: Devices = serde_json:: from_str ( & output) . expect ( "JSON was not well-formatted" ) ;
117+
118+ // Find the device with the parttypename "BIOS boot"
119+ for device in devices. blockdevices {
120+ if let Some ( parttypename) = & device. parttypename {
121+ if parttypename == "BIOS boot" && device. pttype == "gpt" {
122+ return Ok ( Some ( device. path ) ) ;
123+ }
124+ }
125+ }
126+ Ok ( None )
127+ }
84128}
85129
86130impl Component for Bios {
@@ -120,6 +164,11 @@ impl Component for Bios {
120164 }
121165
122166 fn query_adopt ( & self ) -> Result < Option < Adoptable > > {
167+ #[ cfg( target_arch = "x86_64" ) ]
168+ if crate :: efi:: is_efi_booted ( ) ? && self . get_bios_boot_partition ( ) ?. is_none ( ) {
169+ log:: debug!( "Skip BIOS adopt" ) ;
170+ return Ok ( None ) ;
171+ }
123172 crate :: component:: query_adopt_state ( )
124173 }
125174
0 commit comments