]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/timesync/timesyncd.c
2 This file is part of systemd.
4 Copyright 2014 Kay Sievers, Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #include "sd-daemon.h"
23 #include "capability-util.h"
24 #include "clock-util.h"
27 #include "network-util.h"
28 #include "signal-util.h"
29 #include "timesyncd-conf.h"
30 #include "timesyncd-manager.h"
31 #include "user-util.h"
33 static int load_clock_timestamp(uid_t uid
, gid_t gid
) {
34 _cleanup_close_
int fd
= -1;
35 usec_t min
= TIME_EPOCH
* USEC_PER_SEC
;
39 /* Let's try to make sure that the clock is always
40 * monotonically increasing, by saving the clock whenever we
41 * have a new NTP time, or when we shut down, and restoring it
42 * when we start again. This is particularly helpful on
43 * systems lacking a battery backed RTC. We also will adjust
44 * the time to at least the build time of systemd. */
46 fd
= open("/var/lib/systemd/clock", O_RDWR
|O_CLOEXEC
, 0644);
51 /* check if the recorded time is later than the compiled-in one */
54 stamp
= timespec_load(&st
.st_mtim
);
59 /* Try to fix the access mode, so that we can still
60 touch the file after dropping priviliges */
61 (void) fchmod(fd
, 0644);
62 (void) fchown(fd
, uid
, gid
);
65 /* create stamp file with the compiled-in date */
66 (void) touch_file("/var/lib/systemd/clock", true, min
, uid
, gid
, 0644);
68 ct
= now(CLOCK_REALTIME
);
71 char date
[FORMAT_TIMESTAMP_MAX
];
73 log_info("System clock time unset or jumped backwards, restoring from recorded timestamp: %s",
74 format_timestamp(date
, sizeof(date
), min
));
76 if (clock_settime(CLOCK_REALTIME
, timespec_store(&ts
, min
)) < 0)
77 log_error_errno(errno
, "Failed to restore system clock: %m");
83 int main(int argc
, char *argv
[]) {
84 _cleanup_(manager_freep
) Manager
*m
= NULL
;
85 const char *user
= "systemd-timesync";
90 log_set_target(LOG_TARGET_AUTO
);
91 log_set_facility(LOG_CRON
);
92 log_parse_environment();
98 log_error("This program does not take arguments.");
103 r
= get_user_creds(&user
, &uid
, &gid
, NULL
, NULL
);
105 log_error_errno(r
, "Cannot resolve user name %s: %m", user
);
109 r
= load_clock_timestamp(uid
, gid
);
113 r
= drop_privileges(uid
, gid
, (1ULL << CAP_SYS_TIME
));
117 assert_se(sigprocmask_many(SIG_BLOCK
, NULL
, SIGTERM
, SIGINT
, -1) >= 0);
121 log_error_errno(r
, "Failed to allocate manager: %m");
125 if (clock_is_localtime(NULL
) > 0) {
126 log_info("The system is configured to read the RTC time in the local time zone. "
127 "This mode can not be fully supported. All system time to RTC updates are disabled.");
128 m
->rtc_local_time
= true;
131 r
= manager_parse_config_file(m
);
133 log_warning_errno(r
, "Failed to parse configuration file: %m");
135 log_debug("systemd-timesyncd running as pid " PID_FMT
, getpid());
138 "STATUS=Daemon is running");
140 if (network_is_online()) {
141 r
= manager_connect(m
);
146 r
= sd_event_loop(m
->event
);
148 log_error_errno(r
, "Failed to run event loop: %m");
152 /* if we got an authoritative time, store it in the file system */
154 (void) touch("/var/lib/systemd/clock");
156 sd_event_get_exit_code(m
->event
, &r
);
161 "STATUS=Shutting down...");
163 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;