summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-09-17 16:41:13 +0200
committerKay Sievers <kay@vrfy.org>2012-09-17 16:56:26 +0200
commit72edcff5db936e54cfc322d9392ec46e2428fd9b (patch)
tree2de5e6ba1b02e2b6db42ad3ab99c0907cfcf6285 /src
parent4096d6f5879aef73e20dd7b62a01f447629945b0 (diff)
hwclock: always set the kernel's timezone
Properly tell the kernel at bootup, and any later time zone changes, the actual system time zone. Things like the kernel's FAT filesystem driver needs the actual time zone to calculate the proper local time to use for the on-disk time stamps. https://bugzilla.redhat.com/show_bug.cgi?id=802198
Diffstat (limited to 'src')
-rw-r--r--src/core/main.c15
-rw-r--r--src/shared/hwclock.c9
-rw-r--r--src/shared/hwclock.h4
-rw-r--r--src/timedate/timedated.c13
4 files changed, 26 insertions, 15 deletions
diff --git a/src/core/main.c b/src/core/main.c
index 44c010cfb..199383e63 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1321,3 +1321,3 @@ int main(int argc, char *argv[]) {
- if (!skip_setup)
+ if (!skip_setup) {
if (hwclock_is_localtime() > 0) {
@@ -1325,3 +1325,4 @@ int main(int argc, char *argv[]) {
- r = hwclock_apply_localtime_delta(&min);
+ /* The first-time call to settimeofday() does a time warp in the kernel */
+ r = hwclock_set_timezone(&min);
if (r < 0)
@@ -1330,4 +1331,12 @@ int main(int argc, char *argv[]) {
log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
- }
+ } else {
+ /* Do dummy first-time call to seal the kernel's time warp magic */
+ hwclock_reset_timezone();
+ /* Tell the kernel our time zone */
+ r = hwclock_set_timezone(NULL);
+ if (r < 0)
+ log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r));
+ }
+ }
} else {
diff --git a/src/shared/hwclock.c b/src/shared/hwclock.c
index 9f8ab08e2..d9d5600ff 100644
--- a/src/shared/hwclock.c
+++ b/src/shared/hwclock.c
@@ -190,3 +190,3 @@ int hwclock_is_localtime(void) {
-int hwclock_apply_localtime_delta(int *min) {
+int hwclock_set_timezone(int *min) {
const struct timeval *tv_null = NULL;
@@ -216,3 +216,3 @@ int hwclock_apply_localtime_delta(int *min) {
-int hwclock_reset_localtime_delta(void) {
+int hwclock_reset_timezone(void) {
const struct timeval *tv_null = NULL;
@@ -223,2 +223,7 @@ int hwclock_reset_localtime_delta(void) {
+ /*
+ * The very first time we set the kernel's timezone, it will warp
+ * the clock. Do a dummy call here, so the time warping is sealed
+ * and we set only the time zone with next call.
+ */
if (settimeofday(tv_null, &tz) < 0)
diff --git a/src/shared/hwclock.h b/src/shared/hwclock.h
index 26d1b444e..b2bdc78f0 100644
--- a/src/shared/hwclock.h
+++ b/src/shared/hwclock.h
@@ -25,4 +25,4 @@
int hwclock_is_localtime(void);
-int hwclock_apply_localtime_delta(int *min);
-int hwclock_reset_localtime_delta(void);
+int hwclock_set_timezone(int *min);
+int hwclock_reset_timezone(void);
int hwclock_get_time(struct tm *tm);
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 7eed31c47..0ebece893 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -698,2 +698,5 @@ static DBusHandlerResult timedate_message_handler(
+ /* 2. Tell the kernel our time zone */
+ hwclock_set_timezone(NULL);
+
if (tz.local_rtc) {
@@ -702,5 +705,2 @@ static DBusHandlerResult timedate_message_handler(
- /* 2. Teach kernel new timezone */
- hwclock_apply_localtime_delta(NULL);
-
/* 3. Sync RTC from system clock, with the new delta */
@@ -755,7 +755,4 @@ static DBusHandlerResult timedate_message_handler(
- /* 2. Teach kernel new timezone */
- if (tz.local_rtc)
- hwclock_apply_localtime_delta(NULL);
- else
- hwclock_reset_localtime_delta();
+ /* 2. Tell the kernel our time zone */
+ hwclock_set_timezone(NULL);