mirror of
				https://github.com/siderolabs/talos.git
				synced 2025-11-04 02:11:12 +01:00 
			
		
		
		
	This is a complete rewrite of time sync process. Now the time sync process starts early at boot time, and it adapts to configuration changes: * before config is available, `pool.ntp.org` is used * once config is available, configured time servers are used Controller updates same time sync resource as other controllers had dependency on, so they have a chance to wait for the time sync event. Talos services which depend on time now wait on same resource instead of waiting on timed health. New features: * time sync now sticks to the particular time server unless there's an error from that server, and server is changed in that case, this improves time sync accuracy * time sync acts on config changes immediately, so it's possible to reconfigure time sync at any time * there's a new 'epoch' field in time sync resources which allows time-dependent controllers to regenerate certs when there's a big enough jump in time Features to implement later: * apid shouldn't depend on timed, it should be started early and it should regenerate certs on time jump * trustd should be updated in same way Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
		
			
				
	
	
		
			109 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
// License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
						|
 | 
						|
// Package timex provides a simple wrapper around adjtimex syscall.
 | 
						|
package timex
 | 
						|
 | 
						|
import (
 | 
						|
	"strings"
 | 
						|
	"syscall"
 | 
						|
)
 | 
						|
 | 
						|
// Values for timex.mode.
 | 
						|
//
 | 
						|
//nolint:golint,stylecheck,revive
 | 
						|
const (
 | 
						|
	ADJ_OFFSET    = 0x0001
 | 
						|
	ADJ_FREQUENCY = 0x0002
 | 
						|
	ADJ_MAXERROR  = 0x0004
 | 
						|
	ADJ_ESTERROR  = 0x0008
 | 
						|
	ADJ_STATUS    = 0x0010
 | 
						|
	ADJ_TIMECONST = 0x0020
 | 
						|
	ADJ_TAI       = 0x0080
 | 
						|
	ADJ_SETOFFSET = 0x0100
 | 
						|
	ADJ_MICRO     = 0x1000
 | 
						|
	ADJ_NANO      = 0x2000
 | 
						|
	ADJ_TICK      = 0x4000
 | 
						|
)
 | 
						|
 | 
						|
// Status is bitmask field of statuses.
 | 
						|
type Status int32
 | 
						|
 | 
						|
// Clock statuses.
 | 
						|
//
 | 
						|
//nolint:golint,stylecheck,revive
 | 
						|
const (
 | 
						|
	STA_PLL       = 0x0001 /* enable PLL updates (rw) */
 | 
						|
	STA_PPSFREQ   = 0x0002 /* enable PPS freq discipline (rw) */
 | 
						|
	STA_PPSTIME   = 0x0004 /* enable PPS time discipline (rw) */
 | 
						|
	STA_FLL       = 0x0008 /* select frequency-lock mode (rw) */
 | 
						|
	STA_INS       = 0x0010 /* insert leap (rw) */
 | 
						|
	STA_DEL       = 0x0020 /* delete leap (rw) */
 | 
						|
	STA_UNSYNC    = 0x0040 /* clock unsynchronized (rw) */
 | 
						|
	STA_FREQHOLD  = 0x0080 /* hold frequency (rw) */
 | 
						|
	STA_PPSSIGNAL = 0x0100 /* PPS signal present (ro) */
 | 
						|
	STA_PPSJITTER = 0x0200 /* PPS signal jitter exceeded (ro) */
 | 
						|
	STA_PPSWANDER = 0x0400 /* PPS signal wander exceeded (ro) */
 | 
						|
	STA_PPSERROR  = 0x0800 /* PPS signal calibration error (ro) */
 | 
						|
	STA_CLOCKERR  = 0x1000 /* clock hardware fault (ro) */
 | 
						|
	STA_NANO      = 0x2000 /* resolution (0 = us, 1 = ns) (ro) */
 | 
						|
	STA_MODE      = 0x4000 /* mode (0 = PLL, 1 = FLL) (ro) */
 | 
						|
	STA_CLK       = 0x8000 /* clock source (0 = A, 1 = B) (ro) */
 | 
						|
)
 | 
						|
 | 
						|
func (status Status) String() string {
 | 
						|
	var labels []string
 | 
						|
 | 
						|
	for bit, label := range map[Status]string{
 | 
						|
		STA_PLL:       "STA_PLL",
 | 
						|
		STA_PPSFREQ:   "STA_PPSFREQ",
 | 
						|
		STA_PPSTIME:   "STA_PPSTIME",
 | 
						|
		STA_FLL:       "STA_FLL",
 | 
						|
		STA_INS:       "STA_INS",
 | 
						|
		STA_DEL:       "STA_DEL",
 | 
						|
		STA_UNSYNC:    "STA_UNSYNC",
 | 
						|
		STA_FREQHOLD:  "STA_FREQHOLD",
 | 
						|
		STA_PPSSIGNAL: "STA_PPSSIGNAL",
 | 
						|
		STA_PPSJITTER: "STA_PPSJITTER",
 | 
						|
		STA_PPSWANDER: "STA_PPSWANDER",
 | 
						|
		STA_PPSERROR:  "STA_PPSERROR",
 | 
						|
		STA_CLOCKERR:  "STA_CLOCKERR",
 | 
						|
		STA_NANO:      "STA_NANO",
 | 
						|
		STA_MODE:      "STA_MODE",
 | 
						|
		STA_CLK:       "STA_CLK",
 | 
						|
	} {
 | 
						|
		if (status & bit) == bit {
 | 
						|
			labels = append(labels, label)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return strings.Join(labels, " | ")
 | 
						|
}
 | 
						|
 | 
						|
// State is clock state.
 | 
						|
type State int
 | 
						|
 | 
						|
// Clock states.
 | 
						|
//
 | 
						|
//nolint:golint,stylecheck,revive
 | 
						|
const (
 | 
						|
	TIME_OK State = iota
 | 
						|
	TIME_INS
 | 
						|
	TIME_DEL
 | 
						|
	TIME_OOP
 | 
						|
	TIME_WAIT
 | 
						|
	TIME_ERROR
 | 
						|
)
 | 
						|
 | 
						|
func (state State) String() string {
 | 
						|
	return [...]string{"TIME_OK", "TIME_INS", "TIME_DEL", "TIME_OOP", "TIME_WAIT", "TIME_ERROR"}[int(state)]
 | 
						|
}
 | 
						|
 | 
						|
// Adjtimex provides a wrapper around syscall.Adjtimex.
 | 
						|
func Adjtimex(buf *syscall.Timex) (state State, err error) {
 | 
						|
	st, err := syscall.Adjtimex(buf)
 | 
						|
 | 
						|
	return State(st), err
 | 
						|
}
 |