From b11429d77e448c941bbab2a364a443400e4d7a22 Mon Sep 17 00:00:00 2001 From: Anastasios Papagiannis Date: Thu, 1 Feb 2024 10:40:55 +0000 Subject: [PATCH] Compute a stable start_time We first calculate the boot time of the Linux. Then we add to that whatever we get from the kernel space. Signed-off-by: Anastasios Papagiannis --- cmd/tetragon/main.go | 3 +++ pkg/ktime/ktime.go | 37 +++++++++++++++++++++++++++++++++++++ pkg/process/process.go | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/cmd/tetragon/main.go b/cmd/tetragon/main.go index dda58023f8c..2719ccdc0c8 100644 --- a/cmd/tetragon/main.go +++ b/cmd/tetragon/main.go @@ -35,6 +35,7 @@ import ( "github.com/cilium/tetragon/pkg/fileutils" "github.com/cilium/tetragon/pkg/filters" tetragonGrpc "github.com/cilium/tetragon/pkg/grpc" + "github.com/cilium/tetragon/pkg/ktime" "github.com/cilium/tetragon/pkg/logger" "github.com/cilium/tetragon/pkg/metrics" "github.com/cilium/tetragon/pkg/metrics/metricsconfig" @@ -147,6 +148,8 @@ func tetragonExecute() error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + ktime.InitializeBootTime() + sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, tgsyscall.SIGRTMIN_20, tgsyscall.SIGRTMIN_21, tgsyscall.SIGRTMIN_22) diff --git a/pkg/ktime/ktime.go b/pkg/ktime/ktime.go index 84f8de760ca..22ddd4205b8 100644 --- a/pkg/ktime/ktime.go +++ b/pkg/ktime/ktime.go @@ -4,6 +4,7 @@ package ktime import ( + "sort" "time" "github.com/sirupsen/logrus" @@ -11,6 +12,32 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) +var ( + bootTime int64 +) + +func InitializeBootTime() { + var times []int64 + + // Try to get the linux boot time in a microsecond resolution. + // As there are 2 calls to get the time "time.Now()" and "unix.ClockGettime" + // we have a race. So we run this 1024 times and we keep the lowest value. + // We expect after tetragon restart to always get the same value. + for i := 0; i < 1024; i++ { + now := time.Now() + currentTime := unix.Timespec{} + if err := unix.ClockGettime(int32(unix.CLOCK_BOOTTIME), ¤tTime); err != nil { + continue + } + + t := time.Unix(currentTime.Sec, currentTime.Nsec).UnixMicro() + b := now.UnixMicro() + times = append(times, b-t) + } + sort.Slice(times, func(i, j int) bool { return times[i] < times[j] }) + bootTime = times[0] +} + func ToProto(ktime uint64) *timestamppb.Timestamp { return ToProtoOpt(ktime, true) } @@ -37,6 +64,7 @@ func NanoTimeSince(ktime int64) (time.Duration, error) { diff := currentTime.Nano() - ktime return time.Duration(diff), nil } + func DecodeKtime(ktime int64, monotonic bool) (time.Time, error) { var clk int32 if monotonic { @@ -52,3 +80,12 @@ func DecodeKtime(ktime int64, monotonic bool) (time.Time, error) { t := time.Now().Add(time.Duration(diff)) return t, nil } + +func DecodeKtimeStable(ktime int64) time.Time { + return time.UnixMicro(bootTime + ktime) +} + +func ToProtoOptStable(ktime uint64) *timestamppb.Timestamp { + decodedTime := DecodeKtimeStable(int64(ktime) / 1000) // nano to micro + return timestamppb.New(decodedTime) +} diff --git a/pkg/process/process.go b/pkg/process/process.go index 2f31901ecde..d6dd23eec54 100644 --- a/pkg/process/process.go +++ b/pkg/process/process.go @@ -358,7 +358,7 @@ func initProcessInternalExec( Binary: binary, Arguments: args, Flags: strings.Join(exec.DecodeCommonFlags(process.Flags), " "), - StartTime: ktime.ToProtoOpt(process.Ktime, (process.Flags&api.EventProcFS) == 0), + StartTime: ktime.ToProtoOptStable(process.Ktime), Auid: &wrapperspb.UInt32Value{Value: process.AUID}, Pod: protoPod, ExecId: execID,