Skip to content

Commit 18d3abd

Browse files
chore: refactor time pkg
1 parent 34238f1 commit 18d3abd

File tree

2 files changed

+99
-49
lines changed

2 files changed

+99
-49
lines changed

pkg/ebpf/tracee.go

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -520,25 +520,7 @@ func (t *Tracee) Init(ctx gocontext.Context) error {
520520

521521
t.validateKallsymsDependencies() // disable events w/ missing ksyms dependencies
522522

523-
// Initialize event derivation logic
524-
525-
err = t.initDerivationTable()
526-
if err != nil {
527-
return errfmt.Errorf("error initializing event derivation map: %v", err)
528-
}
529-
530-
// Initialize events parameter types map
531-
532-
t.eventsParamTypes = make(map[events.ID][]bufferdecoder.ArgType)
533-
for _, eventDefinition := range events.Core.GetDefinitions() {
534-
id := eventDefinition.GetID()
535-
params := eventDefinition.GetParams()
536-
for _, param := range params {
537-
t.eventsParamTypes[id] = append(t.eventsParamTypes[id], bufferdecoder.GetParamType(param.Type))
538-
}
539-
}
540-
541-
// Initialize time normalizer
523+
// Initialize time
542524

543525
// Checking the kernel symbol needs to happen after obtaining the capability;
544526
// otherwise, we get a warning.
@@ -562,13 +544,37 @@ func (t *Tracee) Init(ctx gocontext.Context) error {
562544
return errfmt.WrapError(err)
563545
}
564546

547+
// init time functionalities
548+
err = traceetime.Init(int32(usedClockID))
549+
if err != nil {
550+
return errfmt.WrapError(err)
551+
}
552+
565553
// elapsed time in nanoseconds since system start
566-
t.startTime = uint64(traceetime.GetStartTimeNS(int32(usedClockID)))
554+
t.startTime = uint64(traceetime.GetStartTimeNS())
567555
// time in nanoseconds when the system was booted
568-
t.bootTime = uint64(traceetime.GetBootTimeNS(int32(usedClockID)))
556+
t.bootTime = uint64(traceetime.GetBootTimeNS())
569557

570558
t.timeNormalizer = traceetime.CreateTimeNormalizerByConfig(t.config.Output.RelativeTime, t.startTime, t.bootTime)
571559

560+
// Initialize event derivation logic
561+
562+
err = t.initDerivationTable()
563+
if err != nil {
564+
return errfmt.Errorf("error initializing event derivation map: %v", err)
565+
}
566+
567+
// Initialize events parameter types map
568+
569+
t.eventsParamTypes = make(map[events.ID][]bufferdecoder.ArgType)
570+
for _, eventDefinition := range events.Core.GetDefinitions() {
571+
id := eventDefinition.GetID()
572+
params := eventDefinition.GetParams()
573+
for _, param := range params {
574+
t.eventsParamTypes[id] = append(t.eventsParamTypes[id], bufferdecoder.GetParamType(param.Type))
575+
}
576+
}
577+
572578
// Initialize Process Tree (if enabled)
573579

574580
if t.config.ProcTree.Source != proctree.SourceNone {

pkg/time/time.go

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ import (
1818
"github.com/aquasecurity/tracee/pkg/utils"
1919
)
2020

21-
var configHZOnce, clockTickOnce, bootTimeOnce sync.Once
21+
var configHZOnce, clockTickOnce sync.Once
2222
var configHZ int
2323
var userHZ int64
24-
var bootTime int64 // To normalize times, this should be constant
2524

2625
// GetSystemHZ returns an approximation of CONFIG_HZ (the kernel timer interrupt).
2726
func GetSystemHZ() int {
@@ -77,42 +76,77 @@ func getBootTimeInJiffies() int64 {
7776
// Boot time functions
7877
//
7978

79+
var initTimeOnce sync.Once // Set reference times times once
80+
var startTime, bootTime int64 // To normalize times, these should be constant
81+
8082
// Common clock IDs
8183
const (
8284
CLOCK_MONOTONIC = unix.CLOCK_MONOTONIC // Time since a boot (not including time spent in suspend)
8385
CLOCK_BOOTTIME = unix.CLOCK_BOOTTIME // Time since a boot (including time spent in suspend)
8486
)
8587

86-
// GetStartTimeNS returns the elapsed time since system start in nanoseconds.
87-
// Possible to retrieve from two differents clocks: CLOCK_MONOTONIC or CLOCK_BOOTTIME.
88-
func GetStartTimeNS(clockID int32) int64 {
89-
var ts unix.Timespec
88+
// Init sets the reference points for (approximate) system and process start time.
89+
// Run this function ASAP. Not running this function first will cause wrong behaviour
90+
// in other functions of the package.
91+
//
92+
// Reference points can be set from two differents clocks: CLOCK_MONOTONIC or CLOCK_BOOTTIME.
93+
// Tracee bpf code tries to use boottime clock if available, otherwise uses monotonic clock.
94+
// ClockGettime get time elapsed since start (boot) so tracee can calculate event timestamps.
95+
func Init(clockID int32) error {
96+
var err error
97+
initTimeOnce.Do(func() {
98+
startTimeMonotonic, errIn := getClockTimeNS(clockID)
99+
if errIn != nil {
100+
err = errIn
101+
return
102+
}
103+
startTimeEpoch := time.Now().UnixNano()
104+
105+
// process start time since boot
106+
startTime = startTimeMonotonic
107+
108+
/*
109+
Note how the epoch read is just after the monotonic read, allowing us
110+
to approximate the boot time
111+
Epoch
112+
Read
113+
---|-----------...-----|-----------...-------|-|--------------------->
114+
Epoch Boot Monotonic
115+
Start Read
116+
*/
117+
// process start time since boot - process start time since epoch = (approx) boot time since epoch
118+
bootTime = startTimeEpoch - startTimeMonotonic
119+
})
120+
121+
return err
122+
}
90123

91-
// Tracee bpf code try to use boottime clock if available, otherwise uses monotonic clock.
92-
// ClockGettime get time elapsed since start (boot) so tracee can calculate event timestamps
93-
// relative to it.
94-
err := unix.ClockGettime(clockID, &ts)
95-
if err != nil {
96-
logger.Debugw("error getting time", "err", err)
97-
return 0
98-
}
99-
return ts.Nano()
124+
// GetStartTimeNS sets the constant start time and returns it.
125+
126+
// relative to it.
127+
func GetStartTimeNS() int64 {
128+
return startTime
100129
}
101130

102-
// GetBootTimeNS returns the boot time of the system in nanoseconds.
103-
func GetBootTimeNS(clockID int32) int64 {
104-
bootTimeOnce.Do(
105-
func() {
106-
startTime := GetStartTimeNS(clockID)
107-
bootTime = time.Now().UnixNano() - startTime
108-
})
131+
// GetBootTimeNS returns the boot time of the system in nanoseconds since epoch.
132+
func GetBootTimeNS() int64 {
109133
return bootTime
110134
}
111135

112-
func GetBootTime(clockID int32) time.Time {
113-
startTime := GetStartTimeNS(clockID)
114-
uptime := time.Duration(startTime) * time.Nanosecond
115-
return time.Now().Add(-uptime)
136+
func GetBootTime() time.Time {
137+
bootNS := GetBootTimeNS()
138+
return time.Unix(0, bootNS)
139+
}
140+
141+
func getClockTimeNS(clockID int32) (int64, error) {
142+
var ts unix.Timespec
143+
144+
err := unix.ClockGettime(clockID, &ts)
145+
if err != nil {
146+
logger.Debugw("error getting time", "err", err)
147+
return 0, err
148+
}
149+
return ts.Nano(), nil
116150
}
117151

118152
//
@@ -134,10 +168,20 @@ func ClockTicksToNsSinceBootTime(ticks int64) uint64 {
134168
return uint64(ticks * 1000000000 / GetUserHZ())
135169
}
136170

171+
// BootToEpochNS converts time since boot to the epoch time
172+
func BootToEpochNS(ns uint64) uint64 {
173+
return uint64(GetBootTimeNS()) + ns
174+
}
175+
176+
// EpochToBootTimeNS converts time since epoch to relative time from boot
177+
func EpochToBootTimeNS(ns uint64) uint64 {
178+
return ns - uint64(GetBootTimeNS())
179+
}
180+
137181
// NsSinceBootTimeToTime converts nanoseconds timestamp (since boot) to a time.Time object.
138-
func NsSinceBootTimeToTime(clockID int32, ns uint64) time.Time {
182+
func NsSinceBootTimeToTime(ns uint64) time.Time {
139183
duration := time.Duration(int64(ns))
140-
bootTime := GetBootTime(clockID)
184+
bootTime := GetBootTime()
141185
return bootTime.Add(duration)
142186
}
143187

0 commit comments

Comments
 (0)