Skip to content

Commit 45dcab6

Browse files
committed
adopt_update: pass RootContext as parameter
1 parent 0eb1e31 commit 45dcab6

File tree

4 files changed

+55
-22
lines changed

4 files changed

+55
-22
lines changed

src/bios.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ impl Bios {
9797
}
9898

9999
// check bios_boot partition on gpt type disk
100+
#[allow(dead_code)]
100101
fn get_bios_boot_partition(&self) -> Option<String> {
101102
match blockdev::get_single_device("/") {
102103
Ok(device) => {
@@ -147,24 +148,37 @@ impl Component for Bios {
147148
Ok(meta)
148149
}
149150

150-
fn query_adopt(&self) -> Result<Option<Adoptable>> {
151+
fn query_adopt(&self, devices: &Option<Vec<String>>) -> Result<Option<Adoptable>> {
151152
#[cfg(target_arch = "x86_64")]
152-
if crate::efi::is_efi_booted()? && self.get_bios_boot_partition().is_none() {
153+
if crate::efi::is_efi_booted()? && devices.is_none() {
153154
log::debug!("Skip BIOS adopt");
154155
return Ok(None);
155156
}
156157
crate::component::query_adopt_state()
157158
}
158159

159-
fn adopt_update(&self, _: &openat::Dir, update: &ContentMetadata) -> Result<InstalledContent> {
160-
let Some(meta) = self.query_adopt()? else {
160+
fn adopt_update(
161+
&self,
162+
sysroot: &RootContext,
163+
update: &ContentMetadata,
164+
) -> Result<InstalledContent> {
165+
let bios_devices = blockdev::find_colocated_bios_boot(&sysroot.devices)?;
166+
let Some(meta) = self.query_adopt(&bios_devices)? else {
161167
anyhow::bail!("Failed to find adoptable system")
162168
};
163169

164-
let target_root = "/";
165-
let device = blockdev::get_single_device(&target_root)?;
166-
self.run_grub_install(target_root, &device)?;
167-
log::debug!("Install grub modules on {device}");
170+
let mut parent_devices = sysroot.devices.iter();
171+
let Some(parent) = parent_devices.next() else {
172+
anyhow::bail!("Failed to find parent device");
173+
};
174+
175+
if let Some(next) = parent_devices.next() {
176+
anyhow::bail!(
177+
"Found multiple parent devices {parent} and {next}; not currently supported"
178+
);
179+
}
180+
self.run_grub_install(sysroot.path.as_str(), &parent)?;
181+
log::debug!("Install grub modules on {parent}");
168182
Ok(InstalledContent {
169183
meta: update.clone(),
170184
filetree: None,

src/bootupd.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ pub(crate) fn adopt_and_update(name: &str, rootcxt: &RootContext) -> Result<Cont
276276
SavedState::acquire_write_lock(sysroot).context("Failed to acquire write lock")?;
277277

278278
let inst = component
279-
.adopt_update(&state_guard.sysroot, &update)
279+
.adopt_update(&rootcxt, &update)
280280
.context("Failed adopt and update")?;
281281
state.installed.insert(component.name().into(), inst);
282282

@@ -327,8 +327,10 @@ pub(crate) fn status() -> Result<Status> {
327327

328328
// Process the remaining components not installed
329329
log::trace!("Remaining known components: {}", known_components.len());
330-
for (name, component) in known_components {
331-
if let Some(adopt_ver) = component.query_adopt()? {
330+
for (name, _) in known_components {
331+
// Only run `query_adopt_state()` is enough
332+
// When do adopt and update for each component, will check more
333+
if let Some(adopt_ver) = crate::component::query_adopt_state()? {
332334
ret.adoptable.insert(name.to_string(), adopt_ver);
333335
} else {
334336
log::trace!("Not adoptable: {}", name);

src/component.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ pub(crate) trait Component {
2929
/// In an operating system whose initially booted disk image is not
3030
/// using bootupd, detect whether it looks like the component exists
3131
/// and "synthesize" content metadata from it.
32-
fn query_adopt(&self) -> Result<Option<Adoptable>>;
32+
fn query_adopt(&self, devices: &Option<Vec<String>>) -> Result<Option<Adoptable>>;
3333

3434
/// Given an adoptable system and an update, perform the update.
3535
fn adopt_update(
3636
&self,
37-
sysroot: &openat::Dir,
37+
sysroot: &RootContext,
3838
update: &ContentMetadata,
3939
) -> Result<InstalledContent>;
4040

src/efi.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,8 @@ impl Component for Efi {
264264
"EFI"
265265
}
266266

267-
fn query_adopt(&self) -> Result<Option<Adoptable>> {
268-
let esp = self.open_esp_optional()?;
269-
if esp.is_none() {
267+
fn query_adopt(&self, devices: &Option<Vec<String>>) -> Result<Option<Adoptable>> {
268+
if devices.is_none() {
270269
log::trace!("No ESP detected");
271270
return Ok(None);
272271
};
@@ -282,23 +281,41 @@ impl Component for Efi {
282281
/// Given an adoptable system and an update, perform the update.
283282
fn adopt_update(
284283
&self,
285-
sysroot: &openat::Dir,
284+
sysroot: &RootContext,
286285
updatemeta: &ContentMetadata,
287286
) -> Result<InstalledContent> {
288-
let Some(meta) = self.query_adopt()? else {
287+
let esp_devices = blockdev::find_colocated_esps(&sysroot.devices)?;
288+
let Some(meta) = self.query_adopt(&esp_devices)? else {
289289
anyhow::bail!("Failed to find adoptable system")
290290
};
291291

292-
let esp = self.open_esp()?;
293-
validate_esp(&esp)?;
292+
// Confirm that esp_devices is Some(value)
293+
let esp_devices = esp_devices.unwrap();
294+
let mut devices = esp_devices.iter();
295+
let Some(esp) = devices.next() else {
296+
anyhow::bail!("Failed to find esp device");
297+
};
298+
299+
if let Some(next_esp) = devices.next() {
300+
anyhow::bail!(
301+
"Found multiple esp devices {esp} and {next_esp}; not currently supported"
302+
);
303+
}
304+
let destpath = &self.ensure_mounted_esp(sysroot.path.as_ref(), Path::new(&esp))?;
305+
306+
let destdir = &openat::Dir::open(&destpath.join("EFI"))
307+
.with_context(|| format!("opening EFI dir {}", destpath.display()))?;
308+
validate_esp(&destdir)?;
294309
let updated = sysroot
310+
.sysroot
295311
.sub_dir(&component_updatedirname(self))
296312
.context("opening update dir")?;
297313
let updatef = filetree::FileTree::new_from_dir(&updated).context("reading update dir")?;
298314
// For adoption, we should only touch files that we know about.
299-
let diff = updatef.relative_diff_to(&esp)?;
315+
let diff = updatef.relative_diff_to(&destdir)?;
300316
log::trace!("applying adoption diff: {}", &diff);
301-
filetree::apply_diff(&updated, &esp, &diff, None).context("applying filesystem changes")?;
317+
filetree::apply_diff(&updated, &destdir, &diff, None)
318+
.context("applying filesystem changes")?;
302319
Ok(InstalledContent {
303320
meta: updatemeta.clone(),
304321
filetree: Some(updatef),

0 commit comments

Comments
 (0)