@@ -18,7 +18,7 @@ use chrono::prelude::*;
1818use fn_error_context:: context;
1919use openat_ext:: OpenatDirExt ;
2020use os_release:: OsRelease ;
21- use rustix:: fd:: BorrowedFd ;
21+ use rustix:: { fd:: AsFd , fd :: BorrowedFd , fs :: StatVfsMountFlags } ;
2222use walkdir:: WalkDir ;
2323use widestring:: U16CString ;
2424
@@ -47,6 +47,9 @@ pub(crate) const SHIM: &str = "shimx64.efi";
4747#[ cfg( target_arch = "riscv64" ) ]
4848pub ( crate ) const SHIM : & str = "shimriscv64.efi" ;
4949
50+ /// The mount path for uefi
51+ const EFIVARFS : & str = "/sys/firmware/efi/efivars" ;
52+
5053/// Systemd boot loader info EFI variable names
5154const LOADER_INFO_VAR_STR : & str = "LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f" ;
5255const STUB_INFO_VAR_STR : & str = "StubInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f" ;
@@ -146,6 +149,19 @@ impl Efi {
146149 return Ok ( ( ) ) ;
147150 }
148151 let sysroot = Dir :: open_ambient_dir ( "/" , cap_std:: ambient_authority ( ) ) ?;
152+ let efi = sysroot
153+ . open_dir ( EFIVARFS . strip_prefix ( "/" ) . unwrap ( ) )
154+ . context ( "Opening efivars dir" ) ?;
155+ let st = rustix:: fs:: fstatvfs ( efi. as_fd ( ) ) ?;
156+ // Do nothing if efivars is readonly or empty
157+ // See https://github.com/coreos/bootupd/issues/972
158+ if st. f_flag . contains ( StatVfsMountFlags :: RDONLY )
159+ || std:: fs:: read_dir ( EFIVARFS ) ?. next ( ) . is_none ( )
160+ {
161+ log:: info!( "Skipped EFI variables update: efivars not writable or empty" ) ;
162+ return Ok ( ( ) ) ;
163+ }
164+
149165 let product_name = get_product_name ( & sysroot) ?;
150166 log:: debug!( "Get product name: '{product_name}'" ) ;
151167 assert ! ( product_name. len( ) > 0 ) ;
@@ -182,7 +198,7 @@ fn string_from_utf16_bytes(slice: &[u8]) -> String {
182198
183199/// Read a nul-terminated UTF-16 string from an EFI variable.
184200fn read_efi_var_utf16_string ( name : & str ) -> Option < String > {
185- let efivars = Path :: new ( "/sys/firmware/efi/efivars" ) ;
201+ let efivars = Path :: new ( EFIVARFS ) ;
186202 if !efivars. exists ( ) {
187203 log:: trace!( "No efivars mount at {:?}" , efivars) ;
188204 return None ;
0 commit comments