From 9c14606aba640296fc9f2fed962dbf82399af9ae Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 13 May 2016 13:31:43 -0400 Subject: [PATCH] Disable futile attempts to correct uncorrectable time When an anomaly is detected that suggests the event timeline is uselessly corrupt, abandon all attempts to correct older entries and skip or verbatim translate remaining time entries. The notable scenario is when an older event has a higher timestamp value than a newer event (time went backwards, or pre-init to normal) without a clock sync notification to navigate the change. Change-Id: I31aa9cd04e20fbdb55d7b955db6f6640da9c75a7 --- pyghmi/ipmi/events.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/pyghmi/ipmi/events.py b/pyghmi/ipmi/events.py index 1bf7e793..2e9cb8c5 100644 --- a/pyghmi/ipmi/events.py +++ b/pyghmi/ipmi/events.py @@ -1,6 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2015 Lenovo +# Copyright 2016 Lenovo # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -299,20 +299,32 @@ def _fix_sel_time(records, ipmicmd): newtimestamp = 0 lasttimestamp = None trimindexes = [] + correctionenabled = True for index in reversed(xrange(len(records))): record = records[index] if 'timecode' not in record or record['timecode'] == 0xffffffff: continue if ('event' in record and record['event'] == 'Clock time change' and record['event_data'] == 'After'): + if (lasttimestamp is not None and + record['timecode'] > lasttimestamp): + # if the timestamp did something impossible, declare the rest + # of history not meaningfully correctable + correctionenabled = False + newtimestamp = 0 + continue newtimestamp = record['timecode'] trimindexes.append(index) elif ('event' in record and record['event'] == 'Clock time change' and record['event_data'] == 'Before'): + if not correctionenabled: + continue if newtimestamp: if record['timecode'] < 0x20000000: correctearly = True nowtime = correctednowtime + # we want time that occurred before this point to get the delta + # added to it to catch up correctednowtime += newtimestamp - record['timecode'] newtimestamp = 0 trimindexes.append(index) @@ -320,7 +332,7 @@ def _fix_sel_time(records, ipmicmd): # clean up after potentially broken time sync pairs newtimestamp = 0 if record['timecode'] < 0x20000000: # uptime timestamp - if not correctearly: + if not correctearly or not correctionenabled: correctednowtime = nowtime continue if (lasttimestamp is not None and @@ -328,6 +340,7 @@ def _fix_sel_time(records, ipmicmd): # Time has gone backwards in pre-init, no hope for # accurate time correctearly = False + correctionenabled = False correctednowtime = nowtime continue inpreinit = True @@ -339,6 +352,11 @@ def _fix_sel_time(records, ipmicmd): # We are in 'normal' time, assume we cannot go to # pre-init time and do corrections unless time sync events # guide us in safely + if (lasttimestamp is not None and + record['timecode'] > lasttimestamp): + # Time has gone backwards, without a clock sync + # give up any attempt to correct from this point back... + correctionenabled = False if inpreinit: inpreinit = False # We were in pre-init, now in real time, reset the @@ -346,7 +364,8 @@ def _fix_sel_time(records, ipmicmd): # 'wall clock' correction correctednowtime = nowtime correctearly = False - if correctednowtime < 0x20000000: + lasttimestamp = record['timecode'] + if not correctionenabled or correctednowtime < 0x20000000: # We can't correct time when the correction factor is # rooted in a pre-init timestamp, just convert record['timestamp'] = time.strftime(