@@ -18,10 +18,9 @@ import (
18
18
"github.com/aquasecurity/tracee/pkg/utils"
19
19
)
20
20
21
- var configHZOnce , clockTickOnce , bootTimeOnce sync.Once
21
+ var configHZOnce , clockTickOnce sync.Once
22
22
var configHZ int
23
23
var userHZ int64
24
- var bootTime int64 // To normalize times, this should be constant
25
24
26
25
// GetSystemHZ returns an approximation of CONFIG_HZ (the kernel timer interrupt).
27
26
func GetSystemHZ () int {
@@ -77,42 +76,77 @@ func getBootTimeInJiffies() int64 {
77
76
// Boot time functions
78
77
//
79
78
79
+ var initTimeOnce sync.Once // Set reference times times once
80
+ var startTime , bootTime int64 // To normalize times, these should be constant
81
+
80
82
// Common clock IDs
81
83
const (
82
84
CLOCK_MONOTONIC = unix .CLOCK_MONOTONIC // Time since a boot (not including time spent in suspend)
83
85
CLOCK_BOOTTIME = unix .CLOCK_BOOTTIME // Time since a boot (including time spent in suspend)
84
86
)
85
87
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
+ }
90
123
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
100
129
}
101
130
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 {
109
133
return bootTime
110
134
}
111
135
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
116
150
}
117
151
118
152
//
@@ -134,10 +168,20 @@ func ClockTicksToNsSinceBootTime(ticks int64) uint64 {
134
168
return uint64 (ticks * 1000000000 / GetUserHZ ())
135
169
}
136
170
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
+
137
181
// 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 {
139
183
duration := time .Duration (int64 (ns ))
140
- bootTime := GetBootTime (clockID )
184
+ bootTime := GetBootTime ()
141
185
return bootTime .Add (duration )
142
186
}
143
187
0 commit comments