fix: shutdown order (#3073)

* fix: race condition in Daemon.stop()

* fix: do not stop Daemon on context leave

* fix: remove duplicate Daemons.term calls

* feat: honor dependency order when shutting terminating Daemons

* fixes, and remove started

---------

Co-authored-by: Aiden McClelland <me@drbonez.dev>
This commit is contained in:
Remco Ros
2025-12-15 23:21:23 +01:00
committed by GitHub
parent 0430e0f930
commit 9c43c43a46
14 changed files with 131 additions and 100 deletions

View File

@@ -53,16 +53,22 @@ pub fn kill_init(procfs: &Path, chroot: &Path) -> Result<(), Error> {
)
})?;
if pids.0.len() == 2 && pids.0[1] == 1 {
nix::sys::signal::kill(Pid::from_raw(pid), nix::sys::signal::SIGKILL)
.with_ctx(|_| {
(
ErrorKind::Filesystem,
lazy_format!(
"kill pid {} (determined to be pid 1 in subcontainer)",
pid
),
)
})?;
match nix::sys::signal::kill(
Pid::from_raw(pid),
Some(nix::sys::signal::SIGKILL),
) {
Err(Errno::ESRCH) => Ok(()),
a => a,
}
.with_ctx(|_| {
(
ErrorKind::Filesystem,
lazy_format!(
"kill pid {} (determined to be pid 1 in subcontainer)",
pid
),
)
})?;
}
}
}
@@ -510,10 +516,13 @@ pub fn exec(
std::thread::spawn(move || {
if let Ok(pid) = recv_pid.blocking_recv() {
for sig in sig.forever() {
nix::sys::signal::kill(
match nix::sys::signal::kill(
Pid::from_raw(pid),
Some(nix::sys::signal::Signal::try_from(sig).unwrap()),
)
) {
Err(Errno::ESRCH) => Ok(()),
a => a,
}
.unwrap();
}
}

View File

@@ -29,7 +29,25 @@ impl ServiceActorSeed {
pub fn start(&self) -> Transition<'_> {
Transition {
kind: TransitionKind::Starting,
future: self.persistent_container.start().boxed(),
future: async {
self.persistent_container.start().await?;
let id = &self.id;
self.ctx
.db
.mutate(|db| {
db.as_public_mut()
.as_package_data_mut()
.as_idx_mut(id)
.or_not_found(id)?
.as_status_info_mut()
.started()
})
.await
.result?;
Ok(())
}
.boxed(),
}
}
@@ -47,8 +65,7 @@ impl ServiceActorSeed {
.as_idx_mut(id)
.or_not_found(id)?
.as_status_info_mut()
.as_started_mut()
.ser(&None)
.stopped()
})
.await
.result?;

View File

@@ -28,11 +28,24 @@ impl StatusInfo {
}
}
impl Model<StatusInfo> {
pub fn start(&mut self) -> Result<(), Error> {
self.as_desired_mut().map_mutate(|s| Ok(s.start()))?;
Ok(())
}
pub fn started(&mut self) -> Result<(), Error> {
self.as_started_mut()
.map_mutate(|s| Ok(Some(s.unwrap_or_else(|| Utc::now()))))?;
Ok(())
}
pub fn stop(&mut self) -> Result<(), Error> {
self.as_desired_mut().map_mutate(|s| Ok(s.stop()))?;
self.as_health_mut().ser(&Default::default())?;
Ok(())
}
pub fn stopped(&mut self) -> Result<(), Error> {
self.as_started_mut().ser(&None)?;
Ok(())
}
pub fn init(&mut self) -> Result<(), Error> {
self.as_started_mut().ser(&None)?;
self.as_desired_mut().map_mutate(|s| {