summaryrefslogtreecommitdiffstats
path: root/pyiplobserver
diff options
context:
space:
mode:
authorRaptor Engineering Development Team <support@raptorengineering.com>2018-03-02 20:29:25 -0600
committerRaptor Engineering Development Team <support@raptorengineering.com>2019-04-19 10:28:12 +0000
commit7d963b63375bcc9032ca0dd9fcb4fc2684983316 (patch)
tree882af7932d9bf6aded53d27e61f6f2529ea91e1b /pyiplobserver
parent61fc936d039de054cd5b89549ca900dd96cd6ab6 (diff)
downloadtalos-skeleton-7d963b63375bcc9032ca0dd9fcb4fc2684983316.tar.gz
talos-skeleton-7d963b63375bcc9032ca0dd9fcb4fc2684983316.zip
Remove race condition in skiboot completion monitor
Diffstat (limited to 'pyiplobserver')
-rw-r--r--pyiplobserver/ipl_status_observer.py21
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')
OpenPOWER on IntegriCloud