Skip to content

Commit 78cc93c

Browse files
committed
esp: Find shim and grub in newer fcos images
From fcos 43, shim and grub are not longer located in /usr/lib/bootupd.. but in /usr/lib/efi/.. This commit adds some changes to be able to find shim and grub binaries both under the old and new image fs hierarchy. Note that as for the kernel images, the first found shim and grub are returned. Signed-off-by: Beñat Gartzia Arruabarrena <bgartzia@redhat.com>
1 parent 4c77196 commit 78cc93c

2 files changed

Lines changed: 37 additions & 30 deletions

File tree

lib/src/esp.rs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// SPDX-License-Identifier: MIT
55

66
use crate::pefile;
7+
use glob::glob;
78
use std::fs;
89
use std::io;
910
use std::path::{Path, PathBuf};
@@ -14,35 +15,32 @@ pub struct Esp {
1415
grub: PathBuf,
1516
}
1617

17-
const ESP_VENDOR_NAMES: [&str; 2] = ["redhat", "fedora"];
18+
fn find_efi_bin(root_path: &Path, bin_name: &str) -> io::Result<PathBuf> {
19+
let glob_path = root_path.join(Path::new("**/EFI/*/").join(bin_name));
20+
let glob_pattern = glob_path.to_str().ok_or_else(|| {
21+
io::Error::new(
22+
io::ErrorKind::InvalidInput,
23+
"Invalid efi bin search pattern",
24+
)
25+
})?;
1826

19-
fn esp_vendor_path(esp_root_path: &Path) -> io::Result<PathBuf> {
20-
for vendor in ESP_VENDOR_NAMES {
21-
let vendor_path = esp_root_path.join(format!("EFI/{vendor}"));
22-
match fs::metadata(&vendor_path) {
23-
Err(_) => {}
24-
Ok(metadata) => {
25-
if metadata.is_dir() {
26-
return Ok(vendor_path);
27-
}
28-
}
27+
let search_results = match glob(glob_pattern) {
28+
Ok(results) => results,
29+
Err(_) => {
30+
return Err(io::Error::new(
31+
io::ErrorKind::InvalidInput,
32+
"Invalid efi bin search pattern",
33+
));
2934
}
35+
};
36+
if let Some(path) = search_results.filter_map(Result::ok).next() {
37+
// Assume there's just one of them; return the first one
38+
return Ok(path);
3039
}
31-
Err(io::Error::new(
32-
io::ErrorKind::NotFound,
33-
String::from("Unknown ESP tree format"),
34-
))
35-
}
3640

37-
fn bin_path_from_esp_vendor(esp_vendor_path: &Path, bin_name: &str) -> io::Result<PathBuf> {
38-
let bin_path = esp_vendor_path.join(bin_name);
39-
let metadata = fs::metadata(&bin_path)?;
40-
if metadata.is_file() {
41-
return Ok(bin_path);
42-
}
4341
Err(io::Error::new(
44-
io::ErrorKind::IsADirectory,
45-
bin_path.to_string_lossy(),
42+
io::ErrorKind::NotFound,
43+
format!("{bin_name} not found"),
4644
))
4745
}
4846

@@ -53,11 +51,9 @@ impl Esp {
5351
return Err(io::Error::new(io::ErrorKind::NotADirectory, path));
5452
}
5553

56-
let esp_vendor_path = esp_vendor_path(&path_pb)?;
57-
5854
Ok(Esp {
59-
grub: bin_path_from_esp_vendor(&esp_vendor_path, "grubx64.efi")?,
60-
shim: bin_path_from_esp_vendor(&esp_vendor_path, "shimx64.efi")?,
55+
grub: find_efi_bin(&path_pb, "grubx64.efi")?,
56+
shim: find_efi_bin(&path_pb, "shimx64.efi")?,
6157
})
6258
}
6359

lib/src/rootfs.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,33 @@
33
//
44
// SPDX-License-Identifier: MIT
55

6+
use std::fs;
67
use std::io;
78
use std::path;
89

910
const RELATIVE_KERNELS_PATH: &str = "usr/lib/modules/";
10-
const RELATIVE_ESP_PATH: &str = "usr/lib/bootupd/updates/";
11+
const RELATIVE_ESP_OLD: &str = "usr/lib/bootupd/updates/";
12+
// From fcos-43 on shim/grub are stored in different directories
13+
const RELATIVE_ESP_NEW: &str = "usr/lib/efi";
1114

1215
pub struct RootFSTree {
1316
esp_path: String,
1417
kernels_path: String,
1518
}
1619

20+
fn esp_path_absolute(rootfs_path: &path::Path) -> io::Result<path::PathBuf> {
21+
let temptative = rootfs_path.join(RELATIVE_ESP_NEW);
22+
match fs::exists(&temptative)? {
23+
true => Ok(temptative),
24+
false => Ok(rootfs_path.join(RELATIVE_ESP_OLD)),
25+
}
26+
}
27+
1728
impl RootFSTree {
1829
pub fn new(rootfs_path: &str) -> io::Result<RootFSTree> {
1930
let rootfs_path = path::absolute(rootfs_path)?;
2031
let kernels_path = rootfs_path.join(RELATIVE_KERNELS_PATH);
21-
let esp_path = rootfs_path.join(RELATIVE_ESP_PATH);
32+
let esp_path = esp_path_absolute(&rootfs_path)?;
2233
Ok(RootFSTree {
2334
esp_path: esp_path.to_str().unwrap().into(),
2435
kernels_path: kernels_path.to_str().unwrap().into(),

0 commit comments

Comments
 (0)