Skip to content

Commit

Permalink
Compute a stable start_time
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
tpapagian committed Feb 1, 2024
1 parent be64e0b commit b11429d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
3 changes: 3 additions & 0 deletions cmd/tetragon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
37 changes: 37 additions & 0 deletions pkg/ktime/ktime.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,40 @@
package ktime

import (
"sort"
"time"

"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
"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), &currentTime); 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)
}
Expand All @@ -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 {
Expand All @@ -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)
}
2 changes: 1 addition & 1 deletion pkg/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit b11429d

Please sign in to comment.