ADJTIMEX(8)

πŸ“¦
version 1.29 Β· 3 versions
, in debian trixie, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– adjtimex(8) β€” the manual page, but make it a group chat πŸ’–

okay bestie so this is adjtimex, straight out of the System Manager's Manual, and it is the tool for messing with your kernel's time variables. raw access. no filter. let's get into it πŸ•°οΈβœ¨


✨ NAME ✨

adjtimex β€” display or set the kernel time variables. she shows you stuff, or she changes stuff. depending on who you are (spoiler: you gotta be root to change stuff, more on that in a sec) πŸ’…


🌸 SYNOPSIS 🌸

adjtimex [option ...]

that's it. that's the whole vibe. options, plural, optional, iconic ✨


πŸ¦‹ DESCRIPTION πŸ¦‹

so. this program gives you raw access to the kernel time variables. not a cute little wrapper, not a friendly GUI β€” raw. anyone (literally anyone, no cap) may print out the time variables, but only the superuser may change them. so if you're sitting there like "why can't I write to these" β€” that's why, bestie 😭

okay now the important lore 🧚 your computer has two clocks:

  • the "hardware clock" β€” she runs all the time, even when your machine is off. persistent queen πŸ‘‘
  • the system clock β€” she runs only while the computer is on. a little more high-maintenance tbh.

normally, hwclock --hctosys should be run at startup to initialize the system clock. that's the standard move, don't skip it πŸ™ˆ

here's the tea though: the system clock has much better precision (approximately 1 usec), but the hardware clock probably has better long-term stability. so it's giving "short-term precision girlfriend, long-term stability boyfriend" energy, and honestly? we need both.

there are three basic strategies for managing these clocks. let's break them down πŸŽ€

🌈 strategy one: ntpd, the internet girlies

for a machine connected to the Internet, or equipped with a precision oscillator or radio clock, the best way is to regulate the system clock with ntpd(8). and here's the slay part β€” the kernel will automatically update the hardware clock every eleven minutes. eleven!! the kernel is handling it fr fr, you don't have to do a thing πŸ’–

πŸŽ€ strategy two: hwclock --adjust, the manual drift correction

in addition, hwclock(8) can be used to approximately correct for a constant drift in the hardware clock. in this case, hwclock --adjust is run occasionally. here's how it works: hwclock notes how long it has been since the last adjustment, and nudges the hardware clock forward or back by the appropriate amount. little nudge, big difference ✨

the user needs to set the time with hwclock --set several times over the course of a few days so hwclock can estimate the drift rate. yes, several times. yes, over days. it's a whole journey, not a one-night thing 😭

⚠️ warning bestie: during that time, ntpd should not be running, or else hwclock will conclude the hardware clock does not drift at all. two people trying to fix the same clock = chaos πŸ’€

after you have run hwclock --set for the last time, it's okay to start ntpd. then, hwclock --systohc should be run when the machine is shut down.

