Skip to content

Commit 07e4a22

Browse files
boot/uki: Refactor .efi file collection
Merge `Type2Entry` and `UsrLibModulesUki` structs keeping only `Type2Entry` Signed-off-by: Johan-Liebert1 <[email protected]>
1 parent 6b56c83 commit 07e4a22

File tree

1 file changed

+24
-81
lines changed

1 file changed

+24
-81
lines changed

crates/composefs-boot/src/bootloader.rs

Lines changed: 24 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ pub enum PEType {
221221

222222
#[derive(Debug)]
223223
pub struct Type2Entry<ObjectID: FsVerityHashValue> {
224+
pub kver: Option<Box<OsStr>>,
224225
// This is the path (relative to /boot/EFI/Linux) of the file
225226
pub file_path: PathBuf,
226227
// The Portable Executable binary
@@ -239,40 +240,44 @@ impl<ObjectID: FsVerityHashValue> Type2Entry<ObjectID> {
239240
}
240241
}
241242

242-
fn recurse_dir(
243+
// Find UKI components, the UKI PE binary and other UKI addons,
244+
// if any, in the provided directory
245+
fn find_uki_components(
243246
dir: &Directory<ObjectID>,
244247
entries: &mut Vec<Self>,
245248
path: &mut PathBuf,
249+
kver: &Option<Box<OsStr>>,
246250
) -> Result<()> {
247251
for (filename, inode) in dir.entries() {
248252
path.push(filename);
249253

250-
// We also want to collect all UKI extensions
254+
// Collect all UKI extensions
255+
// Usually we'll find them in the root with directories ending in `.efi.extra.d` for kernel
256+
// specific addons. Global addons are found in `loader/addons`
251257
if let Inode::Directory(dir) = inode {
252-
if !filename.as_bytes().ends_with(EFI_ADDON_DIR_EXT.as_bytes()) {
253-
continue;
254-
}
255-
256-
Type2Entry::recurse_dir(dir, entries, path)?;
257-
return Ok(());
258+
Self::find_uki_components(dir, entries, path, kver)?;
259+
path.pop();
260+
continue;
258261
}
259262

260263
if !filename.as_bytes().ends_with(EFI_EXT.as_bytes()) {
264+
path.pop();
261265
continue;
262266
}
263267

264268
let Inode::Leaf(leaf) = inode else {
265-
bail!("/boot/EFI/Linux/{filename:?} is a directory");
269+
bail!("{filename:?} is a directory");
266270
};
267271

268272
let LeafContent::Regular(file) = &leaf.content else {
269-
bail!("/boot/EFI/Linux/{filename:?} is not a regular file");
273+
bail!("{filename:?} is not a regular file");
270274
};
271275

272276
entries.push(Self {
277+
kver: kver.clone(),
273278
file_path: path.clone(),
274279
file: file.clone(),
275-
pe_type: if path.components().count() == 1 {
280+
pe_type: if path.components().count() == 0 {
276281
PEType::Uki
277282
} else {
278283
PEType::UkiAddon
@@ -290,84 +295,25 @@ impl<ObjectID: FsVerityHashValue> Type2Entry<ObjectID> {
290295

291296
match root.get_directory("/boot/EFI/Linux".as_ref()) {
292297
Ok(entries_dir) => {
293-
Type2Entry::recurse_dir(entries_dir, &mut entries, &mut PathBuf::new())?
298+
Self::find_uki_components(entries_dir, &mut entries, &mut PathBuf::new(), &None)?
294299
}
295300
Err(ImageError::NotFound(..)) => {}
296301
Err(other) => Err(other)?,
297302
};
298303

299-
Ok(entries)
300-
}
301-
}
302-
303-
#[derive(Debug)]
304-
pub struct UsrLibModulesUki<ObjectID: FsVerityHashValue> {
305-
pub kver: Box<OsStr>,
306-
pub file_path: PathBuf,
307-
pub file: RegularFile<ObjectID>,
308-
pub pe_type: PEType,
309-
}
310-
311-
impl<ObjectID: FsVerityHashValue> UsrLibModulesUki<ObjectID> {
312-
fn recurse_dir(
313-
dir: &Directory<ObjectID>,
314-
entries: &mut Vec<Self>,
315-
path: &mut PathBuf,
316-
kver: &OsStr,
317-
) -> Result<()> {
318-
for (filename, inode) in dir.entries() {
319-
path.push(filename);
320-
321-
// Collect all UKI extensions
322-
if let Inode::Directory(dir) = inode {
323-
if !filename.as_bytes().ends_with(EFI_ADDON_DIR_EXT.as_bytes()) {
324-
continue;
325-
}
326-
327-
UsrLibModulesUki::recurse_dir(dir, entries, path, kver)?;
328-
return Ok(());
329-
}
330-
331-
if !filename.as_bytes().ends_with(EFI_EXT.as_bytes()) {
332-
continue;
333-
}
334-
335-
let Inode::Leaf(leaf) = inode else {
336-
bail!("/usr/lib/modules/{filename:?} is a directory");
337-
};
338-
339-
let LeafContent::Regular(file) = &leaf.content else {
340-
bail!("/usr/lib/modules/{filename:?} is not a regular file");
341-
};
342-
343-
entries.push(Self {
344-
kver: Box::from(kver),
345-
file_path: path.clone(),
346-
file: file.clone(),
347-
pe_type: if path.components().count() == 0 {
348-
PEType::Uki
349-
} else {
350-
PEType::UkiAddon
351-
},
352-
});
353-
354-
path.pop();
355-
}
356-
357-
Ok(())
358-
}
359-
360-
pub fn load_all(root: &Directory<ObjectID>) -> Result<Vec<Self>> {
361-
let mut entries = vec![];
362-
363304
match root.get_directory("/usr/lib/modules".as_ref()) {
364305
Ok(modules_dir) => {
365306
for (kver, inode) in modules_dir.entries() {
366307
let Inode::Directory(dir) = inode else {
367308
continue;
368309
};
369310

370-
UsrLibModulesUki::recurse_dir(dir, &mut entries, &mut PathBuf::new(), kver)?;
311+
Self::find_uki_components(
312+
dir,
313+
&mut entries,
314+
&mut PathBuf::new(),
315+
&Some(Box::from(kver)),
316+
)?;
371317
}
372318
}
373319
Err(ImageError::NotFound(..)) => {}
@@ -452,7 +398,7 @@ initrd /{id}/initramfs.img
452398
pub enum BootEntry<ObjectID: FsVerityHashValue> {
453399
Type1(Type1Entry<ObjectID>),
454400
Type2(Type2Entry<ObjectID>),
455-
UsrLibModulesUki(UsrLibModulesUki<ObjectID>),
401+
UsrLibModulesUki(Type2Entry<ObjectID>),
456402
UsrLibModulesVmLinuz(UsrLibModulesVmlinuz<ObjectID>),
457403
}
458404

@@ -468,9 +414,6 @@ pub fn get_boot_resources<ObjectID: FsVerityHashValue>(
468414
for e in Type2Entry::load_all(&image.root)? {
469415
entries.push(BootEntry::Type2(e));
470416
}
471-
for e in UsrLibModulesUki::load_all(&image.root)? {
472-
entries.push(BootEntry::UsrLibModulesUki(e));
473-
}
474417
for e in UsrLibModulesVmlinuz::load_all(&image.root)? {
475418
entries.push(BootEntry::UsrLibModulesVmLinuz(e));
476419
}

0 commit comments

Comments
 (0)