Discussion:
How to use /etc/adjtime
(too old to reply)
Stefan Monnier
2024-06-27 16:50:01 UTC
Permalink
I have a machine whose RTC clock is drifting significantly and it is
often suspended for several days. I run NTP so the drift I see when
I wake the machine up gets fixed by "stepping" the clock after a while,
but that can take a while and I'd like to improve this
intermediate situation.

The /etc/adjtime is supposed to be there for such purposes but it seems
to be mostly unused: I assume its "UTC" setting is respected but the
first and second lines indicate it has not been updated since 2015
(i.e. when that Debian install was used in another machine).

I have two questions:

- How can I get Debian to use this file when waking up the machine from
suspend (which would presumably change the file by updating the first
line's "last adjust time")?

- How can I get `ntpd` to adjust the first line's "drift factor" when it
steps the clock?

The second question is less important (I can write the drift factor by
hand, e.g. in case `ntpd` is not being told when the clock is (re)set
based on the RTC, making it impossible for it to compute a drift factor).


Stefan
t***@tuxteam.de
2024-06-27 17:10:01 UTC
Permalink
Post by Stefan Monnier
I have a machine whose RTC clock is drifting significantly and it is
often suspended for several days. I run NTP so the drift I see when
I wake the machine up gets fixed by "stepping" the clock after a while,
but that can take a while and I'd like to improve this
intermediate situation.
The /etc/adjtime is supposed to be there for such purposes but it seems
to be mostly unused: I assume its "UTC" setting is respected but the
first and second lines indicate it has not been updated since 2015
(i.e. when that Debian install was used in another machine).
- How can I get Debian to use this file when waking up the machine from
suspend (which would presumably change the file by updating the first
line's "last adjust time")?
- How can I get `ntpd` to adjust the first line's "drift factor" when it
steps the clock?
The second question is less important (I can write the drift factor by
hand, e.g. in case `ntpd` is not being told when the clock is (re)set
based on the RTC, making it impossible for it to compute a drift factor).
I think hwclock(8) has the info you need. On my system (yes, one of
those) there is an /etc/init.d/hwclock.sh which seems to take care
of that. No idea how the young'uns do it, though :-)

Cheers
--
t
Stefan Monnier
2024-06-28 13:50:01 UTC
Permalink
Post by t***@tuxteam.de
I think hwclock(8) has the info you need. On my system (yes, one of
those) there is an /etc/init.d/hwclock.sh which seems to take care
of that. No idea how the young'uns do it, though :-)
AFAICT this `hwclock.sh` (which I do have) is not used (I'm using
systemd) and even less so upon suspend/wakeup: it seems targeted at
boot/shutdown.

The hwclock(8) tells me how to use the `hwclock` command but not how to
make other parts of the system run the `hwclock` command at the right
time (or how to get a similar result without running that command, of
course).


Stefan
David Wright
2024-06-28 02:30:01 UTC
Permalink
Post by Stefan Monnier
I have a machine whose RTC clock is drifting significantly and it is
often suspended for several days. I run NTP so the drift I see when
I wake the machine up gets fixed by "stepping" the clock after a while,
but that can take a while and I'd like to improve this
intermediate situation.
Do you really run ntp? You might already be running ntpsec,
its replacement.
Post by Stefan Monnier
The /etc/adjtime is supposed to be there for such purposes but it seems
to be mostly unused: I assume its "UTC" setting is respected but the
first and second lines indicate it has not been updated since 2015
(i.e. when that Debian install was used in another machine).
You might find your clock drift in /var/lib/ntpsec/ntp.drift
or wherever /etc/ntpsec/ntp.conf specifies it.
Post by Stefan Monnier
- How can I get Debian to use this file when waking up the machine from
suspend (which would presumably change the file by updating the first
line's "last adjust time")?
- How can I get `ntpd` to adjust the first line's "drift factor" when it
steps the clock?
The second question is less important (I can write the drift factor by
hand, e.g. in case `ntpd` is not being told when the clock is (re)set
based on the RTC, making it impossible for it to compute a drift factor).
I don't know how to speed up correcting the clock as I use chrony,
but ntpsec may have similar directives available.

Cheers,
David.
Stefan Monnier
2024-06-28 13:50:01 UTC
Permalink
Do you really run ntp? You might already be running ntpsec,
its replacement.
I call it ntp but yes, it's ntpsec.
Post by Stefan Monnier
The /etc/adjtime is supposed to be there for such purposes but it seems
to be mostly unused: I assume its "UTC" setting is respected but the
first and second lines indicate it has not been updated since 2015
(i.e. when that Debian install was used in another machine).
You might find your clock drift in /var/lib/ntpsec/ntp.drift
or wherever /etc/ntpsec/ntp.conf specifies it.
Oh, indeed, thanks. I had computed it manually from
`journalctl | grep stepped` and it gave close enough results.
The question remains: how to make use of that info upon wakeup to adjust
the "initial" time before NTP takes over.
I don't know how to speed up correcting the clock as I use chrony,
but ntpsec may have similar directives available.
Indeed, I could try and shorten the time before the NTP info takes
precedence over the RTC-derived initial approximation (I haven't found
any way to tell ntpsec to do that, short of limiting the maximum
interval between pollings or maybe killing&restarting the deamon, both
of which seem too crude for my sense of aesthetics), but I'm more
interested in improving the initial approximation.


Stefan
Greg Wooledge
2024-06-28 14:10:01 UTC
Permalink
Post by Stefan Monnier
Oh, indeed, thanks. I had computed it manually from
`journalctl | grep stepped` and it gave close enough results.
The question remains: how to make use of that info upon wakeup to adjust
the "initial" time before NTP takes over.
As I understand it, the drift is used to speed up or slow down the
system clock, so that it more closely tracks real time, and needs
fewer nudges by NTP.

As such, it really has nothing to do with how the system clock is
initialized at boot time (or wake-from-suspend time? I don't do laptops).

At boot time, the system clock is initialized by reading the hardware
clock, with the assumptions that the hardware clock is not very
accurate, but is better than nothing. The system clock will be
adjusted by NTP once the network is up and once the NTP daemon has had
a chance to communicate with its servers and figure out what time it
actually is.
Post by Stefan Monnier
Indeed, I could try and shorten the time before the NTP info takes
precedence over the RTC-derived initial approximation (I haven't found
any way to tell ntpsec to do that, short of limiting the maximum
interval between pollings or maybe killing&restarting the deamon, both
of which seem too crude for my sense of aesthetics), but I'm more
interested in improving the initial approximation.
I'm failing to understand your thought process here.

The hardware clock has a time, which is loaded into the system clock
to initialize it. That's it. The only variable factor here is whether
the hardware clock's time is in UTC or some local time zone.

You can't do anything with drift at this point, because you don't actually
know how long you were asleep. All you know is the current HW clock time.
It's not like you can say "Oh, I was asleep for 7.5234 hours, so I need
to adjust the HW clock time forward by X seconds because I know it runs
a bit slow." That information is not available to you.
David Wright
2024-06-28 14:40:01 UTC
Permalink
Post by Greg Wooledge
Post by Stefan Monnier
Oh, indeed, thanks. I had computed it manually from
`journalctl | grep stepped` and it gave close enough results.
The question remains: how to make use of that info upon wakeup to adjust
the "initial" time before NTP takes over.
As I understand it, the drift is used to speed up or slow down the
system clock, so that it more closely tracks real time, and needs
fewer nudges by NTP.
As such, it really has nothing to do with how the system clock is
initialized at boot time (or wake-from-suspend time? I don't do laptops).
At boot time, the system clock is initialized by reading the hardware
clock, with the assumptions that the hardware clock is not very
accurate, but is better than nothing. The system clock will be
adjusted by NTP once the network is up and once the NTP daemon has had
a chance to communicate with its servers and figure out what time it
actually is.
Post by Stefan Monnier
Indeed, I could try and shorten the time before the NTP info takes
precedence over the RTC-derived initial approximation (I haven't found
any way to tell ntpsec to do that, short of limiting the maximum
interval between pollings or maybe killing&restarting the deamon, both
of which seem too crude for my sense of aesthetics), but I'm more
interested in improving the initial approximation.
I'm failing to understand your thought process here.
The hardware clock has a time, which is loaded into the system clock
to initialize it. That's it. The only variable factor here is whether
the hardware clock's time is in UTC or some local time zone.
You can't do anything with drift at this point, because you don't actually
know how long you were asleep. All you know is the current HW clock time.
It's not like you can say "Oh, I was asleep for 7.5234 hours, so I need
to adjust the HW clock time forward by X seconds because I know it runs
a bit slow." That information is not available to you.
In chrony, you'd use its rtcfile directive, which saves the time
when it last made a correction. Here's an outline:

rtcfile file
The rtcfile directive defines the name of the file in which
chronyd can save parameters associated with tracking the
accuracy of the RTC.

An example of the directive is:

rtcfile /var/lib/chrony/rtc

chronyd saves information in this file when it exits and when
the writertc command is issued in chronyc. The information
saved is the RTC’s error at some epoch, that epoch (in seconds
since January 1 1970), and the rate at which the RTC gains or
loses time.

So far, the support for real-time clocks is limited; their
code is even more system-specific than the rest of the
software. You can only use the RTC facilities (the rtcfile
directive and the -s command-line option to chronyd) if the
following three conditions apply:

1. You are running Linux.

2. The kernel is compiled with extended real-time clock
support (i.e. the /dev/rtc device is capable of doing
useful things).

3. You do not have other applications that need to make use
of /dev/rtc at all.

Perhaps ntpsec can do something similar.

Cheers,
David.
John Hasler
2024-06-28 14:50:01 UTC
Permalink
Post by Stefan Monnier
The question remains: how to make use of that info upon wakeup to
adjust the "initial" time before NTP takes over.
hwclock -a can do this. If you use it be sure ntpsec isn't trying to do
the same thing.
--
John Hasler
***@sugarbit.com
Elmwood, WI USA
David Wright
2024-06-28 15:10:01 UTC
Permalink
Post by John Hasler
Post by Stefan Monnier
The question remains: how to make use of that info upon wakeup to
adjust the "initial" time before NTP takes over.
hwclock -a can do this.
Sure it can.
Post by John Hasler
If you use it be sure ntpsec isn't trying to do
the same thing.
It's not clear to me which NTP (protocol) packages are set up to
use the util-linux stuff, assuming you're not rolling your own
startup/shutdown scripts. (That's the problem in the Subject
line, in a sense.)

Does ntpsec have this facility built in, or are you expected to
link it up to hwclock?

The critical part of the whole operation AIUI is not what happens
at startup, but at shutdown: writing to the RTC, and the correct
preservation of its state.

Cheers,
David.
John Hasler
2024-06-28 16:20:01 UTC
Permalink
It's not clear to me which NTP (protocol) packages are set up to use
the util-linux stuff, assuming you're not rolling your own
startup/shutdown scripts. (That's the problem in the Subject line, in
a sense.)
Chrony can. I don't know about Ntpsec. But that doesn't get the
adjustment made early enough.
The critical part of the whole operation AIUI is not what happens at
startup,
The tricky part, I think, is correcting the rtc before it is used to
initialize the system time. Otherwise you'll still have to step or slew
the system time.
but at shutdown: writing to the RTC, and the correct preservation of
its state.
You write to the rtc and to /etc/adjtime periodically at a rate
determined by the computed hot drift rate and also during a controlled
shutdown.
--
John Hasler
***@sugarbit.com
Elmwood, WI USA
David Wright
2024-06-28 19:10:02 UTC
Permalink
Post by John Hasler
It's not clear to me which NTP (protocol) packages are set up to use
the util-linux stuff, assuming you're not rolling your own
startup/shutdown scripts. (That's the problem in the Subject line, in
a sense.)
Chrony can. I don't know about Ntpsec. But that doesn't get the
adjustment made early enough.
By "use the util-linux stuff" I meant use /sbin/hwclock. Neither
chrony nor ntpsec can use hwclock by default as they don't list
util-linux as a dependency. They use their own binaries. IDK whether
you can deliberately configure them to use hwclock instead, or why
any one would do so.
Post by John Hasler
The critical part of the whole operation AIUI is not what happens at
startup,
The tricky part, I think, is correcting the rtc before it is used to
initialize the system time. Otherwise you'll still have to step or slew
the system time.
but at shutdown: writing to the RTC, and the correct preservation of
its state.
You write to the rtc and to /etc/adjtime periodically at a rate
determined by the computed hot drift rate and also during a controlled
shutdown.
With chrony, you can monitor the RTC over time and adjust the system
clock in accordance with its drift rate at boot time, without
correcting the RTC itself, or you can actually set the RTC from the
system clock periodically.

The particular problem at shutdown is that there were/are systems, as
you described, that write the system time to the RTC without
necessarily regarding how you might be running the clock otherwise.
That alteration is unknowable for chrony when it restarts after booting.

Cheers,
David.
John Hasler
2024-06-28 20:10:01 UTC
Permalink
Post by David Wright
With chrony, you can monitor the RTC over time and adjust the system
clock in accordance with its drift rate at boot time, without
correcting the RTC itself, or you can actually set the RTC from the
system clock periodically.
That leads to the probelem that started this thread: system time being
set incorrectly at boot and then stepped later.
Post by David Wright
The particular problem at shutdown is that there were/are systems, as
you described, that write the system time to the RTC without
necessarily regarding how you might be running the clock otherwise.
That alteration is unknowable for chrony when it restarts after booting.
Obviously you must make sure that only one process ever writes to the
RTC.

Actually you need never write to the RTC at all: just track its offset
and drift rate. That would require hacking the boot process to make
sure only your code ever reads it, though.
--
John Hasler
***@sugarbit.com
Elmwood, WI USA
David Wright
2024-06-30 04:50:01 UTC
Permalink
Post by John Hasler
Post by David Wright
With chrony, you can monitor the RTC over time and adjust the system
clock in accordance with its drift rate at boot time, without
correcting the RTC itself, or you can actually set the RTC from the
system clock periodically.
That leads to the probelem that started this thread: system time being
set incorrectly at boot and then stepped later.
Post by David Wright
The particular problem at shutdown is that there were/are systems, as
you described, that write the system time to the RTC without
necessarily regarding how you might be running the clock otherwise.
That alteration is unknowable for chrony when it restarts after booting.
Obviously you must make sure that only one process ever writes to the
RTC.
Actually you need never write to the RTC at all: just track its offset
and drift rate. That would require hacking the boot process to make
sure only your code ever reads it, though.
I think that's what I wrote in the first half of the sentence at the top.
I don't think you can avoid the kernel setting the system clock before
chrony does, but I don't see the problem with that: chrony just sets it
again when it runs.

So the problem may reduce to how to get resume to run chrony (as the
example) before any user processes run again. There are options to
make that more likely, like keeping chrony resident, and increasing
its scheduling priority, and I have already suggested a method that
might allow systemd to make it certain.

Cheers,
David.

t***@tuxteam.de
2024-06-29 05:00:01 UTC
Permalink
Post by David Wright
Post by John Hasler
It's not clear to me which NTP (protocol) packages are set up to use
the util-linux stuff, assuming you're not rolling your own
startup/shutdown scripts. (That's the problem in the Subject line, in
a sense.)
Chrony can. I don't know about Ntpsec. But that doesn't get the
adjustment made early enough.
By "use the util-linux stuff" I meant use /sbin/hwclock. Neither
chrony nor ntpsec can use hwclock by default as they don't list
util-linux as a dependency. They use their own binaries. IDK whether
you can deliberately configure them to use hwclock instead, or why
any one would do so.
Still they can set (and AFAIK discipline) the "hardware clock", via the
Linux kernel -- if things are set up this way. See the notes on the Linux
kernel's "11 minute mode" in the hwclock(8) man page.

Cheers
--
t
David Wright
2024-06-30 04:50:01 UTC
Permalink
Post by t***@tuxteam.de
Post by David Wright
Post by John Hasler
It's not clear to me which NTP (protocol) packages are set up to use
the util-linux stuff, assuming you're not rolling your own
startup/shutdown scripts. (That's the problem in the Subject line, in
a sense.)
Chrony can. I don't know about Ntpsec. But that doesn't get the
adjustment made early enough.
By "use the util-linux stuff" I meant use /sbin/hwclock. Neither
chrony nor ntpsec can use hwclock by default as they don't list
util-linux as a dependency. They use their own binaries. IDK whether
you can deliberately configure them to use hwclock instead, or why
any one would do so.
Still they can set (and AFAIK discipline) the "hardware clock", via the
Linux kernel -- if things are set up this way. See the notes on the Linux
kernel's "11 minute mode" in the hwclock(8) man page.
I don't think that's a good idea for solving drift correction over
long periods of time. You should periodically check the RTC and
system clocks with NTP, and store the measurements of the RTC, in
order to refine its drift rate over a longer and longer time interval.
Every time you set the RTC, you invalidate any measurements you've
already collected.

Cheers,
David.
Stefan Monnier
2024-06-28 18:50:01 UTC
Permalink
Post by John Hasler
Post by Stefan Monnier
The question remains: how to make use of that info upon wakeup to
adjust the "initial" time before NTP takes over.
hwclock -a can do this.
Indeed, and my question can be thought of as asking how to run
`hwclock -a` when we wake up (as well, as how to run `hwclock --systohc`
just before suspend).

But note that when we wake up ntpsec is already running, so I'm not sure
`hwclock -a` could prove problematic.

BTW, I noticed another instance of my original problem: in my original
problem, after sleeping for many days, the time is off by many seconds
and it stays that way for several minutes before ntpsec to decide to
"step" the clock. But after sleeping a smaller amount of time, the time
can be off by a small enough offset that ntpsec doesn't step the clock
but slews it instead, so the clock stays off for an even longer period.

Ideally, we'd like to avoid stepping the system clock at all: when
waking up, the system clock should be (re)initialized right away to the
drift-adjusted RTC clock time, so the user processes only see "a long
sleep" rather than "a long sleep followed by a time warp".

While my machine's RTC drift is particularly bad, I since then noticed
that `journalctl| grep stepped` returns many entries on all my machines
(save those that never sleep), so it's a really widespread problem.


Stefan
Max Nikulin
2024-06-29 01:30:01 UTC
Permalink
Post by Stefan Monnier
But note that when we wake up ntpsec is already running
It should be possible to stop the NTP daemon on suspend (or hibernate)
and start it on resume.

I think, what you are truing to achieve is doable. I do not agree with
Greg. The question is what is already implemented and how much scripting
is required to make it working reliably.

I would start from replacing the RTC battery though.

Next I would search systemd-timesyncd and systemd-datetimed, chrony,
ntpsec docs and sources for relevant configuration options,
configuration files and function calls. Switching to another NTP daemon
may save your time required for scripting and configuring your system.

The last part is adding boot/shutdown and suspend/resume hooks and a
periodic task to maintain timestamp when hardware clock was set last
time. Perhaps the tricky part is to ensure that the NTP daemon or some
other system service does not set RTC without notifying your scripts.

My expectation is that events when RTC is updated, but the corresponding
timestamp is not (or vice versa) may be made rare enough. So precise
enough time may be restored on boot or on resume in most cases and NTP
can handle remaining ones.
Stefan Monnier
2024-06-28 18:40:01 UTC
Permalink
Post by Greg Wooledge
The hardware clock has a time, which is loaded into the system clock
to initialize it. That's it. The only variable factor here is whether
the hardware clock's time is in UTC or some local time zone.
You can't do anything with drift at this point, because you don't actually
know how long you were asleep. All you know is the current HW clock time.
/etc/adjtime complements that info with the expected drift and the last
time the RTC was adjusted to the presumably correct time (which you'd
want to do every once in a while).
So by comparing the RTC time to the last-adjustment time you get to know
how much drift happened and you can correct this initial time estimate.
Post by Greg Wooledge
It's not like you can say "Oh, I was asleep for 7.5234 hours, so I need
to adjust the HW clock time forward by X seconds because I know it runs
a bit slow." That information is not available to you.
It is if /etc/adjtime is set properly when you go to sleep.
See `hwclock(8)` or `adjtime_config(5)`.


Stefan
Greg Wooledge
2024-06-28 19:00:01 UTC
Permalink
Post by Stefan Monnier
Post by Greg Wooledge
It's not like you can say "Oh, I was asleep for 7.5234 hours, so I need
to adjust the HW clock time forward by X seconds because I know it runs
a bit slow." That information is not available to you.
It is if /etc/adjtime is set properly when you go to sleep.
See `hwclock(8)` or `adjtime_config(5)`.
Yeah, except... you're assuming a workflow that is not real or reliable.

hobbit:~$ ls -l /etc/adjtime
-rw-r--r-- 1 root root 44 Mar 6 07:04 /etc/adjtime
hobbit:~$ uptime
14:47:40 up 29 days, 2:54, 29 users, load average: 1.58, 1.07, 1.15

Nothing writes to /etc/adjtime on a regular basis. It's only written
if you manually run an hwclock command, or if you change something
(such as deciding to store your HW clock in UTC instead of local time,
which is what I did on March 6 after learning that Debian had chosen
local time when I installed).
Post by Stefan Monnier
It is if /etc/adjtime is set properly when you go to sleep.
You cannot assume that adjtime was updated the last time your system
stopped running, because your system might have stopped running due to
a crash, instead of a controlled shutdown.

All of the arguments that are being constructed here are bogus.

The *only* thing you know at boot time is what's in the HW clock, and
if you're really lucky, you'll be able to figure out what time zone
it's allegedly set to (after reading /etc/adjtime from disk).

hobbit:~$ cat /etc/adjtime
0.000000 1708191089 0.000000
1708191089
UTC
hobbit:~$ date -d @1708191089
Sat Feb 17 12:31:29 EST 2024
David Wright
2024-06-28 19:50:01 UTC
Permalink
Post by Greg Wooledge
Post by Stefan Monnier
Post by Greg Wooledge
It's not like you can say "Oh, I was asleep for 7.5234 hours, so I need
to adjust the HW clock time forward by X seconds because I know it runs
a bit slow." That information is not available to you.
It is if /etc/adjtime is set properly when you go to sleep.
See `hwclock(8)` or `adjtime_config(5)`.
Yeah, except... you're assuming a workflow that is not real or reliable.
That's why I wrote "It's not clear to me which NTP (protocol) packages
are set up to use the util-linux stuff, assuming you're not rolling
your own startup/shutdown scripts. (That's the problem in the Subject
line, in a sense.)"

Packages like chrony can set up a workflow that retains the clock
information and makes adjustments to the system clock (and, if
required, the RTC) as necessary.
Post by Greg Wooledge
hobbit:~$ ls -l /etc/adjtime
-rw-r--r-- 1 root root 44 Mar 6 07:04 /etc/adjtime
hobbit:~$ uptime
14:47:40 up 29 days, 2:54, 29 users, load average: 1.58, 1.07, 1.15
Nothing writes to /etc/adjtime on a regular basis. It's only written
if you manually run an hwclock command, or if you change something
(such as deciding to store your HW clock in UTC instead of local time,
which is what I did on March 6 after learning that Debian had chosen
local time when I installed).
Packages like chrony may have an upstream default to use /etc/adjtime,
but AIUI Debian's default is a private, often protected, file.
Post by Greg Wooledge
Post by Stefan Monnier
It is if /etc/adjtime is set properly when you go to sleep.
You cannot assume that adjtime was updated the last time your system
stopped running, because your system might have stopped running due to
a crash, instead of a controlled shutdown.
All of the arguments that are being constructed here are bogus.
You can track the system clock and RTC periodically, and keep the
statistics. Optionally you can also set the RTC at the same time,
but that's not necessary, and a separate decision.
Post by Greg Wooledge
The *only* thing you know at boot time is what's in the HW clock, and
if you're really lucky, you'll be able to figure out what time zone
it's allegedly set to (after reading /etc/adjtime from disk).
hobbit:~$ cat /etc/adjtime
0.000000 1708191089 0.000000
1708191089
UTC
Sat Feb 17 12:31:29 EST 2024
I don't think you've mentioned which package(s) you're using to
control your system clock.

Cheers,
David.
Stefan Monnier
2024-06-28 20:00:02 UTC
Permalink
Post by Greg Wooledge
Yeah, except... you're assuming a workflow that is not real or reliable.
[...]
Post by Greg Wooledge
Post by Stefan Monnier
It is if /etc/adjtime is set properly when you go to sleep.
You cannot assume that adjtime was updated the last time your system
stopped running, because your system might have stopped running due to
a crash, instead of a controlled shutdown.
Notice I wrote "sleep". I'm concerned about the suspend+wakeup case,
not the case when you're booting up.
[ I thought I'd made it abundantly clear. ]


Stefan
Greg Wooledge
2024-06-28 20:30:01 UTC
Permalink
Post by David Wright
Post by Greg Wooledge
The *only* thing you know at boot time is what's in the HW clock, and
if you're really lucky, you'll be able to figure out what time zone
it's allegedly set to (after reading /etc/adjtime from disk).
hobbit:~$ cat /etc/adjtime
0.000000 1708191089 0.000000
1708191089
UTC
Sat Feb 17 12:31:29 EST 2024
I don't think you've mentioned which package(s) you're using to
control your system clock.
I'm using ntpsec.
Post by David Wright
Notice I wrote "sleep". I'm concerned about the suspend+wakeup case,
not the case when you're booting up.
[ I thought I'd made it abundantly clear. ]
I'm not a laptop person. I don't know how to fix laptop-specific issues.

And I'm pretty convinced this is a highly laptop-specific issue, disguised
as a question about /etc/adjtime. An X-Y problem, for sure.

If I'm understanding correctly, the problem you want to solve is as
follows:

1) You are using a laptop.

2) Your laptop's hardware clock drifts quite notably.

3) At times, you perform a "sleep" or "suspend" or whatever it's called.
This period of not-running-but-not-shut-down-either lasts for long
enough that your clock drift becomes severe.

4) Apparently, the system clock does not advance while in this state.

5) After going from the not-running state to the running state, your
system clock is reinitialized from the hardware clock. Which is
not accurate enough for your purposes.

6) After going from the not-running state to the running state, your
NTP daemon does not perform a clock synchronization soon enough for
your purposes. User programs have already begun to run. Or continue
to run? I have absolutely no idea what goes on here.

Now, for some reason, you have become fixated on the /etc/adjtime file,
which may or may not be an appropriate way to mitigate the problem.
I have doubts.

It sounds like whatever least-bad solution you end up using is going to
depend on which NTP daemon you use, and will involve configuration
thereof. It will not be something generic to adjtime_config(5) or
hwclock(8) or util-linux. It also won't be something generic to Debian
systems as a whole, because neither servers nor traditional desktop
computers have this issue. It's a laptop issue.

David has said that chrony can do fancy things involving the hardware
clock. Maybe you should investigate that solution path.
Stefan Monnier
2024-06-28 21:10:01 UTC
Permalink
Post by Greg Wooledge
Post by Stefan Monnier
Notice I wrote "sleep". I'm concerned about the suspend+wakeup case,
not the case when you're booting up.
[ I thought I'd made it abundantly clear. ]
I'm not a laptop person. I don't know how to fix laptop-specific issues.
FWIW, the offending machine is a desktop.
I `suspend` most of my machines, whether desktops or laptops.
Only servers never sleep.
Post by Greg Wooledge
1) You are using a laptop.
It's not the case, but it shouldn't make any difference anyway.
Feel free to assume it's the case.
Post by Greg Wooledge
2) Your laptop's hardware clock drifts quite notably.
Right. Tho, AFAICT the same holds (to a lesser extent) of most machines.
Post by Greg Wooledge
3) At times, you perform a "sleep" or "suspend" or whatever it's called.
This period of not-running-but-not-shut-down-either lasts for long
enough that your clock drift becomes severe.
At least severe enough that I'd like to reduce it.
Post by Greg Wooledge
4) Apparently, the system clock does not advance while in this state.
While suspended, the machine's CPU is completely off.
Only the DRAM is still powered.
[ BTW, I suspect the same problem shows up for "suspend to disk" a.k.a
hibernate where the machine might be 100% turned off while sleeping,
but it might go through slightly different routes in the code. ]
Post by Greg Wooledge
5) After going from the not-running state to the running state, your
system clock is reinitialized from the hardware clock. Which is
not accurate enough for your purposes.
Apparently, yes. I don't actually know how/who reads the RTC to set the
system clock upon wakeup. Maybe `hwclock` is not involved at all, and
maybe part of this happens directly in the kernel.
Post by Greg Wooledge
6) After going from the not-running state to the running state, your
NTP daemon does not perform a clock synchronization soon enough for
your purposes. User programs have already begun to run. Or continue
to run? I have absolutely no idea what goes on here.
Yes they just continue running "as if" the machine had never been turned
off (to them, it's mostly as if the scheduler had given priority to
other tasks for a *long* time).
Post by Greg Wooledge
Now, for some reason, you have become fixated on the /etc/adjtime file,
Not at all. I only mention that file because that's the way this
problem used to be handled during shutdown+reboot back in the SysV-init
days using `/etc/init.d/hwclock.sh`.
Post by Greg Wooledge
It sounds like whatever least-bad solution you end up using is going to
depend on which NTP daemon you use, and will involve configuration
thereof.
Actually, I think The Right Solution™ should be independent from any NTP
daemon, since in order to avoid time warps you'd like to drift-adjust
the RTC time before user-level processes (like the NTP daemon) are
woken up.
Post by Greg Wooledge
It will not be something generic to adjtime_config(5) or
hwclock(8) or util-linux. It also won't be something generic to Debian
systems as a whole, because neither servers nor traditional desktop
computers have this issue. It's a laptop issue.
Nowadays, there's not much difference between a desktop and a laptop
(they all use the same power-saving tricks, they all support suspending
the system, ...).

