|
29 | 29 | #include "time-util.h" |
30 | 30 | #include "timesyncd-conf.h" |
31 | 31 | #include "timesyncd-manager.h" |
| 32 | +#include "user-util.h" |
32 | 33 | #include "util.h" |
33 | 34 |
|
34 | 35 | #ifndef ADJ_SETOFFSET |
@@ -60,7 +61,7 @@ static int manager_arm_timer(Manager *m, usec_t next); |
60 | 61 | static int manager_clock_watch_setup(Manager *m); |
61 | 62 | static int manager_listen_setup(Manager *m); |
62 | 63 | static void manager_listen_stop(Manager *m); |
63 | | -static int manager_save_time_and_rearm(Manager *m); |
| 64 | +static int manager_save_time_and_rearm(Manager *m, usec_t t); |
64 | 65 |
|
65 | 66 | static double ntp_ts_short_to_d(const struct ntp_ts_short *ts) { |
66 | 67 | return be16toh(ts->sec) + (be16toh(ts->frac) / 65536.0); |
@@ -411,6 +412,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re |
411 | 412 | .msg_namelen = sizeof(server_addr), |
412 | 413 | }; |
413 | 414 | struct timespec *recv_time = NULL; |
| 415 | + triple_timestamp dts; |
414 | 416 | ssize_t len; |
415 | 417 | double origin, receive, trans, dest, delay, offset, root_distance; |
416 | 418 | bool spike; |
@@ -564,12 +566,18 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re |
564 | 566 | m->samples_jitter, spike ? " spike" : "", |
565 | 567 | m->poll_interval_usec / USEC_PER_SEC); |
566 | 568 |
|
| 569 | + /* Get current monotonic/realtime clocks immediately before adjusting the latter */ |
| 570 | + triple_timestamp_get(&dts); |
| 571 | + |
567 | 572 | if (!spike) { |
| 573 | + /* Fix up our idea of the time. */ |
| 574 | + dts.realtime = (usec_t) (dts.realtime + offset * USEC_PER_SEC); |
| 575 | + |
568 | 576 | r = manager_adjust_clock(m, offset, leap_sec); |
569 | 577 | if (r < 0) |
570 | 578 | log_error_errno(r, "Failed to call clock_adjtime(): %m"); |
571 | 579 |
|
572 | | - (void) manager_save_time_and_rearm(m); |
| 580 | + (void) manager_save_time_and_rearm(m, dts.realtime); |
573 | 581 |
|
574 | 582 | /* If touch fails, there isn't much we can do. Maybe it'll work next time. */ |
575 | 583 | (void) touch("/run/systemd/timesync/synchronized"); |
@@ -1124,7 +1132,7 @@ static int manager_save_time_handler(sd_event_source *s, uint64_t usec, void *us |
1124 | 1132 |
|
1125 | 1133 | assert(m); |
1126 | 1134 |
|
1127 | | - (void) manager_save_time_and_rearm(m); |
| 1135 | + (void) manager_save_time_and_rearm(m, USEC_INFINITY); |
1128 | 1136 | return 0; |
1129 | 1137 | } |
1130 | 1138 |
|
@@ -1152,12 +1160,16 @@ int manager_setup_save_time_event(Manager *m) { |
1152 | 1160 | return 0; |
1153 | 1161 | } |
1154 | 1162 |
|
1155 | | -static int manager_save_time_and_rearm(Manager *m) { |
| 1163 | +static int manager_save_time_and_rearm(Manager *m, usec_t t) { |
1156 | 1164 | int r; |
1157 | 1165 |
|
1158 | 1166 | assert(m); |
1159 | 1167 |
|
1160 | | - r = touch(CLOCK_FILE); |
| 1168 | + /* Updates the timestamp file to the specified time. If 't' is USEC_INFINITY uses the current system |
| 1169 | + * clock, but otherwise uses the specified timestamp. Note that whenever we acquire an NTP sync the |
| 1170 | + * specified timestamp value might be more accurate than the system clock, since the latter is |
| 1171 | + * subject to slow adjustments. */ |
| 1172 | + r = touch_file(CLOCK_FILE, false, t, UID_INVALID, GID_INVALID, MODE_INVALID); |
1161 | 1173 | if (r < 0) |
1162 | 1174 | log_debug_errno(r, "Failed to update " CLOCK_FILE ", ignoring: %m"); |
1163 | 1175 |
|
|
0 commit comments