]> git.proxmox.com Git - proxmox-backup.git/blame - proxmox-restore-daemon/src/proxmox_restore_daemon/watchdog.rs
update to first proxmox crate split
[proxmox-backup.git] / proxmox-restore-daemon / src / proxmox_restore_daemon / watchdog.rs
CommitLineData
a26ebad5
SR
1//! Tokio-based watchdog that shuts down the VM if not pinged for TIMEOUT
2use std::sync::atomic::{AtomicI64, Ordering};
4c1b7761 3
6ef1b649 4use proxmox_time::epoch_i64;
a26ebad5
SR
5
6const TIMEOUT: i64 = 600; // seconds
7static TRIGGERED: AtomicI64 = AtomicI64::new(0);
1fde4167
SR
8static INHIBITORS: AtomicI64 = AtomicI64::new(0);
9
10pub struct WatchdogInhibitor {}
a26ebad5
SR
11
12fn handle_expired() -> ! {
13 use nix::sys::reboot;
14 println!("watchdog expired, shutting down");
15 let err = reboot::reboot(reboot::RebootMode::RB_POWER_OFF).unwrap_err();
16 println!("'reboot' syscall failed: {}", err);
17 std::process::exit(1);
18}
19
20async fn watchdog_loop() {
21 use tokio::time::{sleep, Duration};
22 loop {
23 let remaining = watchdog_remaining();
24 if remaining <= 0 {
25 handle_expired();
26 }
27 sleep(Duration::from_secs(remaining as u64)).await;
28 }
29}
30
31/// Initialize watchdog
32pub fn watchdog_init() {
33 watchdog_ping();
34 tokio::spawn(watchdog_loop());
35}
36
37/// Trigger watchdog keepalive
38pub fn watchdog_ping() {
39 TRIGGERED.fetch_max(epoch_i64(), Ordering::AcqRel);
40}
41
42/// Returns the remaining time before watchdog expiry in seconds
43pub fn watchdog_remaining() -> i64 {
1fde4167
SR
44 if INHIBITORS.load(Ordering::Acquire) > 0 {
45 TIMEOUT
46 } else {
47 TIMEOUT - (epoch_i64() - TRIGGERED.load(Ordering::Acquire))
48 }
49}
50
51/// Returns an object that inhibts watchdog expiry for its lifetime, it will issue a ping on Drop
52pub fn watchdog_inhibit() -> WatchdogInhibitor {
53 let prev = INHIBITORS.fetch_add(1, Ordering::AcqRel);
54 log::info!("Inhibit added: {}", prev + 1);
55 WatchdogInhibitor {}
56}
57
58impl Drop for WatchdogInhibitor {
59 fn drop(&mut self) {
60 watchdog_ping();
61 let prev = INHIBITORS.fetch_sub(1, Ordering::AcqRel);
62 log::info!("Inhibit dropped: {}", prev - 1);
63 }
a26ebad5 64}