mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 16:59:03 +03:00
timesync: save and expose NTP responce on bus
This commit is contained in:
parent
c583dd564c
commit
66086a4030
@ -10,6 +10,7 @@ systemd_timesyncd_sources = files('''
|
||||
timesyncd-conf.h
|
||||
timesyncd-manager.c
|
||||
timesyncd-manager.h
|
||||
timesyncd-ntp-message.h
|
||||
timesyncd-server.c
|
||||
timesyncd-server.h
|
||||
'''.split())
|
||||
|
@ -95,6 +95,62 @@ static int property_get_current_server_address(
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static usec_t ntp_ts_short_to_usec(const struct ntp_ts_short *ts) {
|
||||
return be16toh(ts->sec) * USEC_PER_SEC + (be16toh(ts->frac) * USEC_PER_SEC) / (usec_t) 0x10000ULL;
|
||||
}
|
||||
|
||||
static usec_t ntp_ts_to_usec(const struct ntp_ts *ts) {
|
||||
return (be32toh(ts->sec) - OFFSET_1900_1970) * USEC_PER_SEC + (be32toh(ts->frac) * USEC_PER_SEC) / (usec_t) 0x100000000ULL;
|
||||
}
|
||||
|
||||
static int property_get_ntp_message(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = userdata;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(reply);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'r', "uuuuittayttttbtt");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(reply, "uuuuitt",
|
||||
NTP_FIELD_LEAP(m->ntpmsg.field),
|
||||
NTP_FIELD_VERSION(m->ntpmsg.field),
|
||||
NTP_FIELD_MODE(m->ntpmsg.field),
|
||||
m->ntpmsg.stratum,
|
||||
m->ntpmsg.precision,
|
||||
ntp_ts_short_to_usec(&m->ntpmsg.root_delay),
|
||||
ntp_ts_short_to_usec(&m->ntpmsg.root_dispersion));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append_array(reply, 'y', m->ntpmsg.refid, 4);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append(reply, "ttttbtt",
|
||||
timespec_load(&m->origin_time),
|
||||
ntp_ts_to_usec(&m->ntpmsg.recv_time),
|
||||
ntp_ts_to_usec(&m->ntpmsg.trans_time),
|
||||
timespec_load(&m->dest_time),
|
||||
m->spike,
|
||||
m->packet_count,
|
||||
(usec_t) (m->samples_jitter * USEC_PER_SEC));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
@ -107,6 +163,8 @@ static const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("PollIntervalMinUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_min_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("PollIntervalMaxUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("PollIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_usec), 0),
|
||||
SD_BUS_PROPERTY("NTPMessage", "(uuuuittayttttbtt)", property_get_ntp_message, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Frequency", "x", NULL, offsetof(Manager, drift_freq), 0),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "network-util.h"
|
||||
#include "ratelimit.h"
|
||||
#include "socket-util.h"
|
||||
#include "sparse-endian.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "time-util.h"
|
||||
@ -50,59 +49,18 @@
|
||||
*/
|
||||
#define NTP_MAX_ADJUST 0.4
|
||||
|
||||
/* NTP protocol, packet header */
|
||||
#define NTP_LEAP_PLUSSEC 1
|
||||
#define NTP_LEAP_MINUSSEC 2
|
||||
#define NTP_LEAP_NOTINSYNC 3
|
||||
#define NTP_MODE_CLIENT 3
|
||||
#define NTP_MODE_SERVER 4
|
||||
#define NTP_FIELD_LEAP(f) (((f) >> 6) & 3)
|
||||
#define NTP_FIELD_VERSION(f) (((f) >> 3) & 7)
|
||||
#define NTP_FIELD_MODE(f) ((f) & 7)
|
||||
#define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
|
||||
|
||||
/* Default of maximum acceptable root distance in microseconds. */
|
||||
#define NTP_MAX_ROOT_DISTANCE (5 * USEC_PER_SEC)
|
||||
|
||||
/* Maximum number of missed replies before selecting another source. */
|
||||
#define NTP_MAX_MISSED_REPLIES 2
|
||||
|
||||
/*
|
||||
* "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
|
||||
* in seconds relative to 0h on 1 January 1900."
|
||||
*/
|
||||
#define OFFSET_1900_1970 UINT64_C(2208988800)
|
||||
|
||||
#define RETRY_USEC (30*USEC_PER_SEC)
|
||||
#define RATELIMIT_INTERVAL_USEC (10*USEC_PER_SEC)
|
||||
#define RATELIMIT_BURST 10
|
||||
|
||||
#define TIMEOUT_USEC (10*USEC_PER_SEC)
|
||||
|
||||
struct ntp_ts {
|
||||
be32_t sec;
|
||||
be32_t frac;
|
||||
} _packed_;
|
||||
|
||||
struct ntp_ts_short {
|
||||
be16_t sec;
|
||||
be16_t frac;
|
||||
} _packed_;
|
||||
|
||||
struct ntp_msg {
|
||||
uint8_t field;
|
||||
uint8_t stratum;
|
||||
int8_t poll;
|
||||
int8_t precision;
|
||||
struct ntp_ts_short root_delay;
|
||||
struct ntp_ts_short root_dispersion;
|
||||
char refid[4];
|
||||
struct ntp_ts reference_time;
|
||||
struct ntp_ts origin_time;
|
||||
struct ntp_ts recv_time;
|
||||
struct ntp_ts trans_time;
|
||||
} _packed_;
|
||||
|
||||
static int manager_arm_timer(Manager *m, usec_t next);
|
||||
static int manager_clock_watch_setup(Manager *m);
|
||||
static int manager_listen_setup(Manager *m);
|
||||
@ -357,18 +315,18 @@ static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
|
||||
(void) touch("/var/lib/systemd/timesync/clock");
|
||||
(void) touch("/run/systemd/timesync/synchronized");
|
||||
|
||||
m->drift_ppm = tmx.freq / 65536;
|
||||
m->drift_freq = tmx.freq;
|
||||
|
||||
log_debug(" status : %04i %s\n"
|
||||
" time now : %"PRI_TIME".%03"PRI_USEC"\n"
|
||||
" constant : %"PRI_TIMEX"\n"
|
||||
" offset : %+.3f sec\n"
|
||||
" freq offset : %+"PRI_TIMEX" (%i ppm)\n",
|
||||
" freq offset : %+"PRI_TIMEX" (%+"PRI_TIMEX" ppm)\n",
|
||||
tmx.status, tmx.status & STA_UNSYNC ? "unsync" : "sync",
|
||||
tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
|
||||
tmx.constant,
|
||||
(double)tmx.offset / NSEC_PER_SEC,
|
||||
tmx.freq, m->drift_ppm);
|
||||
tmx.freq, tmx.freq / 65536);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -652,10 +610,18 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
||||
log_error_errno(r, "Failed to call clock_adjtime(): %m");
|
||||
}
|
||||
|
||||
log_debug("interval/delta/delay/jitter/drift " USEC_FMT "s/%+.3fs/%.3fs/%.3fs/%+ippm%s",
|
||||
m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
|
||||
/* Save NTP response */
|
||||
m->ntpmsg = ntpmsg;
|
||||
m->origin_time = m->trans_time;
|
||||
m->dest_time = *recv_time;
|
||||
m->spike = spike;
|
||||
|
||||
log_debug("interval/delta/delay/jitter/drift " USEC_FMT "s/%+.3fs/%.3fs/%.3fs/%+"PRI_TIMEX"ppm%s",
|
||||
m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_freq / 65536,
|
||||
spike ? " (ignored)" : "");
|
||||
|
||||
(void) sd_bus_emit_properties_changed(m->bus, "/org/freedesktop/timesync1", "org.freedesktop.timesync1.Manager", "NTPMessage", NULL);
|
||||
|
||||
if (!m->good) {
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
Copyright 2014 Kay Sievers, Lennart Poettering
|
||||
***/
|
||||
|
||||
#include <sys/timex.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-event.h"
|
||||
#include "sd-network.h"
|
||||
@ -15,6 +17,7 @@
|
||||
#include "list.h"
|
||||
#include "ratelimit.h"
|
||||
#include "time-util.h"
|
||||
#include "timesyncd-ntp-message.h"
|
||||
|
||||
typedef struct Manager Manager;
|
||||
|
||||
@ -81,7 +84,7 @@ struct Manager {
|
||||
/* last change */
|
||||
bool jumped;
|
||||
bool sync;
|
||||
int drift_ppm;
|
||||
long drift_freq;
|
||||
|
||||
/* watch for time changes */
|
||||
sd_event_source *event_clock_watch;
|
||||
@ -92,6 +95,11 @@ struct Manager {
|
||||
|
||||
/* RTC runs in local time, leave it alone */
|
||||
bool rtc_local_time;
|
||||
|
||||
/* NTP response */
|
||||
struct ntp_msg ntpmsg;
|
||||
struct timespec origin_time, dest_time;
|
||||
bool spike;
|
||||
};
|
||||
|
||||
int manager_new(Manager **ret);
|
||||
|
45
src/timesync/timesyncd-ntp-message.h
Normal file
45
src/timesync/timesyncd-ntp-message.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include "sparse-endian.h"
|
||||
|
||||
/* NTP protocol, packet header */
|
||||
#define NTP_LEAP_PLUSSEC 1
|
||||
#define NTP_LEAP_MINUSSEC 2
|
||||
#define NTP_LEAP_NOTINSYNC 3
|
||||
#define NTP_MODE_CLIENT 3
|
||||
#define NTP_MODE_SERVER 4
|
||||
#define NTP_FIELD_LEAP(f) (((f) >> 6) & 3)
|
||||
#define NTP_FIELD_VERSION(f) (((f) >> 3) & 7)
|
||||
#define NTP_FIELD_MODE(f) ((f) & 7)
|
||||
#define NTP_FIELD(l, v, m) (((l) << 6) | ((v) << 3) | (m))
|
||||
|
||||
/*
|
||||
* "NTP timestamps are represented as a 64-bit unsigned fixed-point number,
|
||||
* in seconds relative to 0h on 1 January 1900."
|
||||
*/
|
||||
#define OFFSET_1900_1970 UINT64_C(2208988800)
|
||||
|
||||
struct ntp_ts {
|
||||
be32_t sec;
|
||||
be32_t frac;
|
||||
} _packed_;
|
||||
|
||||
struct ntp_ts_short {
|
||||
be16_t sec;
|
||||
be16_t frac;
|
||||
} _packed_;
|
||||
|
||||
struct ntp_msg {
|
||||
uint8_t field;
|
||||
uint8_t stratum;
|
||||
int8_t poll;
|
||||
int8_t precision;
|
||||
struct ntp_ts_short root_delay;
|
||||
struct ntp_ts_short root_dispersion;
|
||||
char refid[4];
|
||||
struct ntp_ts reference_time;
|
||||
struct ntp_ts origin_time;
|
||||
struct ntp_ts recv_time;
|
||||
struct ntp_ts trans_time;
|
||||
} _packed_;
|
Loading…
Reference in New Issue
Block a user