units/sys-kernel-security.mount \
units/var-run.mount \
units/media.mount \
- units/hwclock-load.service \
units/hwclock-save.service \
units/remount-rootfs.service \
units/printer.target \
( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \
rm -f remote-fs.target && \
$(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target )
- ( cd $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants && \
- rm -f hwclock-load.service && \
- $(LN_S) $(systemunitdir)/hwclock-load.service hwclock-load.service )
( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \
rm -f dev-hugepages.automount \
dev-mqueue.automount \
if (label_init() < 0)
goto finish;
+
+ if (hwclock_is_localtime()) {
+ int min;
+
+ min = hwclock_apply_localtime_delta();
+ log_info("Hwclock configured in localtime, applying delta of %i minutes to system time", min);
+ }
} else {
arg_running_as = MANAGER_USER;
log_set_target(LOG_TARGET_CONSOLE);
#include <dlfcn.h>
#include <sys/wait.h>
#include <sys/capability.h>
+#include <sys/time.h>
+#include <linux/rtc.h>
#include "macro.h"
#include "util.h"
*strv = files;
return r;
}
+
+bool hwclock_is_localtime(void) {
+ FILE *f;
+ char line[LINE_MAX];
+ bool local = false;
+
+ /*
+ * The third line of adjtime is "UTC" or "LOCAL" or nothing.
+ * # /etc/adjtime
+ * 0.0 0 0.0
+ * 0
+ * UTC
+ */
+ f = fopen("/etc/adjtime", "re");
+ if (f) {
+ if (fgets(line, sizeof(line), f) &&
+ fgets(line, sizeof(line), f) &&
+ fgets(line, sizeof(line), f) ) {
+ if (!strcmp(line, "LOCAL\n"))
+ local = true;
+ }
+ fclose(f);
+ }
+ return local;
+}
+
+int hwclock_apply_localtime_delta(void) {
+ const struct timeval *tv_null = NULL;
+ struct timeval tv;
+ struct tm *tm;
+ int minuteswest;
+ struct timezone tz;
+
+ gettimeofday(&tv, NULL);
+ tm = localtime(&tv.tv_sec);
+ minuteswest = tm->tm_gmtoff / 60;
+
+ tz.tz_minuteswest = -minuteswest;
+ tz.tz_dsttime = 0; /* DST_NONE*/
+
+ /*
+ * If the hardware clock does not run in UTC, but in local time:
+ * The very first time we set the kernel's timezone, it will warp
+ * the clock so that it runs in UTC instead of local time.
+ */
+ if (settimeofday(tv_null, &tz) < 0)
+ return -errno;
+ else
+ return minuteswest;
+}
+
+int hwclock_get_time(struct tm *tm) {
+ int fd;
+ int err = 0;
+
+ fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+ if (ioctl(fd, RTC_RD_TIME, tm) < 0)
+ err = -errno;
+ close(fd);
+
+ return err;
+}
+
+int hwclock_set_time(const struct tm *tm) {
+ int fd;
+ int err = 0;
+
+ fd = open("/dev/rtc0", O_RDONLY|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+ if (ioctl(fd, RTC_SET_TIME, tm) < 0)
+ err = -errno;
+ close(fd);
+
+ return err;
+}
int signal_from_string_try_harder(const char *s);
int conf_files_list(char ***strv, const char *suffix, const char *dir, ...);
+
+bool hwclock_is_localtime(void);
+
+int hwclock_apply_localtime_delta(void);
+
+int hwclock_get_time(struct tm *tm);
+
+int hwclock_set_time(const struct tm *tm);
+
#endif
+++ /dev/null
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-
-[Unit]
-Description=Apply System Clock UTC Offset
-DefaultDependencies=no
-Wants=time-sync.target
-Conflicts=shutdown.target
-After=systemd-readahead-collect.service systemd-readahead-replay.service
-Before=sysinit.target shutdown.target udev.service time-sync.target
-
-[Service]
-Type=oneshot
-RemainAfterExit=yes
-ExecStart=/sbin/hwclock --systz
-StandardOutput=syslog
-
-# Note the weird semantics of hwclock and the kernel here: the first
-# settimeofday() invocation from userspace is special and may be used
-# to set the offset from UTC of the system clock. It is independent
-# of any specific RTC device. This is mostly a crufty hack to support
-# legacy operating systems which insist on storing local time in the
-# RTC.
-
-# Note that we do not run --hctosys here, we assume the kernel
-# includes a compiled in RTC module which is used to initialize the
-# system time as part of kernel setup.
-
-[Install]
-WantedBy=sysinit.target