Skip to content

Commit

Permalink
timeutil/ptp: fix conversion from seconds to Time
Browse files Browse the repository at this point in the history
Epic: none
Release note (bug fix): since 22.2.0, using a PTP clock device (enabled by the
--clock-device flag) would generate timestamps in the far future. It now
generates the correct time. This could cause nodes to crash due to incorrect
timestamps, or in the worst case irreversibly advance the cluster's HLC clock
into the far future.
  • Loading branch information
pav-kv committed Aug 3, 2023
1 parent 36665f6 commit 2f8cd09
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 2 deletions.
2 changes: 2 additions & 0 deletions pkg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ ALL_TESTS = [
"//pkg/util/timeofday:timeofday_test",
"//pkg/util/timetz:timetz_test",
"//pkg/util/timeutil/pgdate:pgdate_test",
"//pkg/util/timeutil/ptp:ptp_test",
"//pkg/util/timeutil:timeutil_test",
"//pkg/util/tochar:tochar_test",
"//pkg/util/tracing/collector:collector_test",
Expand Down Expand Up @@ -2416,6 +2417,7 @@ GO_TARGETS = [
"//pkg/util/timeutil/pgdate:pgdate",
"//pkg/util/timeutil/pgdate:pgdate_test",
"//pkg/util/timeutil/ptp:ptp",
"//pkg/util/timeutil/ptp:ptp_test",
"//pkg/util/timeutil:timeutil",
"//pkg/util/timeutil:timeutil_test",
"//pkg/util/tochar:tochar",
Expand Down
18 changes: 17 additions & 1 deletion pkg/util/timeutil/ptp/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "ptp",
Expand Down Expand Up @@ -59,3 +59,19 @@ go_library(
"//conditions:default": [],
}),
)

go_test(
name = "ptp_test",
srcs = ["ptp_clock_linux_test.go"],
args = ["-test.timeout=295s"],
embed = [":ptp"],
deps = select({
"@io_bazel_rules_go//go/platform:android": [
"//pkg/util/timeutil",
],
"@io_bazel_rules_go//go/platform:linux": [
"//pkg/util/timeutil",
],
"//conditions:default": [],
}),
)
7 changes: 6 additions & 1 deletion pkg/util/timeutil/ptp/ptp_clock_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,10 @@ func (p Clock) Now() time.Time {
panic(err)
}

return timeutil.Unix(int64(ts.tv_sec)*1e9, int64(ts.tv_nsec))
return timeutil.Unix(int64(ts.tv_sec), int64(ts.tv_nsec))
}

// realtime returns a clock using the system CLOCK_REALTIME device. For testing.
func realtime() Clock {
return Clock{clockDeviceID: uintptr(C.CLOCK_REALTIME)}
}
30 changes: 30 additions & 0 deletions pkg/util/timeutil/ptp/ptp_clock_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

//go:build linux
// +build linux

package ptp

import (
"testing"
"time"

"github.com/cockroachdb/cockroach/pkg/util/timeutil"
)

// TestClockNow sanity checks that Clock.Now() sourced from the CLOCK_REALTIME
// device returns time close to timeutil.Now(). This ensures that the conversion
// from the time returned by a clock device to Go's time.Time is correct.
func TestClockNow(t *testing.T) {
if got, want := realtime().Now(), timeutil.Now(); want.Sub(got).Abs() > 10*time.Second {
t.Errorf("clock mismatch: got %v; timeutil says %v", got, want)
}
}

0 comments on commit 2f8cd09

Please sign in to comment.