Skip to content

Commit 643cfb0

Browse files
xtask: Always allow writing to OVMF vars
In the AArch64 version of OVMF currently used in CI, it crashes if the vars aren't writable. (A newer version that I tested locally doesn't have this problem.) Having vars be writable is a more normal UEFI environment anyway though, so remove the special case for AArch64 and make the vars always writable. Since the vars file might be in some read-only location, or owned by root (e.g. a system package installed to /usr), a temporary copy of the vars file is made before using it. Also add a `PflashMode` enum to make the call sites of `add_pflash_args` a little clearer.
1 parent 8833ff9 commit 643cfb0

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

xtask/src/qemu.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use tempfile::TempDir;
1717
struct OvmfPaths {
1818
code: PathBuf,
1919
vars: PathBuf,
20-
vars_read_only: bool,
2120
}
2221

2322
impl OvmfPaths {
@@ -26,19 +25,14 @@ impl OvmfPaths {
2625
UefiArch::AArch64 => Self {
2726
code: dir.join("QEMU_EFI-pflash.raw"),
2827
vars: dir.join("vars-template-pflash.raw"),
29-
// The OVMF implementation for AArch64 won't boot unless
30-
// the vars file is writeable.
31-
vars_read_only: false,
3228
},
3329
UefiArch::IA32 => Self {
3430
code: dir.join("OVMF32_CODE.fd"),
3531
vars: dir.join("OVMF32_VARS.fd"),
36-
vars_read_only: true,
3732
},
3833
UefiArch::X86_64 => Self {
3934
code: dir.join("OVMF_CODE.fd"),
4035
vars: dir.join("OVMF_VARS.fd"),
41-
vars_read_only: true,
4236
},
4337
}
4438
}
@@ -84,10 +78,18 @@ impl OvmfPaths {
8478
}
8579
}
8680

87-
fn add_pflash_args(cmd: &mut Command, file: &Path, read_only: bool) {
81+
enum PflashMode {
82+
ReadOnly,
83+
ReadWrite,
84+
}
85+
86+
fn add_pflash_args(cmd: &mut Command, file: &Path, mode: PflashMode) {
8887
// Build the argument as an OsString to avoid requiring a UTF-8 path.
8988
let mut arg = OsString::from("if=pflash,format=raw,readonly=");
90-
arg.push(if read_only { "on" } else { "off" });
89+
arg.push(match mode {
90+
PflashMode::ReadOnly => "on",
91+
PflashMode::ReadWrite => "off",
92+
});
9193
arg.push(",file=");
9294
arg.push(file);
9395

@@ -313,10 +315,20 @@ pub fn run_qemu(arch: UefiArch, opt: &QemuOpt) -> Result<()> {
313315
}
314316
}
315317

318+
let tmp_dir = TempDir::new()?;
319+
let tmp_dir = tmp_dir.path();
320+
316321
// Set up OVMF.
317322
let ovmf_paths = OvmfPaths::find(opt, arch)?;
318-
add_pflash_args(&mut cmd, &ovmf_paths.code, /*read_only=*/ true);
319-
add_pflash_args(&mut cmd, &ovmf_paths.vars, ovmf_paths.vars_read_only);
323+
324+
// Make a copy of the OVMF vars file so that it can be used
325+
// read+write without modifying the original. Under AArch64, some
326+
// versions of OVMF won't boot if the vars file isn't writeable.
327+
let ovmf_vars = tmp_dir.join("ovmf_vars");
328+
fs_err::copy(&ovmf_paths.vars, &ovmf_vars)?;
329+
330+
add_pflash_args(&mut cmd, &ovmf_paths.code, PflashMode::ReadOnly);
331+
add_pflash_args(&mut cmd, &ovmf_vars, PflashMode::ReadWrite);
320332

321333
// Mount a local directory as a FAT partition.
322334
cmd.arg("-drive");
@@ -331,9 +343,6 @@ pub fn run_qemu(arch: UefiArch, opt: &QemuOpt) -> Result<()> {
331343
cmd.args(&["-display", "none"]);
332344
}
333345

334-
let tmp_dir = TempDir::new()?;
335-
let tmp_dir = tmp_dir.path();
336-
337346
let test_disk = tmp_dir.join("test_disk.fat.img");
338347
create_mbr_test_disk(&test_disk)?;
339348

0 commit comments

Comments
 (0)