mirror of
https://github.com/edera-dev/sprout.git
synced 2026-11-04 21:42:23 +00:00
Commit 2da1cea skipped filesystems that couldn't be opened, but an error
while scanning an opened filesystem, such as a driver returning
DEVICE_ERROR or ACCESS_DENIED, still aborted autoconfiguration for every
filesystem. Log a warning and move on to the next scan instead, and do
the same for each directory scanned for Linux kernels.
85 lines
3.1 KiB
Rust
85 lines
3.1 KiB
Rust
use anyhow::{Context, Result};
|
|
use edera_sprout_config::RootConfiguration;
|
|
use log::warn;
|
|
use uefi::fs::FileSystem;
|
|
use uefi::proto::device_path::DevicePath;
|
|
use uefi::proto::media::fs::SimpleFileSystem;
|
|
|
|
/// bls: autodetect and configure BLS-enabled filesystems.
|
|
pub mod bls;
|
|
|
|
/// linux: autodetect and configure Linux kernels.
|
|
/// This autoconfiguration module should not be activated
|
|
/// on BLS-enabled filesystems as it may make duplicate entries.
|
|
pub mod linux;
|
|
|
|
/// windows: autodetect and configure Windows boot configurations.
|
|
pub mod windows;
|
|
|
|
/// Generate a [RootConfiguration] based on the environment.
|
|
/// Intakes a `config` to use as the basis of the autoconfiguration.
|
|
pub fn autoconfigure(config: &mut RootConfiguration) -> Result<()> {
|
|
// Find all the filesystems that are on the system.
|
|
let filesystem_handles =
|
|
uefi::boot::find_handles::<SimpleFileSystem>().context("unable to scan filesystems")?;
|
|
|
|
// For each filesystem that was detected, scan it for supported autoconfig mechanisms.
|
|
for handle in filesystem_handles {
|
|
// Acquire the device path root for the filesystem.
|
|
// A filesystem that can't be opened is skipped, as it should not prevent
|
|
// autoconfiguring the other filesystems.
|
|
let root = match uefi::boot::open_protocol_exclusive::<DevicePath>(handle) {
|
|
Ok(root) => root.to_boxed(),
|
|
Err(error) => {
|
|
warn!("skipping filesystem, unable to get its root: {}", error);
|
|
continue;
|
|
}
|
|
};
|
|
|
|
// Open the filesystem that was detected.
|
|
let filesystem = match uefi::boot::open_protocol_exclusive::<SimpleFileSystem>(handle) {
|
|
Ok(filesystem) => filesystem,
|
|
Err(error) => {
|
|
warn!("skipping filesystem, unable to open it: {}", error);
|
|
continue;
|
|
}
|
|
};
|
|
|
|
// Trade the filesystem protocol for the uefi filesystem helper.
|
|
let mut filesystem = FileSystem::new(filesystem);
|
|
|
|
// A scan that fails is skipped, as a filesystem that can't be read should not
|
|
// prevent autoconfiguring the other filesystems.
|
|
|
|
// Scan the filesystem for BLS supported configurations.
|
|
let bls_found = match bls::scan(&mut filesystem, &root, config) {
|
|
Ok(found) => found,
|
|
Err(error) => {
|
|
warn!(
|
|
"unable to scan filesystem for bls configurations: {:#}",
|
|
error
|
|
);
|
|
false
|
|
}
|
|
};
|
|
|
|
// If BLS was not found, scan for Linux configurations.
|
|
if !bls_found && let Err(error) = linux::scan(&mut filesystem, &root, config) {
|
|
warn!(
|
|
"unable to scan filesystem for linux configurations: {:#}",
|
|
error
|
|
);
|
|
}
|
|
|
|
// Always look for Windows configurations.
|
|
if let Err(error) = windows::scan(&mut filesystem, &root, config) {
|
|
warn!(
|
|
"unable to scan filesystem for windows configurations: {:#}",
|
|
error
|
|
);
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|