Skip to content

Commit 5a04229

Browse files
authored
Merge pull request #490 from mikluko/feature/hwclocksync
Add hwclock sync loop to the guestagent
2 parents d7cf23c + 9d2bb68 commit 5a04229

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

pkg/guestagent/guestagent_linux.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/lima-vm/lima/pkg/guestagent/api"
1414
"github.com/lima-vm/lima/pkg/guestagent/iptables"
1515
"github.com/lima-vm/lima/pkg/guestagent/procnettcp"
16+
"github.com/lima-vm/lima/pkg/guestagent/timesync"
1617
"github.com/sirupsen/logrus"
1718
"github.com/yalue/native_endian"
1819
)
@@ -37,6 +38,7 @@ func New(newTicker func() (<-chan time.Time, func()), iptablesIdle time.Duration
3738
}
3839

3940
go a.setWorthCheckingIPTablesRoutine(auditClient, iptablesIdle)
41+
go a.fixSystemTimeSkew()
4042
return a, nil
4143
}
4244

@@ -244,3 +246,31 @@ func (a *agent) Info(ctx context.Context) (*api.Info, error) {
244246
}
245247
return &info, nil
246248
}
249+
250+
const deltaLimit = 2 * time.Second
251+
252+
func (a *agent) fixSystemTimeSkew() {
253+
for {
254+
ticker := time.NewTicker(10 * time.Second)
255+
for now := range ticker.C {
256+
rtc, err := timesync.GetRTCTime()
257+
if err != nil {
258+
logrus.Warnf("fixSystemTimeSkew: lookup error: %s", err.Error())
259+
continue
260+
}
261+
d := rtc.Sub(now)
262+
logrus.Debugf("fixSystemTimeSkew: rtc=%s systime=%s delta=%s",
263+
rtc.Format(time.RFC3339), now.Format(time.RFC3339), d)
264+
if d > deltaLimit || d < -deltaLimit {
265+
err = timesync.SetSystemTime(rtc)
266+
if err != nil {
267+
logrus.Warnf("fixSystemTimeSkew: set system clock error: %s", err.Error())
268+
continue
269+
}
270+
logrus.Infof("fixSystemTimeSkew: system time synchronized with rtc")
271+
break
272+
}
273+
}
274+
ticker.Stop()
275+
}
276+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package timesync
2+
3+
import (
4+
"os"
5+
"time"
6+
7+
"golang.org/x/sys/unix"
8+
)
9+
10+
const rtc = "/dev/rtc"
11+
12+
func GetRTCTime() (t time.Time, err error) {
13+
f, err := os.Open(rtc)
14+
if err != nil {
15+
return
16+
}
17+
defer f.Close()
18+
obj, err := unix.IoctlGetRTCTime(int(f.Fd()))
19+
if err != nil {
20+
return
21+
}
22+
t = time.Date(int(obj.Year+1900), time.Month(obj.Mon+1), int(obj.Mday), int(obj.Hour), int(obj.Min), int(obj.Sec), 0, time.UTC)
23+
return t, nil
24+
}
25+
26+
func SetSystemTime(t time.Time) error {
27+
v := unix.NsecToTimeval(t.UnixNano())
28+
return unix.Settimeofday(&v)
29+
}

0 commit comments

Comments
 (0)