The problem does not affect servers, admittedly.
Post by Greg Wooledge
David has said that chrony can do fancy things involving the hardware
clock. Maybe you should investigate that solution path.
I'm trying to find out how to fix it Right, rather than how to work
around the problem (I already know how to work around the problem).

Fixing it right requires changing the code that reads the RTC time
upon wakeup. In any case, thank you all for your help.
Apparently none of you have the answer I'm looking for, but you did help
me narrow down the scope and make more precise what I'm after.

Indeed I see now that the time is read from RTC to set system time
directly by the kernel in `kernel/time/timekeeping.c` and
`drivers/rtc/class.c`.
So The Right Solution™ apparently involves changes to the kernel.


Stefan
David Wright
2024-06-29 00:10:01 UTC
Permalink
Post by Stefan Monnier
Post by Greg Wooledge
David has said that chrony can do fancy things involving the hardware
clock. Maybe you should investigate that solution path.
I'm trying to find out how to fix it Right, rather than how to work
around the problem (I already know how to work around the problem).
Fixing it right requires changing the code that reads the RTC time
upon wakeup. In any case, thank you all for your help.
Apparently none of you have the answer I'm looking for, but you did help
me narrow down the scope and make more precise what I'm after.
Indeed I see now that the time is read from RTC to set system time
directly by the kernel in `kernel/time/timekeeping.c` and
`drivers/rtc/class.c`.
So The Right Solution™ apparently involves changes to the kernel.
I can only suggest what you might investigate, as the concepts are
way above my paygrade.

