diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-11-13 19:02:48 +0100 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-11-13 19:02:48 +0100 |
commit | 6af5eb82bfd23842f33b8cf46c207845f1b88fa7 (patch) | |
tree | 30a3a23ba43e72b4dab823deaa0c93db165f6547 /src | |
parent | d960fb1e49f057ad235be45e4f62080edcedaefe (diff) |
save current system time to disk on SIGTERM before exiting
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/src/main.rs b/src/main.rs index dd0da4d..8619555 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ -use std::fs; use std::io; use std::net::{self, IpAddr, SocketAddr}; +use std::num; use std::path::Path; use std::thread; -use std::time::Duration; +use std::time::{self, Duration, SystemTime}; + +use tokio::fs; +use tokio::signal::unix::{signal, SignalKind}; use chrono::DateTime; use nix::sys::time::TimeSpec; @@ -27,6 +30,10 @@ enum Error { Io(#[from] io::Error), #[error("can't parse network address: {0}")] ParseAddr(#[from] net::AddrParseError), + #[error("system time monotonicity error: {0}")] + SystemTime(#[from] time::SystemTimeError), + #[error("integer doesn't fit: {0}")] + TryFromInt(#[from] num::TryFromIntError), #[error("chrono parse: {0}")] ChronoParse(#[from] chrono::ParseError), @@ -40,31 +47,54 @@ enum Error { type Result<T> = std::result::Result<T, Error>; -fn main() -> Result<()> { +#[tokio::main] +async fn main() -> Result<()> { let ds_config = Path::new(rsdsl_ip_config::LOCATION); while !ds_config.exists() { println!("wait for pppoe"); thread::sleep(Duration::from_secs(8)); } + let mut resync = tokio::time::interval(INTERVAL); + let mut sigterm = signal(SignalKind::terminate())?; + loop { - match sync_time(NTP_SERVER) { - Ok(_) => {} - Err(e) => eprintln!("can't synchronize system time: {}", e), + tokio::select! { + _ = resync.tick() => match sync_time(NTP_SERVER).await { + Ok(_) => {} + Err(e) => eprintln!("can't synchronize system time: {}", e), + }, + _ = sigterm.recv() => { + sysnow_to_disk().await?; + + println!("save system time"); + return Ok(()); + } } - - thread::sleep(INTERVAL); } } -fn last_time_unix() -> Option<i64> { +async fn last_time_unix() -> Option<i64> { Some(i64::from_be_bytes( - fs::read("/data/ntp.last_unix").ok()?[..8].try_into().ok()?, + fs::read("/data/ntp.last_unix").await.ok()?[..8] + .try_into() + .ok()?, )) } -fn sync_time(server: &str) -> Result<()> { +async fn sysnow_to_disk() -> Result<()> { + let t: i64 = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH)? + .as_secs() + .try_into()?; + fs::write("/data/ntp.last_unix", t.to_be_bytes()).await?; + + Ok(()) +} + +async fn sync_time(server: &str) -> Result<()> { let last = last_time_unix() + .await .unwrap_or(DateTime::parse_from_rfc3339(env!("SOURCE_TIMESTAMP"))?.timestamp()); let dns = DNS_SERVER.parse()?; @@ -80,7 +110,7 @@ fn sync_time(server: &str) -> Result<()> { let timespec = TimeSpec::new(t, 0); nix::time::clock_settime(ClockId::CLOCK_REALTIME, timespec)?; - fs::write("/data/ntp.last_unix", t.to_be_bytes())?; + fs::write("/data/ntp.last_unix", t.to_be_bytes()).await?; println!("set system time"); Ok(()) |