aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2023-11-13 19:02:48 +0100
committerHimbeerserverDE <himbeerserverde@gmail.com>2023-11-13 19:02:48 +0100
commit6af5eb82bfd23842f33b8cf46c207845f1b88fa7 (patch)
tree30a3a23ba43e72b4dab823deaa0c93db165f6547 /src
parentd960fb1e49f057ad235be45e4f62080edcedaefe (diff)
save current system time to disk on SIGTERM before exiting
Diffstat (limited to 'src')
-rw-r--r--src/main.rs54
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(())