Skip to content

Commit

Permalink
Catch and ignore SIGTERM during update operations
Browse files Browse the repository at this point in the history
Since our updates are non-transactional in general, we should
at least be robust against some concurrent invocation of e.g.
`reboot`.

Replaces: coreos#811
Signed-off-by: Colin Walters <walters@verbum.org>
  • Loading branch information
cgwalters committed Jan 8, 2025
1 parent 045f792 commit 1784dde
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ serde_json = "^1.0"
tempfile = "^3.13"
widestring = "1.1.0"
walkdir = "2.3.2"
signal-hook-registry = "1.4.2"

[profile.release]
# We assume we're being delivered via e.g. RPM which supports split debuginfo
Expand Down
23 changes: 23 additions & 0 deletions src/backend/statefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@ use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

/// Suppress SIGTERM while active
// TODO: In theory we could record if we got SIGTERM and exit
// on drop, but in practice we don't care since we're going to exit anyways.
#[derive(Debug)]
struct SignalTerminationGuard(signal_hook_registry::SigId);

impl SignalTerminationGuard {
pub(crate) fn new() -> Result<Self> {
let signal = unsafe { signal_hook_registry::register(libc::SIGTERM, || {})? };
Ok(Self(signal))
}
}

impl Drop for SignalTerminationGuard {
fn drop(&mut self) {
signal_hook_registry::unregister(self.0);
}
}

impl SavedState {
/// System-wide bootupd write lock (relative to sysroot).
const WRITE_LOCK_PATH: &'static str = "run/bootupd-lock";
Expand All @@ -27,6 +46,7 @@ impl SavedState {
lockfile.lock_exclusive()?;
let guard = StateLockGuard {
sysroot,
termguard: Some(SignalTerminationGuard::new()?),
lockfile: Some(lockfile),
};
Ok(guard)
Expand All @@ -37,6 +57,7 @@ impl SavedState {
pub(crate) fn unlocked(sysroot: openat::Dir) -> Result<StateLockGuard> {
Ok(StateLockGuard {
sysroot,
termguard: None,
lockfile: None,
})
}
Expand Down Expand Up @@ -91,6 +112,8 @@ impl SavedState {
pub(crate) struct StateLockGuard {
pub(crate) sysroot: openat::Dir,
#[allow(dead_code)]
termguard: Option<SignalTerminationGuard>,
#[allow(dead_code)]
lockfile: Option<File>,
}

Expand Down

0 comments on commit 1784dde

Please sign in to comment.