diff options
author | Raptor Engineering Development Team <support@raptorengineering.com> | 2018-03-02 20:29:25 -0600 |
---|---|---|
committer | Raptor Engineering Development Team <support@raptorengineering.com> | 2019-04-19 10:28:12 +0000 |
commit | 7d963b63375bcc9032ca0dd9fcb4fc2684983316 (patch) | |
tree | 882af7932d9bf6aded53d27e61f6f2529ea91e1b /pyiplobserver | |
parent | 61fc936d039de054cd5b89549ca900dd96cd6ab6 (diff) | |
download | blackbird-skeleton-7d963b63375bcc9032ca0dd9fcb4fc2684983316.tar.gz blackbird-skeleton-7d963b63375bcc9032ca0dd9fcb4fc2684983316.zip |
Remove race condition in skiboot completion monitor
Diffstat (limited to 'pyiplobserver')
-rw-r--r-- | pyiplobserver/ipl_status_observer.py | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/pyiplobserver/ipl_status_observer.py b/pyiplobserver/ipl_status_observer.py index 2d4b84a..890dd61 100644 --- a/pyiplobserver/ipl_status_observer.py +++ b/pyiplobserver/ipl_status_observer.py @@ -77,22 +77,25 @@ class IPLStatus(DbusProperties, DbusObjectManager): print "IPLStatus Init Done" - def getSkibootBootFlag(self): + # BMC bits OEM1 and OEM2 are the signalling flags + # OEM1 is unconditionally set at skiboot completion and is only cleared by the BMC IPL monitor + # OEM2 is used as a persistent state indicator, and is only set and cleared by the BMC IPL monitor + def getSkibootBootFlags(self): result = 0 try: proc = subprocess.Popen(["devmem", "0x1e789060", "8"], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False) (out, err) = proc.communicate() - result = (int(out, 16) & 4) >> 2 + result = (int(out, 16) & 12) >> 2 except: pass return result - def resetSkibootBootFlag(self): + def setSkibootBootFlags(self, value): try: proc = subprocess.Popen(["devmem", "0x1e789060", "8"], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False) (out, err) = proc.communicate() - reg_data = int(out, 16) & (~4) + reg_data = (int(out, 16) & (~12)) | ((value & 3) << 2) proc = subprocess.Popen(["devmem", "0x1e789060", "8", str(reg_data)], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False) (out, err) = proc.communicate() except: @@ -123,7 +126,7 @@ class IPLStatus(DbusProperties, DbusObjectManager): self.Set(DBUS_NAME, "current_istep", current_istep) self.IPLStepChanged(current_istep) self.last_istep = current_istep - self.resetSkibootBootFlag() + self.setSkibootBootFlags(0) return True; @@ -202,7 +205,7 @@ class IPLStatus(DbusProperties, DbusObjectManager): if ((current_istep_major > 0) or (current_istep_minor > 0 )): current_status = "IPL_RUNNING" if ((current_istep_major == IPL_COMPLETE_ISTEP_MAJOR) and (current_istep_minor == IPL_COMPLETE_ISTEP_MINOR)): - if (self.getSkibootBootFlag() == 0): + if (self.getSkibootBootFlags() == 0): current_status = "IPL_RUNNING" current_istep_major = SKIBOOT_RUNNING_ISTEP_MAJOR current_istep_minor = SKIBOOT_RUNNING_ISTEP_MINOR @@ -219,6 +222,9 @@ class IPLStatus(DbusProperties, DbusObjectManager): if (self.last_status != current_status): if (current_status == "IPL_COMPLETE"): + # Set skiboot completion flag + self.setSkibootBootFlags(2) + # Signal systemd that IPL is complete try: with open(IPL_FLAG_DIR + IPL_FLAG_FILE, 'a'): @@ -236,7 +242,7 @@ class IPLStatus(DbusProperties, DbusObjectManager): except: pass if (current_istep_major < IPL_COMPLETE_ISTEP_MAJOR): - self.resetSkibootBootFlag() + self.setSkibootBootFlags(0) # Since it is extremely unlikely that both fetches will fail unless the host is offline, simply check that both fetches passed or failed before continuing if (sbe_fetch_failed == hostboot_fetch_failed): @@ -267,6 +273,7 @@ class IPLStatus(DbusProperties, DbusObjectManager): if (value == HOST_STATUS_RUNNING): self.activateMonitoring = True else: + self.setSkibootBootFlags(0) self.activateMonitoring = False @dbus.service.method(DBUS_NAME, in_signature='', out_signature='s') |