acpid: allow PCI fd replacement; eagerly init AML symbols on sendfd
Closes the v4.0 plan P3 'acpid pci_fd is not registered' item.
Two related defects:
1. scheme.rs::on_sendfd had a one-shot EINVAL when self.pci_fd was
already Some. Combined with the lazy AML context init in
AcpiContext::aml_symbols, this created a permanent failure mode:
- pcid starts AFTER acpid (per the requires_weak chain)
- if a /scheme/acpi/symbols request arrives before pcid's sendfd
reaches acpid, the aml init runs with pci_fd = None and logs
'pci_fd is not registered' at error level
- the resulting aml_context state makes subsequent retries fail
the same way; the next pcid sendfd hits the one-shot EINVAL and
is rejected
- aml stays broken for the entire boot
Fix: allow replacement (warn-and-replace on subsequent sendfd).
Document the bug history inline so a future agent does not 'clean
up' the warn log.
2. aml_physmem.rs::AmlPhysMemHandler::new logged the missing fd at
log::error. Downgrade to log::warn -- the deferred-init path is
normal during the acpid-then-pcid ordering window and an error
level is misleading.
3. scheme.rs::on_sendfd now eagerly calls self.ctx.aml_symbols()
after setting pci_fd, so the symbol cache is built immediately
rather than on the first consumer request. The error path logs
at error level (with Debug-formatted detail because AmlError
does not implement Display), making the failure observable
rather than silently deferred.
Test note: cargo test -p acpid fails to link on the host because
libredox's redox_munmap_v1 is target-only; this is pre-existing
and unrelated to this change. cargo check -p acpid is clean.
This commit is contained in:
@@ -178,7 +178,9 @@ impl AmlPhysMemHandler {
|
|||||||
let pci_fd = if let Some(pci_fd) = pci_fd_opt {
|
let pci_fd = if let Some(pci_fd) = pci_fd_opt {
|
||||||
Some(libredox::Fd::new(pci_fd.raw()))
|
Some(libredox::Fd::new(pci_fd.raw()))
|
||||||
} else {
|
} else {
|
||||||
log::error!("pci_fd is not registered");
|
log::warn!(
|
||||||
|
"acpid: AmlPhysMemHandler created without PCI fd; AML init will retry once pcid sends it via scheme:acpid sendfd"
|
||||||
|
);
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -1070,10 +1070,27 @@ impl SchemeSync for AcpiScheme<'_, '_> {
|
|||||||
}
|
}
|
||||||
let new_fd = libredox::Fd::new(new_fd);
|
let new_fd = libredox::Fd::new(new_fd);
|
||||||
|
|
||||||
|
// Allow replacement: pcid may resend the fd after a restart,
|
||||||
|
// and the previous one-shot EINVAL left aml init permanently
|
||||||
|
// broken if the first sendfd raced with an early aml request.
|
||||||
if self.pci_fd.is_some() {
|
if self.pci_fd.is_some() {
|
||||||
return Err(Error::new(EINVAL));
|
log::warn!(
|
||||||
} else {
|
"acpid: replacing previously-registered PCI fd; AML symbol cache will rebuild on next request"
|
||||||
self.pci_fd = Some(new_fd);
|
);
|
||||||
|
}
|
||||||
|
self.pci_fd = Some(new_fd);
|
||||||
|
|
||||||
|
// Kick aml symbol init now that pci_fd is registered. The
|
||||||
|
// next aml request will either find a working cache or get a
|
||||||
|
// fresh error log here; either way the failure mode is
|
||||||
|
// observable rather than silently deferred to "the next
|
||||||
|
// caller retries".
|
||||||
|
match self.ctx.aml_symbols(self.pci_fd.as_ref()) {
|
||||||
|
Ok(_) => log::info!("acpid: AML symbols initialized on PCI fd registration"),
|
||||||
|
Err(err) => {
|
||||||
|
log::error!("acpid: AML symbol init failed after PCI fd registration");
|
||||||
|
log::error!("acpid: AML error detail: {:?}", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(num_fds)
|
Ok(num_fds)
|
||||||
|
|||||||
Reference in New Issue
Block a user