diff --git a/openapi/sled-agent.json b/openapi/sled-agent.json index c33653c468..3e7ec3b5e5 100644 --- a/openapi/sled-agent.json +++ b/openapi/sled-agent.json @@ -2755,6 +2755,17 @@ "format": "uint32", "minimum": 0 }, + "ref_time": { + "description": "The NTP reference time (i.e. what chrony thinks the current time is, not necessarily the current system time).", + "type": "number", + "format": "double" + }, + "stratum": { + "description": "The NTP stratum (our upstream's stratum plus one).", + "type": "integer", + "format": "uint8", + "minimum": 0 + }, "sync": { "description": "The synchronization state of the sled, true when the system clock and the NTP clock are in sync (to within a small window).", "type": "boolean" @@ -2764,6 +2775,8 @@ "correction", "ip_addr", "ref_id", + "ref_time", + "stratum", "sync" ] }, diff --git a/sled-agent/src/params.rs b/sled-agent/src/params.rs index 5ef9594a2a..d0fa2fbe4d 100644 --- a/sled-agent/src/params.rs +++ b/sled-agent/src/params.rs @@ -855,6 +855,11 @@ pub struct TimeSync { pub ref_id: u32, /// The NTP reference IP address. pub ip_addr: IpAddr, + /// The NTP stratum (our upstream's stratum plus one). + pub stratum: u8, + /// The NTP reference time (i.e. what chrony thinks the current time is, not + /// necessarily the current system time). + pub ref_time: f64, // This could be f32, but there is a problem with progenitor/typify // where, although the f32 correctly becomes "float" (and not "double") in // the API spec, that "float" gets converted back to f64 when generating diff --git a/sled-agent/src/rack_setup/service.rs b/sled-agent/src/rack_setup/service.rs index d127512aa6..805c889295 100644 --- a/sled-agent/src/rack_setup/service.rs +++ b/sled-agent/src/rack_setup/service.rs @@ -455,6 +455,8 @@ impl ServiceInner { sync: ts.sync, ref_id: ts.ref_id, ip_addr: ts.ip_addr, + stratum: ts.stratum, + ref_time: ts.ref_time, correction: ts.correction, }) } diff --git a/sled-agent/src/services.rs b/sled-agent/src/services.rs index ceda5c75b7..9868bb4f0d 100644 --- a/sled-agent/src/services.rs +++ b/sled-agent/src/services.rs @@ -2373,6 +2373,8 @@ impl ServiceManager { sync: true, ref_id: 0, ip_addr: IPV6_UNSPECIFIED, + stratum: 0, + ref_time: 0.0, correction: 0.00, }); }; @@ -2401,6 +2403,10 @@ impl ServiceManager { .map_err(|_| Error::NtpZoneNotReady)?; let ip_addr = IpAddr::from_str(v[1]).unwrap_or(IPV6_UNSPECIFIED); + let stratum = u8::from_str(v[2]) + .map_err(|_| Error::NtpZoneNotReady)?; + let ref_time = f64::from_str(v[3]) + .map_err(|_| Error::NtpZoneNotReady)?; let correction = f64::from_str(v[4]) .map_err(|_| Error::NtpZoneNotReady)?; @@ -2410,13 +2416,23 @@ impl ServiceManager { let peer_sync = !ip_addr.is_unspecified() || (ref_id != 0 && ref_id != 0x7f7f0101); - let sync = peer_sync && correction.abs() <= 0.05; + let sync = stratum < 10 + && ref_time > 1234567890.0 + && peer_sync + && correction.abs() <= 0.05; if sync { self.boottime_rewrite(existing_zones.values()); } - Ok(TimeSync { sync, ref_id, ip_addr, correction }) + Ok(TimeSync { + sync, + ref_id, + ip_addr, + stratum, + ref_time, + correction, + }) } else { Err(Error::NtpZoneNotReady) }