Skip to content

Commit 3a39aed

Browse files
Introduce #[cfg(efi_arch)]
A utility cfg macro defined in build.rs so that we can deny EFI only bootloaders - GrubCC and SystemdBoot, on non-EFI systems at compile time Also, only allow setting default bootloaders for EFI systems Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
1 parent e08f0b4 commit 3a39aed

11 files changed

Lines changed: 74 additions & 48 deletions

File tree

build.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn main() {
2+
println!("cargo::rustc-check-cfg=cfg(efi_arch)");
3+
4+
if cfg!(any(
5+
target_arch = "x86_64",
6+
target_arch = "aarch64",
7+
target_arch = "riscv64"
8+
)) {
9+
println!("cargo:rustc-cfg=efi_arch");
10+
}
11+
}

src/backend/statefile.rs

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::bootloader::Bootloader;
44
use crate::bootupd::list_dev_current_root;
5-
use crate::freezethaw::fsfreeze_thaw_cycle;
5+
66
use crate::model::SavedState;
77
use crate::util::SignalTerminationGuard;
88
use anyhow::{bail, Context, Result};
@@ -134,22 +134,7 @@ impl SavedState {
134134
}
135135
}
136136

137-
#[cfg(any(target_arch = "powerpc64", target_arch = "s390x"))]
138-
Bootloader::GrubCC | Bootloader::SystemdBoot => {
139-
let arch = if cfg!(target_arch = "powerpc64") {
140-
"powerpc64"
141-
} else {
142-
"s390x"
143-
};
144-
145-
anyhow::bail!("Only Grub is supported for {arch}");
146-
}
147-
148-
#[cfg(any(
149-
target_arch = "x86_64",
150-
target_arch = "aarch64",
151-
target_arch = "riscv64"
152-
))]
137+
#[cfg(efi_arch)]
153138
Bootloader::GrubCC | Bootloader::SystemdBoot => {
154139
use crate::efi::Efi;
155140
let efi = Efi::default();
@@ -201,6 +186,7 @@ impl SavedState {
201186
bail!("{} already exists", statepath.display());
202187
}
203188

189+
#[cfg(efi_arch)]
204190
Bootloader::GrubCC | Bootloader::SystemdBoot => {
205191
bail!("{} already exists in the ESP", Self::STATEFILE_NAME);
206192
}
@@ -211,6 +197,7 @@ impl SavedState {
211197
/// Write-lock guard for statefile, protecting against concurrent state updates.
212198
#[derive(Debug)]
213199
pub(crate) struct StateLockGuard {
200+
#[allow(dead_code)]
214201
pub(crate) sysroot_path: Utf8PathBuf,
215202
pub(crate) sysroot: Dir,
216203
#[allow(dead_code)]
@@ -234,39 +221,22 @@ impl StateLockGuard {
234221
return Ok(());
235222
}
236223

237-
#[cfg(any(target_arch = "powerpc64", target_arch = "s390x"))]
238-
#[context("Updating state")]
239-
pub(crate) fn update_state(
240-
&mut self,
241-
state: &SavedState,
242-
bootloader: Bootloader,
243-
) -> Result<()> {
244-
let arch = if cfg!(target_arch = "powerpc64") {
245-
"powerpc64"
246-
} else {
247-
"s390x"
248-
};
249-
250-
if bootloader != Bootloader::Grub {
251-
anyhow::bail!("Found bootloader: {bootloader}. Only Grub is supported for {arch}");
252-
}
253-
254-
self.write_grub_statefile(state)
255-
}
256-
257224
/// Atomically replace the on-disk state with a new version.
258-
#[cfg(not(any(target_arch = "powerpc64", target_arch = "s390x")))]
259225
#[context("Updating state")]
260226
pub(crate) fn update_state(
261227
&mut self,
262228
state: &SavedState,
263229
bootloader: Bootloader,
264230
) -> Result<()> {
231+
#[cfg(not(efi_arch))]
232+
return self.write_grub_statefile(state);
233+
265234
if bootloader == Bootloader::Grub {
266235
return self.write_grub_statefile(state);
267236
}
268237

269238
use crate::efi::Efi;
239+
use crate::freezethaw::fsfreeze_thaw_cycle;
270240

271241
let device = get_parent_device(&self.sysroot)?;
272242
let all_esps = device

src/bootloader.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
11
use anyhow::Result;
22
use fn_error_context::context;
33
use serde::{Deserialize, Serialize};
4-
use std::{fmt::Display, sync::OnceLock};
4+
use std::fmt::Display;
55

66
#[derive(
77
Debug, Default, Copy, Clone, clap::ValueEnum, PartialEq, Eq, Hash, Serialize, Deserialize,
88
)]
99
pub enum Bootloader {
1010
#[default]
1111
Grub,
12+
#[cfg(efi_arch)]
1213
GrubCC,
14+
#[cfg(efi_arch)]
1315
SystemdBoot,
1416
}
1517

1618
impl Display for Bootloader {
1719
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1820
match self {
1921
Bootloader::Grub => f.write_str("grub"),
22+
#[cfg(efi_arch)]
2023
Bootloader::GrubCC => f.write_str("grub-cc"),
24+
#[cfg(efi_arch)]
2125
Bootloader::SystemdBoot => f.write_str("systemd-boot"),
2226
}
2327
}
2428
}
2529

2630
impl Bootloader {
31+
#[cfg(efi_arch)]
2732
fn next(self) -> Option<Self> {
2833
match self {
2934
Self::Grub => Some(Self::GrubCC),
@@ -32,6 +37,13 @@ impl Bootloader {
3237
}
3338
}
3439

40+
#[cfg(not(efi_arch))]
41+
fn next(self) -> Option<Self> {
42+
match self {
43+
Self::Grub => None,
44+
}
45+
}
46+
3547
pub(crate) fn iter() -> impl Iterator<Item = Self> {
3648
std::iter::successors(Some(Self::Grub), |v| v.next())
3749
}
@@ -47,31 +59,37 @@ impl Bootloader {
4759
pub(crate) fn efi_component_name(&self) -> &'static str {
4860
match self {
4961
Bootloader::Grub => "grub2",
62+
#[cfg(efi_arch)]
5063
Bootloader::GrubCC => "grub-cc",
64+
#[cfg(efi_arch)]
5165
Bootloader::SystemdBoot => "systemd-boot",
5266
}
5367
}
5468

69+
#[cfg(efi_arch)]
5570
pub(crate) fn try_from_efi_component_name(component_name: &str) -> Result<Self> {
5671
match component_name {
5772
"grub2" => Ok(Self::Grub),
73+
#[cfg(efi_arch)]
5874
"grub-cc" => Ok(Self::GrubCC),
75+
#[cfg(efi_arch)]
5976
"systemd-boot" => Ok(Self::SystemdBoot),
6077
_ => anyhow::bail!("Not a valid bootloader: {component_name}"),
6178
}
6279
}
6380
}
6481

65-
#[cfg(any(target_arch = "powerpc64", target_arch = "s390x"))]
82+
#[cfg(not(efi_arch))]
6683
#[context("Getting bootloader")]
6784
pub(crate) fn get_bootloader() -> Result<Bootloader> {
6885
Ok(Bootloader::Grub)
6986
}
7087

71-
#[cfg(not(any(target_arch = "powerpc64", target_arch = "s390x")))]
88+
#[cfg(efi_arch)]
7289
#[context("Getting bootloader")]
7390
pub(crate) fn get_bootloader() -> Result<Bootloader> {
7491
use crate::efi::get_loader_info;
92+
use std::sync::OnceLock;
7593

7694
static BOOTLOADER: OnceLock<Bootloader> = OnceLock::new();
7795

src/bootupd.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub(crate) fn install(opts: &InstallOpts, devices: &[Device], configs: ConfigMod
9494
anyhow::bail!("No components specified");
9595
}
9696

97+
#[cfg(efi_arch)]
9798
let bootloader = match opts.bootloader {
9899
// CLI overrides anything else
99100
Some(b) => b,
@@ -151,6 +152,9 @@ pub(crate) fn install(opts: &InstallOpts, devices: &[Device], configs: ConfigMod
151152
}
152153
};
153154

155+
#[cfg(not(efi_arch))]
156+
let bootloader = Bootloader::Grub;
157+
154158
let mut state = SavedState::default();
155159
let mut installed_efi_vendor = None;
156160

@@ -300,6 +304,8 @@ fn get_static_config_meta() -> Result<ContentMetadata> {
300304
timestamp: self_bin_meta.modified()?.into(),
301305
version: crate_version!().into(),
302306
versions: None,
307+
308+
#[cfg(efi_arch)]
303309
default_bootloader: None,
304310
};
305311
Ok(self_meta)

src/cli/bootupctl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ pub enum CtlBackend {
7474
#[clap(name = "install", hide = true)]
7575
Install(super::bootupd::InstallOpts),
7676
#[clap(hide = true)]
77+
#[cfg(efi_arch)]
7778
SetDefaultBootloader(super::bootupd::DefaultBootloaderOpts),
7879
}
7980

@@ -111,6 +112,7 @@ impl CtlCommand {
111112
CtlVerb::Backend(CtlBackend::Install(opts)) => {
112113
super::bootupd::DCommand::run_install(opts)
113114
}
115+
#[cfg(efi_arch)]
114116
CtlVerb::Backend(CtlBackend::SetDefaultBootloader(opts)) => {
115117
super::bootupd::DCommand::set_default_bootloader(opts)
116118
}

src/cli/bootupd.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub enum DVerb {
4040
GenerateUpdateMetadata(GenerateOpts),
4141
#[clap(name = "install", about = "Install components")]
4242
Install(InstallOpts),
43+
#[cfg(efi_arch)]
4344
SetDefaultBootloader(DefaultBootloaderOpts),
4445
}
4546

@@ -114,6 +115,7 @@ impl DCommand {
114115
match self.cmd {
115116
DVerb::Install(opts) => Self::run_install(opts),
116117
DVerb::GenerateUpdateMetadata(opts) => Self::run_generate_meta(opts),
118+
#[cfg(efi_arch)]
117119
DVerb::SetDefaultBootloader(opts) => Self::set_default_bootloader(opts),
118120
}
119121
}
@@ -130,12 +132,6 @@ impl DCommand {
130132

131133
/// Runner for `install` verb.
132134
pub(crate) fn run_install(opts: InstallOpts) -> Result<()> {
133-
if !matches!(opts.bootloader, Some(Bootloader::Grub) | None)
134-
&& cfg!(any(target_arch = "powerpc64", target_arch = "s390x"))
135-
{
136-
anyhow::bail!("Only Grub is supported for powerpc64 and s390x");
137-
}
138-
139135
let configmode = if opts.write_uuid {
140136
ConfigMode::WithUUID
141137
} else if opts.with_static_configs {
@@ -162,6 +158,7 @@ impl DCommand {
162158
Ok(())
163159
}
164160

161+
#[cfg(efi_arch)]
165162
pub(crate) fn set_default_bootloader(opts: DefaultBootloaderOpts) -> Result<()> {
166163
let all_components = crate::bootupd::get_components();
167164
let target_components: Vec<_> = all_components.values().collect();

src/component.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::path::{Path, PathBuf};
1414

1515
use bootc_internal_blockdev::Device;
1616

17+
#[cfg(efi_arch)]
1718
use crate::cli::bootupd::DefaultBootloaderOpts;
1819
use crate::{bootloader::Bootloader, bootupd::RootContext, model::*};
1920

@@ -141,6 +142,7 @@ pub(crate) trait Component {
141142
Path::new(&format!("{}.json", self.name())).into()
142143
}
143144

145+
#[cfg(efi_arch)]
144146
fn set_default_bootloader(&self, opts: &DefaultBootloaderOpts) -> Result<()> {
145147
if !self.is_bootloader_supported(opts.bootloader) {
146148
anyhow::bail!("{} not supported for {}", opts.bootloader, self.name());
@@ -167,6 +169,7 @@ pub(crate) trait Component {
167169
Ok(())
168170
}
169171

172+
#[cfg(efi_arch)]
170173
fn get_default_bootloader(&self, root: &Dir) -> Result<Option<Bootloader>> {
171174
let update_meta = self
172175
.get_component_update(&root, None)?
@@ -242,6 +245,7 @@ pub(crate) fn query_adopt_state() -> Result<Option<Adoptable>> {
242245
timestamp: coreos_aleph.ts,
243246
version: coreos_aleph.aleph.version,
244247
versions: None,
248+
#[cfg(efi_arch)]
245249
default_bootloader: None,
246250
};
247251
log::trace!("Adoptable: {:?}", &meta);
@@ -260,6 +264,7 @@ pub(crate) fn query_adopt_state() -> Result<Option<Adoptable>> {
260264
timestamp,
261265
version: "unknown".to_string(),
262266
versions: None,
267+
#[cfg(efi_arch)]
263268
default_bootloader: None,
264269
};
265270
return Ok(Some(Adoptable {
@@ -273,7 +278,6 @@ pub(crate) fn query_adopt_state() -> Result<Option<Adoptable>> {
273278
#[cfg(test)]
274279
mod tests {
275280
use cap_std::fs::{DirBuilder, DirBuilderExt, Permissions, PermissionsExt};
276-
use chrono::Utc;
277281

278282
use super::*;
279283

@@ -353,7 +357,10 @@ mod tests {
353357
}
354358

355359
#[test]
360+
#[cfg(efi_arch)]
356361
fn test_set_default_bootloader() -> Result<()> {
362+
use chrono::Utc;
363+
357364
let td = tempfile::tempdir()?;
358365
let sysroot = td.path().to_str().unwrap().to_string();
359366
let tdir = Dir::open_ambient_dir(&sysroot, ambient_authority())?;

src/efi.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,10 @@ impl Component for Efi {
323323
}
324324

325325
fn is_bootloader_supported(&self, bootloader: Bootloader) -> bool {
326+
#[cfg(not(efi_arch))]
327+
return matches!(bootloader, Bootloader::Grub);
328+
329+
#[cfg(efi_arch)]
326330
matches!(
327331
bootloader,
328332
Bootloader::Grub | Bootloader::GrubCC | Bootloader::SystemdBoot
@@ -883,6 +887,7 @@ fn generate_meta_from_usr_efi(sysroot_path: &Utf8Path) -> Result<ContentMetadata
883887
timestamp: get_metadata_timestamp()?,
884888
version: packages.join(","),
885889
versions: Some(modules_vec),
890+
#[cfg(efi_arch)]
886891
default_bootloader: None,
887892
};
888893

@@ -1117,6 +1122,7 @@ Boot0003* test";
11171122
}
11181123

11191124
#[test]
1125+
#[cfg(efi_arch)]
11201126
fn test_get_efi_component_from_usr() -> Result<()> {
11211127
let tmpdir: &tempfile::TempDir = &tempfile::tempdir()?;
11221128
let tpath = tmpdir.path();

0 commit comments

Comments
 (0)