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
@@ -1319,17 +1319,26 @@ int main(int argc, char *argv[]) {
1319 if (label_init(NULL) < 0) 1319 if (label_init(NULL) < 0)
1320 goto finish; 1320 goto finish;
1321 1321
1322 if (!skip_setup) 1322 if (!skip_setup) {
1323 if (hwclock_is_localtime() > 0) { 1323 if (hwclock_is_localtime() > 0) {
1324 int min; 1324 int min;
1325 1325
1326 r = hwclock_apply_localtime_delta(&min); 1326 /* The first-time call to settimeofday() does a time warp in the kernel */
1327 r = hwclock_set_timezone(&min);
1327 if (r < 0) 1328 if (r < 0)
1328 log_error("Failed to apply local time delta, ignoring: %s", strerror(-r)); 1329 log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
1329 else 1330 else
1330 log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min); 1331 log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
1331 } 1332 } else {
1333 /* Do dummy first-time call to seal the kernel's time warp magic */
1334 hwclock_reset_timezone();
1332 1335
1336 /* Tell the kernel our time zone */
1337 r = hwclock_set_timezone(NULL);
1338 if (r < 0)
1339 log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r));
1340 }
1341 }
1333 } else { 1342 } else {
1334 arg_running_as = MANAGER_USER; 1343 arg_running_as = MANAGER_USER;
1335 log_set_target(LOG_TARGET_AUTO); 1344 log_set_target(LOG_TARGET_AUTO);
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
@@ -188,7 +188,7 @@ int hwclock_is_localtime(void) {
188 return local; 188 return local;
189} 189}
190 190
191int hwclock_apply_localtime_delta(int *min) { 191int hwclock_set_timezone(int *min) {
192 const struct timeval *tv_null = NULL; 192 const struct timeval *tv_null = NULL;
193 struct timespec ts; 193 struct timespec ts;
194 struct tm *tm; 194 struct tm *tm;
@@ -214,13 +214,18 @@ int hwclock_apply_localtime_delta(int *min) {
214 return 0; 214 return 0;
215} 215}
216 216
217int hwclock_reset_localtime_delta(void) { 217int hwclock_reset_timezone(void) {
218 const struct timeval *tv_null = NULL; 218 const struct timeval *tv_null = NULL;
219 struct timezone tz; 219 struct timezone tz;
220 220
221 tz.tz_minuteswest = 0; 221 tz.tz_minuteswest = 0;
222 tz.tz_dsttime = 0; /* DST_NONE*/ 222 tz.tz_dsttime = 0; /* DST_NONE*/
223 223
224 /*
225 * The very first time we set the kernel's timezone, it will warp
226 * the clock. Do a dummy call here, so the time warping is sealed
227 * and we set only the time zone with next call.
228 */
224 if (settimeofday(tv_null, &tz) < 0) 229 if (settimeofday(tv_null, &tz) < 0)
225 return -errno; 230 return -errno;
226 231
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
@@ -23,8 +23,8 @@
23***/ 23***/
24 24
25int hwclock_is_localtime(void); 25int hwclock_is_localtime(void);
26int hwclock_apply_localtime_delta(int *min); 26int hwclock_set_timezone(int *min);
27int hwclock_reset_localtime_delta(void); 27int hwclock_reset_timezone(void);
28int hwclock_get_time(struct tm *tm); 28int hwclock_get_time(struct tm *tm);
29int hwclock_set_time(const struct tm *tm); 29int hwclock_set_time(const struct tm *tm);
30 30
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
@@ -696,13 +696,13 @@ static DBusHandlerResult timedate_message_handler(
696 return bus_send_error_reply(connection, message, NULL, r); 696 return bus_send_error_reply(connection, message, NULL, r);
697 } 697 }
698 698
699 /* 2. Tell the kernel our time zone */
700 hwclock_set_timezone(NULL);
701
699 if (tz.local_rtc) { 702 if (tz.local_rtc) {
700 struct timespec ts; 703 struct timespec ts;
701 struct tm *tm; 704 struct tm *tm;
702 705
703 /* 2. Teach kernel new timezone */
704 hwclock_apply_localtime_delta(NULL);
705
706 /* 3. Sync RTC from system clock, with the new delta */ 706 /* 3. Sync RTC from system clock, with the new delta */
707 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); 707 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
708 assert_se(tm = localtime(&ts.tv_sec)); 708 assert_se(tm = localtime(&ts.tv_sec));
@@ -753,11 +753,8 @@ static DBusHandlerResult timedate_message_handler(
753 return bus_send_error_reply(connection, message, NULL, r); 753 return bus_send_error_reply(connection, message, NULL, r);
754 } 754 }
755 755
756 /* 2. Teach kernel new timezone */ 756 /* 2. Tell the kernel our time zone */
757 if (tz.local_rtc) 757 hwclock_set_timezone(NULL);
758 hwclock_apply_localtime_delta(NULL);
759 else
760 hwclock_reset_localtime_delta();
761 758
762 /* 3. Synchronize clocks */ 759 /* 3. Synchronize clocks */
763 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); 760 assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);