Skip to content

Commit a83550c

Browse files
composefs/boot: Copy system-boot binaries manually
On systemd v258, bootctl doesn't copy the systemd-boot binaries to the ESP, so we copy the binaries ourselves if we don't find them in the final ESP Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
1 parent 176c381 commit a83550c

3 files changed

Lines changed: 70 additions & 3 deletions

File tree

.github/workflows/ci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,6 @@ jobs:
193193
;;
194194
esac
195195
196-
197-
198196
if [ "${{ matrix.variant }}" = "composefs-sealeduki-sdboot" ]; then
199197
BUILDROOTBASE=$(just pullspec-for-os buildroot-base ${{ matrix.test_os }})
200198
echo "BOOTC_buildroot_base=${BUILDROOTBASE}" >> $GITHUB_ENV

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,7 @@ pub(crate) async fn setup_composefs_boot(
12481248
&state.config_opts,
12491249
None,
12501250
get_secureboot_keys(&mounted_fs, BOOTC_AUTOENROLL_PATH)?,
1251+
&mounted_fs,
12511252
)?;
12521253
}
12531254

crates/lib/src/bootloader.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,14 @@ pub(crate) fn install_via_bootupd(
158158
}
159159
}
160160

161-
#[context("Installing bootloader")]
161+
#[context("Installing systemd boot")]
162162
pub(crate) fn install_systemd_boot(
163163
device: &PartitionTable,
164164
_rootfs: &Utf8Path,
165165
_configopts: &crate::install::InstallConfigOpts,
166166
_deployment_path: Option<&str>,
167167
autoenroll: Option<SecurebootKeys>,
168+
mounted_erofs: &Dir,
168169
) -> Result<()> {
169170
let esp_part = device
170171
.find_partition_of_type(discoverable_partition_specification::ESP)
@@ -180,6 +181,73 @@ pub(crate) fn install_systemd_boot(
180181
.log_debug()
181182
.run_inherited_with_cmd_context()?;
182183

184+
// Check for systemd-boot binaries in the EFI/systemd directory
185+
// systemd v258 won't copy the binary if an EFI booted system is not detected
186+
let systemd_dir = esp_mount.fd.open_dir_optional("EFI/systemd")?;
187+
188+
let systemd_boot_found = if let Some(dir) = systemd_dir {
189+
let mut found = false;
190+
for entry in dir.entries()? {
191+
let entry = entry?;
192+
let name = entry.file_name();
193+
194+
if let Some(name_str) = name.to_str() {
195+
if name_str.starts_with("systemd-boot") && name_str.ends_with(".efi") {
196+
found = true;
197+
break;
198+
}
199+
}
200+
}
201+
202+
found
203+
} else {
204+
false
205+
};
206+
207+
if !systemd_boot_found {
208+
println!("Copying systemd-boot binary manually");
209+
210+
// Find the systemd-boot binary in the source directory
211+
let boot_dir = mounted_erofs.open_dir("usr/lib/systemd/boot/efi")?;
212+
let mut systemd_boot_binary = None;
213+
214+
for entry in boot_dir.entries()? {
215+
let entry = entry?;
216+
let name = entry.file_name();
217+
if let Some(name_str) = name.to_str() {
218+
if name_str.starts_with("systemd-boot") && name_str.ends_with(".efi") {
219+
systemd_boot_binary = Some(name_str.to_string());
220+
break;
221+
}
222+
}
223+
}
224+
225+
let binary_name = systemd_boot_binary
226+
.ok_or_else(|| anyhow::anyhow!("No systemd-boot binary found in source"))?;
227+
228+
let src_path = format!("usr/lib/systemd/boot/efi/{}", binary_name);
229+
let systemd_dest_path = format!("EFI/systemd/{}", binary_name);
230+
231+
// Determine the appropriate BOOT binary name based on architecture
232+
let boot_binary_name = if binary_name.contains("x64") {
233+
"BOOTX64.EFI"
234+
} else if binary_name.contains("ia32") {
235+
"BOOTIA32.EFI"
236+
} else if binary_name.contains("aa64") {
237+
"BOOTAA64.EFI"
238+
} else {
239+
"BOOTX64.EFI" // Default fallback
240+
};
241+
242+
mounted_erofs.copy(&src_path, &esp_mount.fd, &systemd_dest_path)?;
243+
244+
mounted_erofs.copy(
245+
&src_path,
246+
&esp_mount.fd,
247+
&format!("EFI/BOOT/{}", boot_binary_name),
248+
)?;
249+
}
250+
183251
if let Some(SecurebootKeys { dir, keys }) = autoenroll {
184252
let path = esp_path.join(SYSTEMD_KEY_DIR);
185253
create_dir_all(&path)?;

0 commit comments

Comments
 (0)