sentry: wait for restore clock instead of panicing in Timekeeper.

PiperOrigin-RevId: 204372296
Change-Id: If1ed9843b93039806e0c65521f30177dc8036979
This commit is contained in:
Zhaozhong Ni
2018-07-12 15:09:02 -07:00
committed by Shentubot
parent bb41ad808a
commit 1cd46c8dd1
3 changed files with 19 additions and 12 deletions
+16 -9
View File
@@ -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 {
+1 -1
View File
@@ -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{})
}
+2 -2
View File
@@ -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)