+static int load_clock(uid_t uid, gid_t gid) {
+ usec_t nt = TIME_EPOCH * USEC_PER_SEC, ct;
+ _cleanup_close_ int fd = -1;
+
+ /* Let's try to make sure that the clock is always
+ * monotonically increasing, by saving the clock whenever we
+ * have a new NTP time, or when we shut down, and restoring it
+ * when we start again. This is particularly helpful on
+ * systems lacking a battery backed RTC. We also will adjust
+ * the time to at least the build time of systemd. */
+
+ mkdir_p("/var/lib/systemd", 0755);
+
+ /* First, we try to create the clock file if it doesn't exist yet */
+ fd = open("/var/lib/systemd/clock", O_RDWR|O_CLOEXEC|O_EXCL, 0644);
+ if (fd < 0) {
+
+ fd = open("/var/lib/systemd/clock", O_RDWR|O_CLOEXEC|O_CREAT, 0644);
+ if (fd < 0) {
+ log_error("Failed to create /var/lib/systemd/clock: %m");
+ return -errno;
+ }
+
+ } else {
+ struct stat st;
+ usec_t ft;
+
+ if (fstat(fd, &st) < 0) {
+ log_error("fstat() failed: %m");
+ return -errno;
+ }
+
+ ft = timespec_load(&st.st_mtim);
+ if (ft > nt)
+ nt = ft;
+ }
+
+ ct = now(CLOCK_REALTIME);
+ if (nt > ct) {
+ struct timespec ts;
+ log_info("System clock time unset or jumed backwards, restoring.");
+
+ if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, nt)) < 0)
+ log_error("Failed to restore system clock: %m");
+ }
+
+ /* Try to fix the access mode, so that we can still
+ touch the file after dropping priviliges */
+ fchmod(fd, 0644);
+ fchown(fd, uid, gid);
+
+ return 0;
+}
+
+static int save_clock(void) {
+
+ static const struct timespec ts[2] = {
+ { .tv_sec = 0, .tv_nsec = UTIME_NOW },
+ { .tv_sec = 0, .tv_nsec = UTIME_NOW },
+ };
+
+ int r;
+
+ r = utimensat(-1, "/var/lib/systemd/clock", ts, AT_SYMLINK_NOFOLLOW);
+ if (r < 0) {
+ log_warning("Failed to touch /var/lib/systemd/clock: %m");
+ return -errno;
+ }
+
+ return 0;
+}
+