All the user processes are in user.slice, as seen by:

# systemd-cgls -u user.slice

There are commands shown in man systemctl called
freeze and thaw (its inverse):

freeze PATTERN...
Freeze one or more units specified on the command line using
cgroup freezer

Freezing the unit will cause all processes contained within
the cgroup corresponding to the unit to be suspended. Being
suspended means that unit's processes won't be scheduled to
run on CPU until thawed. Note that this command is supported
only on systems that use unified cgroup hierarchy. Unit is
automatically thawed just before we execute a job against the
unit, e.g. before the unit is stopped.

So could you suspend the system by invoking a system service to
freeze the control group the appropriate unit (user.slice) first?
When the system resumes, the thawing service would be set to run
after the service that steps the clock. (Don't use slewing.)

Cheers,
David.
Charles Curley
2024-06-29 04:00:01 UTC
Permalink
On Thu, 27 Jun 2024 12:48:03 -0400
Post by Stefan Monnier
I have a machine whose RTC clock is drifting significantly and it is
often suspended for several days. I run NTP so the drift I see when
I wake the machine up gets fixed by "stepping" the clock after a
while, but that can take a while and I'd like to improve this
intermediate situation.
It seems to me that a lot of people much smarter than I have have
wrestled with this problem for more than 50 years, and still don't have
an instantaneous solution.

Other solutions:

* Don't suspend the machine. Problem solved.

* If you must suspend the machine, bring it up some reasonable length
of time before you require accuracy from your clock. Problem solved.

* Invest in a decent GPS receiver, and install chrony and gpsd on the
machine. Doing so may get the system clock in synch faster; it may
not. Doing that sort of thing is well documented on the gpsd home
page.
--
Does anybody read signatures any more?

https://charlescurley.com
https://charlescurley.com/blog/
Charles Curley
2024-06-29 16:50:01 UTC
Permalink
On Sat, 29 Jun 2024 16:39:14 +0100
Post by Charles Curley
* Invest in a decent GPS receiver, and install chrony and gpsd on
the machine. Doing so may get the system clock in synch faster; it
may not. Doing that sort of thing is well documented on the gpsd
home page.
Wouldn't you need to know how fast the laptop is travelling?
Unless it's in low earth orbit, probably not. It may take longer to get
a fix, but that's all.
--
Does anybody read signatures any more?

https://charlescurley.com
https://charlescurley.com/blog/
Loading...