diff options
author | Zhaozhong Ni <nzz@google.com> | 2018-07-12 15:07:59 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-07-12 15:09:02 -0700 |
commit | 1cd46c8dd1a92dd0ad3eeb60a763278f2e98d0b4 (patch) | |
tree | 970e90306e9a146f17014c8d4ec6ebb45a5e5dd7 /pkg/sentry/kernel | |
parent | bb41ad808a75b8a945d82df51f0e322d98edf951 (diff) |
sentry: wait for restore clock instead of panicing in Timekeeper.
PiperOrigin-RevId: 204372296
Change-Id: If1ed9843b93039806e0c65521f30177dc8036979
Diffstat (limited to 'pkg/sentry/kernel')
-rw-r--r-- | pkg/sentry/kernel/timekeeper.go | 25 | ||||
-rw-r--r-- | pkg/sentry/kernel/timekeeper_state.go | 2 | ||||
-rw-r--r-- | pkg/sentry/kernel/timekeeper_test.go | 4 |
3 files changed, 19 insertions, 12 deletions
diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go index 3f16c1676..4de8ac13b 100644 --- a/pkg/sentry/kernel/timekeeper.go +++ b/pkg/sentry/kernel/timekeeper.go @@ -44,14 +44,14 @@ type Timekeeper struct { // It is set only once, by SetClocks. monotonicOffset int64 `state:"nosave"` - // restored indicates that this Timekeeper was restored from a state - // file. - restored bool `state:"nosave"` + // restored, if non-nil, indicates that this Timekeeper was restored + // from a state file. The clocks are not set until restored is closed. + restored chan struct{} `state:"nosave"` // saveMonotonic is the (offset) value of the monotonic clock at the // time of save. // - // It is only valid if restored is true. + // It is only valid if restored is non-nil. // // It is only used in SetClocks after restore to compute the new // monotonicOffset. @@ -59,7 +59,7 @@ type Timekeeper struct { // saveRealtime is the value of the realtime clock at the time of save. // - // It is only valid if restored is true. + // It is only valid if restored is non-nil. // // It is only used in SetClocks after restore to compute the new // monotonicOffset. @@ -98,7 +98,7 @@ func NewTimekeeper(platform platform.Platform, paramPage platform.FileRange) (*T func (t *Timekeeper) SetClocks(c sentrytime.Clocks) { // Update the params, marking them "not ready", as we may need to // restart calibration on this new machine. - if t.restored { + if t.restored != nil { if err := t.params.Write(func() vdsoParams { return vdsoParams{} }); err != nil { @@ -135,7 +135,7 @@ func (t *Timekeeper) SetClocks(c sentrytime.Clocks) { panic("Unable to get current realtime: " + err.Error()) } - if t.restored { + if t.restored != nil { wantMonotonic = t.saveMonotonic elapsed := nowRealtime - t.saveRealtime if elapsed > 0 { @@ -145,7 +145,7 @@ func (t *Timekeeper) SetClocks(c sentrytime.Clocks) { t.monotonicOffset = wantMonotonic - nowMonotonic - if !t.restored { + if t.restored == nil { // Hold on to the initial "boot" time. t.bootTime = ktime.FromNanoseconds(nowRealtime) } @@ -153,6 +153,10 @@ func (t *Timekeeper) SetClocks(c sentrytime.Clocks) { t.mu.Lock() defer t.mu.Unlock() t.startUpdater() + + if t.restored != nil { + close(t.restored) + } } // startUpdater starts an update goroutine that keeps the clocks updated. @@ -255,7 +259,10 @@ func (t *Timekeeper) ResumeUpdates() { // GetTime returns the current time in nanoseconds. func (t *Timekeeper) GetTime(c sentrytime.ClockID) (int64, error) { if t.clocks == nil { - panic("Timekeeper used before initialized with SetClocks") + if t.restored == nil { + panic("Timekeeper used before initialized with SetClocks") + } + <-t.restored } now, err := t.clocks.GetTime(c) if err == nil && c == sentrytime.Monotonic { diff --git a/pkg/sentry/kernel/timekeeper_state.go b/pkg/sentry/kernel/timekeeper_state.go index aee983ac7..2e7fed4d8 100644 --- a/pkg/sentry/kernel/timekeeper_state.go +++ b/pkg/sentry/kernel/timekeeper_state.go @@ -37,5 +37,5 @@ func (t *Timekeeper) beforeSave() { // afterLoad is invoked by stateify. func (t *Timekeeper) afterLoad() { - t.restored = true + t.restored = make(chan struct{}) } diff --git a/pkg/sentry/kernel/timekeeper_test.go b/pkg/sentry/kernel/timekeeper_test.go index 08bacba4f..34a5cec27 100644 --- a/pkg/sentry/kernel/timekeeper_test.go +++ b/pkg/sentry/kernel/timekeeper_test.go @@ -107,7 +107,7 @@ func TestTimekeeperMonotonicForward(t *testing.T) { } tk := stateTestClocklessTimekeeper(t) - tk.restored = true + tk.restored = make(chan struct{}) tk.saveMonotonic = 100000 tk.saveRealtime = 400000 tk.SetClocks(c) @@ -135,7 +135,7 @@ func TestTimekeeperMonotonicJumpBackwards(t *testing.T) { } tk := stateTestClocklessTimekeeper(t) - tk.restored = true + tk.restored = make(chan struct{}) tk.saveMonotonic = 100000 tk.saveRealtime = 600000 tk.SetClocks(c) |