aboutsummaryrefslogtreecommitdiff
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
parentd960fb1e49f057ad235be45e4f62080edcedaefe (diff)
save current system time to disk on SIGTERM before exiting
-rw-r--r--Cargo.lock23
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs54
3 files changed, 66 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index aa36b98..4a707f4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -552,6 +552,7 @@ dependencies = [
"ntp",
"rsdsl_ip_config",
"thiserror",
+ "tokio",
"trust-dns-resolver",
]
@@ -635,6 +636,15 @@ dependencies = [
]
[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -744,11 +754,24 @@ dependencies = [
"mio",
"num_cpus",
"pin-project-lite",
+ "signal-hook-registry",
"socket2 0.4.9",
+ "tokio-macros",
"windows-sys",
]
[[package]]
+name = "tokio-macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index ebd214f..e4a002f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,6 +11,7 @@ nix = { version = "0.26.2", features = ["time"] }
ntp = "0.5.0"
rsdsl_ip_config = { git = "https://github.com/rsdsl/ip_config.git", version = "0.2.4" }
thiserror = "1.0"
+tokio = { version = "1.0", features = ["rt", "macros", "time", "fs", "signal"] }
trust-dns-resolver = "0.23.0"
[build-dependencies]
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(())