At startup, when ntpd starts and after that on every 11 minutes, the kernel sets the hwclock (RTC) to UTC time, regardless of the clock="local" setting in the /etc/conf.d/hwclock configuration file.
The 11 minutes RTC update is enabled in the kernel config, by CONFIG_GENERIC_CMOS_UPDATE || CONFIG_RTC_SYSTOHC. CONFIG_GENERIC_CMOS_UPDATE has no entry in menuconfig, and is dependency of CONFIG_X86 so it can't be disabled simply. The problem can be solved by calling the "settimeofday" system call after bootup in a special way, here is the relevant portion of man 2 settimeofday: "If on the very first call (after booting) that has a non-NULL tz argument, the tv argument is NULL and the tz_minuteswest field is nonzero. (The tz_dsttime field should be zero for this case.) In such a case it is assumed that the CMOS clock is on local time, and that it has to be incremented by this amount to get UTC system time." I wrote a small C program to solve the program: //setrtclocal.c //======= #include <sys/time.h> int main(int argc,char** argv) { struct timezone tz; tz.tz_minuteswest=1; tz.tz_dsttime=0; settimeofday(0,&tz); return 0; } //======= And executed it from /etc/init.d/hwclock, before anything, if clock="local". That solved the prbolem. I'm reporting the bug, because it can be usefull for somebody else.
Not sure what this has to do with the kernel, especially since writing a C program to resolve it works; I therefore think this is an user space problem.
(In reply to mateakos from comment #1) > The 11 minutes RTC update is enabled in the kernel config, by > CONFIG_GENERIC_CMOS_UPDATE || CONFIG_RTC_SYSTOHC. Did you try disabling CONFIG_RTC_SYSTOHC? I ask because, based on what I read in make menuconfig, disabling that option should take care of this. Thanks, William
(In reply to William Hubbs from comment #3) > Did you try disabling CONFIG_RTC_SYSTOHC? I ask because, based on what I > read in make menuconfig, disabling that option should take care of this. Yes, I tried, but I can't disable CONFIG_GENERIC_CMOS_UPDATE because it has no menu entry and it is the dependency of CONFIG_X86, so the OR-ed expression is still true. There is two problem. 1) Can't disable the 11 minutes RTC update on X86. 2) clock="local" does not set the persistent_clock_is_local variable in the kernel. The 2nd problem is solved by my small C program and Script modification. Best regards, Akos
(In reply to mateakos from comment #4) > (In reply to William Hubbs from comment #3) > > Did you try disabling CONFIG_RTC_SYSTOHC? I ask because, based on what I > > read in make menuconfig, disabling that option should take care of this. > > Yes, I tried, but I can't disable CONFIG_GENERIC_CMOS_UPDATE because it has > no menu entry and it is the dependency of CONFIG_X86, so the OR-ed > expression is still true. > There is two problem. > 1) Can't disable the 11 minutes RTC update on X86. This piece is a kernel issue. > 2) clock="local" does not set the persistent_clock_is_local variable in the > kernel. I have one more thing I would like you to try for this, if you haven't already. If you can try this, please do the following. In /etc/conf.d/hwclock, change the line that reads: #clock_hctosys="YES" to: clock_hctosys="NO" Then, reboot without running your c program or your script modification and let me know if that fixes your issue. Thanks very much for your help.
(In reply to William Hubbs from comment #5) > If you can try this, please do the following. > > In /etc/conf.d/hwclock, change the line that reads: > > #clock_hctosys="YES" > > to: > > clock_hctosys="NO" > > Then, reboot without running your c program or your script modification and > let me know if that fixes your issue. > > Thanks very much for your help. With clock="local" clock_systohc="YES" clock_hctosys="NO" the issue is fixed, without my c program, but i can't tell, exactly, why this setting fixes the issue.
(In reply to mateakos from comment #6) My theory: clock_hctosys="NO" causes the hwclock init script to run "hwclock --systz --localtime", which does basically does the same thing as your simple program. When clock_hctosys="YES", the init script runs "hwclock --hctosys --localtime", which does something a little different. This might be a bug in hwclock; the manpage says it is supposed to set the "kernel timezone" in addition to adjusting the system time, but this might be incorrect.
Looking at the kernel source, it appears that the kernel only utilizes the kernel timezone for the 11-minute ntp updates if the very first call to settimeofday has a NULL tv value, thus invoking the "warp clock" behavior. See the following kernel functions: kernel/time.c: do_sys_settimeofday(): calls warp_clock kernel/time.c: warp_clock(): sets persistent_clock_is_local kernel/time/ntp.c sync_cmos_clock(): reads persistent_clock_is_local Given the kernel behavior, I would suggest we change /etc/init.d/hwclock to always call hwclock --systz when the hardware clock is in local time, regardless of how clock_hctosys is set.
Created attachment 381308 [details, diff] Proposed patch
Created attachment 381310 [details, diff] Revised patch
(In reply to Mike Gilbert from comment #7) > (In reply to mateakos from comment #6) > > My theory: clock_hctosys="NO" causes the hwclock init script to run "hwclock > --systz --localtime", which does basically does the same thing as your > simple program. > > When clock_hctosys="YES", the init script runs "hwclock --hctosys > --localtime", which does something a little different. This might be a bug > in hwclock; the manpage says it is supposed to set the "kernel timezone" in > addition to adjusting the system time, but this might be incorrect. Checked with strace. ======== # strace hwclock --systz --localtime 2>&1 | grep timeof settimeofday(NULL, {4294967176, 0}) = 0 4294967176 = -120 (-120 minutes west) It sets the timezone, and warp clock behavior. (If it's the very first call of settimeofday) ========= # strace hwclock --hctosys --localtime 2>&1 | grep timeof settimeofday({1406027117, 0}, {4294967176, 1406027117}) = 0 It sets the timezone, but not the warp clock behavior, because the first parameter is not NULL. ========= So basically: "hwclock --systz --localtime" can be used instead of my C program.
(In reply to Mike Gilbert from comment #10) > Created attachment 381310 [details, diff] [details, diff] > Revised patch Will this patch work correctly, if clock_args is not empty? In that case, I think it might call hwclock with --systz argument even if RTC runs on UTC time.
FYI: net-misc/adjtimex allows viewing and tuning of the kernel time parameters. The trick is that the 11-minute-mode is toggled under certain circumstances by ntpd and calls to hwclock. I mention adjtimex because it allows you to view the status bit for 11-minute-mode (bit 6, value 64): http://serverfault.com/questions/337930/what-is-the-largest-hardware-clock-update-the-linux-kernel-11-minute-mode-can There also used to be a sysctl at one point, but I'm not sure what happened to it: /proc/sys/kernel/time/rtc_update
(In reply to mateakos from comment #12) > Will this patch work correctly, if clock_args is not empty? In that case, I > think it might call hwclock with --systz argument even if RTC runs on UTC > time. You're right, that patch needs a little tweaking. Feel free to propose a revision!
(In reply to Mike Gilbert from comment #14) > (In reply to mateakos from comment #12) > > Will this patch work correctly, if clock_args is not empty? In that case, I > > think it might call hwclock with --systz argument even if RTC runs on UTC > > time. > > You're right, that patch needs a little tweaking. Feel free to propose a > revision! I was wrong. It's right that it will run hwclock with --systz, but it will run as "hwclock --systz --utc" which is not a problem, because there is the --utc argument. # strace hwclock --systz --utc 2>&1 | grep timeof settimeofday(NULL, {0, 66985616}) = 0 settimeofday(NULL, {4294967176, 0}) = 0 At the first settimeofday call, the minuteswest field is zero, the warp_clock function will run, but won't set the persistent_clock_is_local variable, so no problem. The patch works well in all tested cases.
Created attachment 381458 [details, diff] 0001-hwclock-always-set-timezone.patch My understanding of this issue is that we should always set the kernel's timezone, so this is the patch I propose. Thoughts? William
(In reply to William Hubbs from comment #16) > Created attachment 381458 [details, diff] [details, diff] > 0001-hwclock-always-set-timezone.patch > > My understanding of this issue is that we should always set the > kernel's timezone, so this is the patch I propose. > > Thoughts? > > William Now I'm using Mike Gilbert's patch, but I think, this should work too. It's cleaner to always set the kernel's timezone with a separate hwclock run, and then set the time, when it's neccessary with another hwclock run. So I propose this new patch to use by everyone.
(In reply to William Hubbs from comment #16) Looks good. +1 from me.
The issue is that OpenRc's hwclock service script only sets the kernel's timezone when clock_hctosys is set to "NO". This should be done regardless of the clock_hctosys setting. I found an older bug for the same issue, so I am closing this bug as a duplicate. *** This bug has been marked as a duplicate of bug 434410 ***