and now, the explanation, because the original page does NOT gatekeep the reasoning and neither will I 🫢 (to see why, suppose the machine runs for a week with ntpd, is shut down for a day, is restarted, and hwclock --adjust is run by a startup script. it should only correct for one day's worth of drift. however, it has no way of knowing that ntpd has been adjusting the hardware clock, so it bases its adjustment on the last time hwclock was run.) see?? she only knows what she knows 🧚

πŸ“ strategy three: adjtimex, the solo route

for a standalone or intermittently connected machine, where it's not possible to run ntpd, you may use adjtimex instead to correct the system clock for systematic drift. that's the whole point of her, honestly. main character energy πŸ’…


πŸ’œ how to even estimate the drift rate tho

there are several ways to estimate the drift rate. pick your fighter:

  • if your computer can be connected to the net, you might run ntpd for at least several hours and run adjtimex --print to learn what values of tick and freq it settled on. sneak peek of what the internet girlies picked πŸ‘€
  • alternately, you could estimate values using as a reference the CMOS clock β€” see the --compare and --adjust switches.
  • or another host β€” see --host and --review.
  • or some other source of time β€” see --watch and --review.

once you've got your numbers, you could then add a line to rc.local invoking adjtimex, or configure /etc/init.d/adjtimex or /etc/default/adjtimex, to set those parameters each time you reboot. set it and forget it, periodt ⭐


okay that's the whole intro and she ate, ngl. there's more coming bestie, don't go anywhere πŸ’–

okay so, plot twist: options can start with either - or --, and yes bestie, unique abbreviations are allowed. slay.

Here's the whole menu, grouped by vibe. The full tea on every single one comes right after. πŸ’…

🌸 Get/Set Kernel Time Parameters 🌸

  • -p, --print
  • -t val, --tick val
  • -f newfreq, --frequency newfreq
  • -o val, --offset val
  • -s adjustment, --singleshot adjustment
  • -S status, --status status
  • -m val
  • -R, --reset
  • --maxerror val
  • -e val, --esterror val
  • -T val, --timeconstant val
  • -a[count], --adjust[=count]

πŸ¦‹ Estimate Systematic Drifts πŸ¦‹

  • -c[count], --compare[=count]
  • -i tim, --interval tim
  • -l file, --log=file
  • -h timeserver, --host timeserver
  • -w, --watch
  • -r[file], --review[=file]
  • -u, --utc
  • -d, --directisa
  • -n, --nointerrupt

πŸ’– Informative Output πŸ’–

  • --help
  • -v, --version
  • -V, --verbose

-p, --print

Prints out the current values of the kernel time variables. πŸ–¨οΈ

⚠️ NOTE, bestie: the time it shows you is "raw", and it may be off by up to one timer tick (10 msec). don't come for it.

"status" gives you the value of the time_status variable in the kernel. For Linux 1.0 and 1.2 kernels, the value means this:

  • 0 β€” clock is synchronized (so the kernel should periodically set the CMOS clock to match the system clock)
  • 1 β€” inserting a leap second at midnight
  • 2 β€” deleting a leap second at midnight
  • 3 β€” leap second in progress
  • 4 β€” leap second has occurred
  • 5 β€” clock not externally synchronized (so the kernel should leave the CMOS clock alone)

For Linux kernels 2.0 through 2.6, the value is a sum of these:

  • 1 β€” PLL updates enabled
  • 2 β€” PPS freq discipline enabled
  • 4 β€” PPS time discipline enabled
  • 8 β€” frequency-lock mode enabled
  • 16 β€” inserting leap second
  • 32 β€” deleting leap second
  • 64 β€” clock unsynchronized
  • 128 β€” holding frequency
  • 256 β€” PPS signal present
  • 512 β€” PPS signal jitter exceeded
  • 1024 β€” PPS signal wander exceeded
  • 2048 β€” PPS signal calibration error
  • 4096 β€” clock hardware fault
  • The following status value are appended since 2.6.26 (July 2008):
  • 8192 β€” resolution (0 = us, 8192 = ns)
  • 16384 β€” mode (0 = PLL, 16384 = FLL)
  • 32768 β€” clock source (0 = A, 32768 = B)

-t val, --tick val

Sets how many microseconds get added to the system time for each kernel tick interrupt, fr fr.

For a kernel with USER_HZ=100, there are supposed to be 100 ticks per second, so val should be close to 10000. Bumping val up by 1 speeds up the system clock by about 100 ppm, or 8.64 sec/day β€” it's giving minor but mighty. πŸ’…

tick must be in the range 900000/USER_HZ to 1100000/USER_HZ. If the kernel rejects your val, adjtimex will figure out the acceptable range through trial and error and print it for you. (And yes, after it finishes the search, it restores the original value. considerate king.) πŸ‘‘

-f newfreq, --frequency newfreq

Sets the system clock frequency offset to newfreq. newfreq can be negative or positive, and it gives a much finer adjustment than the --tick switch does.

When USER_HZ=100, the value is scaled such that newfreq = 65536 speeds up the system clock by about 1 ppm, or 0.0864 sec/day. So all of these are about the same, no cap:

--tick  9995 --frequency  32768000
--tick 10000 --frequency         0
--tick 10001 --frequency  -6553600
--tick 10002 --frequency -13107200
--tick 10005 --frequency -32768000

To see the acceptable range for newfreq, use --print and look at "tolerance", or just try an invalid value (e.g., --tick 0). chaos method works. πŸ’€

-s adj, --singleshot adj

Slews the system clock by adj usec or nsec (using whichever unit the clock is presently denominated in). Its rate is changed temporarily by about 1 part in 2000. little nudge, big vibes. 🫢

-o adj, --offset adj

Adds a time offset of adj usec or nsec (again, using whichever unit the clock is presently denominated in).

The kernel code adjusts the time gradually by adj, notes how long it's been since the last time offset, and then adjusts the frequency offset to correct for the apparent drift. adj must be in the range -512000 to 512000.

-S status, --status status

Sets the kernel system clock status register to the value status. For what status actually means, look up at the --print switch section above β€” it depends on your kernel. 🧚

-R, --reset

Resets the clock status after setting a clock parameter.

For early Linux kernels, using the adjtimex(2) system call to set any time parameter makes the kernel think the clock is synchronized with an external time source, so it sets the kernel variable time_status to TIME_OK. After that, at 11 minute intervals, it will adjust the CMOS clock to match. 😭

We prevent this "eleven minute mode" by setting the clock, because that has the side effect of resetting time_status to TIME_BAD. We try not to actually change the clock setting though. Kernel versions 2.0.40 and later apparently don't need this. If your kernel does require it, use this option with:

-t -T -t -e -m -f -s -o -c -r

-m val, --maxerror val

Sets maximum error (usec). ✨

-e val, --esterror val

Sets estimated error (usec).

The maximum and estimated error are not used by the kernel at all β€” they're merely made available to user processes via the adjtimex(2) system call. decorative, honestly. πŸŽ€

-T val, --timeconstant val

Sets the phase locked loop (PLL) time constant. val determines the bandwidth, aka the "stiffness", of the PLL.

The effective PLL time constant will be a multiple of (2^val). For room-temperature quartz oscillators, David Mills recommends the value 2, which corresponds to a PLL time constant of about 900 sec and a maximum update interval of about 64 sec. The maximum update interval scales directly with the time constant, so at the maximum time constant of 6, the update interval can be as large as 1024 sec.

Values of val between zero and 2 give quick convergence; values between 2 and 6 can be used to reduce network load, but at a modest cost in accuracy.

-c[count], --compare[=count]

Periodically compares the system clock with the CMOS clock. πŸ•

After the first two calls, it prints values for tick and frequency offset that would bring the system clock into approximate agreement with the CMOS clock. CMOS clock readings are adjusted for systematic drift using the correction in /etc/adjtime β€” see hwclock(8).

The interval between comparisons is 10 seconds, unless you change it with the --interval switch. The optional argument is the number of comparisons. (If the argument is supplied, the = is required β€” do not skip it bestie.)

If the CMOS clock and the system clock differ by more than six minutes, adjtimex will try shifting the time from the CMOS clock by some multiple of one hour, up to plus or minus 13 hours in all. This should allow correct operation, including logging, if the --utc switch was used when the CMOS clock is set to local time (or vice-versa), or if summer time has started or stopped since the CMOS clock was last set. flexible icon behavior. 🌈

-a[count], --adjust[=count]

By itself, it's the same as --compare, except the recommended values are actually installed after every third comparison. πŸ‘‘

With --review, the tick and frequency are set to the least-squares estimates. (In that latter case, any count value is ignored. sorry girl.)

--force-adjust

Overrides the sanity check that prevents changing the clock rate by more than 500 ppm.

bestie this one is literally named "force". you are overriding the safety rail. proceed with intention.

-i tim, --interval tim

Sets the interval in seconds between clock comparisons for the --compare and --adjust options. ⏱️

-u, --utc

The CMOS clock is set to UTC (universal time) rather than local time. 🌍

-d, --directisa

To read the CMOS clock accurately, adjtimex usually accesses the clock via the /dev/rtc device driver of the kernel, and makes use of its CMOS update-ended interrupt to detect the beginning of seconds. It will also try /dev/rtc0 (for udev), /dev/misc/rtc (for the obsolete devfs) and possibly others.

When the /dev/rtc driver is absent, or when the interrupt is not available, adjtimex can sometimes automatically fallback to a direct access method. This method detects the start of seconds by polling the update-in-progress (UIP) flag of the CMOS clock. You can force this direct access to the CMOS chip with the --directisa switch.

Note that the /dev/rtc interrupt method is more accurate, less sensible to perturbations due to system load, cleaner, cheaper, and is generally better than the direct access method. πŸ’… It is advisable to not use the --directisa switch, unless the CMOS chip or the motherboard don't properly provide the necessary interrupt.

-n, --nointerrupt

Forces immediate use of the busywait access method, without first waiting for the interrupt timeout. impatient girlie energy, valid. πŸ™ˆ

-l[file], --log[=file]

Saves the current values of the system and CMOS clocks, and optionally a reference time, to file (default /var/log/clocks.log). The reference time is taken from a network timeserver (see the --host switch) or supplied by the user (see the --watch switch). πŸ“

-h timeserver, --host timeserver

Uses ntpdate to query the given timeserver for the current time. This will fail if timeserver is not running a Network Time Protocol (NTP) server, or if that server is not synchronized. Implies --log.

-w, --watch

Asks for a keypress when the user knows the time, then asks what that time was, and its approximate accuracy. Implies --log. interactive bestie moment. ⌨️

-r[file], --review[=file]

Reviews the clock log file (default /var/log/clocks.log) and estimates, if possible, the rates of the CMOS and system clocks.

It calculates least-squares rates using all suitable log entries, then suggests corrections to adjust for systematic drift. With --adjust, the frequency and tick are set to the suggested values. (The CMOS clock correction is not changed.) πŸ¦‹

-V, --verbose

Increases verbosity. louder. πŸ“’

--help

Prints the program options. we love a helpful queen. πŸ’–

-v, --version

Prints the program version. ✨

🌸 EXAMPLES 🌸

okay so picture this bestie: your system clock is being a lil drama queen and it gained 8 seconds in 24 hours. rude. so here's the fix β€” you could set the tick to 9999, and then it would lose 0.64 seconds a day. (and that's = 1 tick unit = 8.64 seconds per day, just so we're clear on the math πŸ’…)

now to correct the rest of the error, you could set the frequency offset to:

(2^16)*0.64/.0864 = 485452

so like, putting this in rc.local would approximately correct the system clock:

adjtimex  --tick 9999  --freq 485452

periodt. your clock is healed, she's thriving πŸ’–


πŸ“ NOTES πŸ“

okay important thing, bestie, don't skip this one:

adjtimex adjusts only the system clock β€” like, the one that runs while the computer is powered up. that's the whole thing she does.

if you wanna set or regulate the CMOS clock instead? that's a different girl. go see hwclock(8). 🫢


πŸ‘‘ AUTHORS πŸ‘‘

these iconic legends built her:

  • Steven S. Dick <ssd at nevets.oau.org>
  • Jim Van Zandt <jrv at comcast.net>

thank you for your service 🫑✨


πŸ”— SEE ALSO πŸ”—

the bestie extended universe, fr fr:

and the lore files β€” in the directory /usr/src/linux/include/linux:

  • timex.h
  • sched.h

in the directory /usr/src/linux/kernel:

  • time.c
  • sched.c

and that's the whole page, babe 🌈 go forth and keep your clock immaculate. slay πŸ’…

this diva of a manpage is from March 11, 2009 and lives under ADJTIMEX(8) β€” yes she's been iconic since '09 and she's still serving πŸŽ€πŸ’–

πŸ“¦ where this page comes from