diff options
author | Raptor Engineering Development Team <support@raptorengineering.com> | 2019-04-24 05:28:43 +0000 |
---|---|---|
committer | Raptor Engineering Development Team <support@raptorengineering.com> | 2019-04-24 05:28:43 +0000 |
commit | b480da65b9476ae363c488faaf30c196b9291462 (patch) | |
tree | e7190cd47ad6eb5c27b2440da2ab5457bdc6b2d2 | |
parent | 697da84f55c2bb080eee647bcab3255a6fd818e2 (diff) | |
download | talos-skeleton-b480da65b9476ae363c488faaf30c196b9291462.tar.gz talos-skeleton-b480da65b9476ae363c488faaf30c196b9291462.zip |
Update IPL status observer to use new port 81h/82h status codes
-rwxr-xr-x | pyiplobserver/ipl_status_observer.py | 184 |
1 files changed, 68 insertions, 116 deletions
diff --git a/pyiplobserver/ipl_status_observer.py b/pyiplobserver/ipl_status_observer.py index b3bafa7..5fdfd8e 100755 --- a/pyiplobserver/ipl_status_observer.py +++ b/pyiplobserver/ipl_status_observer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2018 Raptor Engineering, LLC +# Copyright 2018-2019 Raptor Engineering, LLC # Released under the terms of the GPL v3 # # Get current istep with @@ -18,6 +18,7 @@ import subprocess import time import subprocess import traceback +from binascii import hexlify from fcntl import fcntl, F_GETFL, F_SETFL from os import O_NONBLOCK, read import obmc.dbuslib.propertycacher as PropertyCacher @@ -26,7 +27,6 @@ import obmc.enums import obmc_system_config as System import obmc.mapper.utils import obmc.inventory -import obmc.system DBUS_NAME = 'org.openbmc.status.IPL' OBJ_NAME = u'/org/openbmc/status/IPL' @@ -34,6 +34,9 @@ OBJ_NAME = u'/org/openbmc/status/IPL' IPL_FLAG_DIR = '/run/openbmc/' IPL_FLAG_FILE = 'host@0-ipl-complete' +PORT81_SNOOP_FIFO = '/dev/aspeed-lpc-snoop0' +PORT82_SNOOP_FIFO = '/dev/aspeed-lpc-snoop1' + HOST_STATUS_RUNNING = "xyz.openbmc_project.State.Host.HostState.Running" IPL_SBE_START_ISTEP_MAJOR = 0 @@ -48,14 +51,14 @@ IPL_HOSTBOOT_START_ISTEP_MINOR = 0 IPL_COMPLETE_ISTEP_MAJOR = 21 IPL_COMPLETE_ISTEP_MINOR = 3 -SKIBOOT_RUNNING_ISTEP_MAJOR = 22 -SKIBOOT_RUNNING_ISTEP_MINOR = 0 +SKIBOOT_RUNNING_ISTEP_MAJOR = 192 +SKIBOOT_RUNNING_ISTEP_MINOR = 12 -KERNEL_RUNNING_ISTEP_MAJOR = 23 -KERNEL_RUNNING_ISTEP_MINOR = 0 +KERNEL_RUNNING_ISTEP_MAJOR = 240 +KERNEL_RUNNING_ISTEP_MINOR = 16 -KERNEL_COMPLETE_ISTEP_MAJOR = 23 -KERNEL_COMPLETE_ISTEP_MINOR = 1 +KERNEL_COMPLETE_ISTEP_MAJOR = 254 +KERNEL_COMPLETE_ISTEP_MINOR = 254 class IPLStatus(DbusProperties, DbusObjectManager): def __init__(self, bus, obj_name): @@ -70,8 +73,8 @@ class IPLStatus(DbusProperties, DbusObjectManager): self.last_istep = "" self.current_istep_major = 0 self.current_istep_minor = 0 - self.consoleProcess = None - self.consoleReadBuffer = "" + self.port_81_fifo = None + self.port_82_fifo = None if not os.path.exists(IPL_FLAG_DIR): os.makedirs(IPL_FLAG_DIR) @@ -81,16 +84,18 @@ class IPLStatus(DbusProperties, DbusObjectManager): host_state_value = host_state_iface.Get("xyz.openbmc_project.State.Host", "CurrentHostState") if host_state_value is not None: power_ctrl_flag = self.getChassisPowerRequestFlag() - skiboot_flags = self.getSkibootBootFlags() - if ((skiboot_flags != 0) and (skiboot_flags != 1)) or ((power_ctrl_flag == 1) and (skiboot_flags == 0)): + # FIXME + # If this service is restarted after the host has completed IPL, we have no way + # of knowing this. If the host has not completed IPL, then running the following + # commands will probably cause a system fault requiring manual intervention to clear + # (i.e. pflash -P GUARD -c once the second CPU faults out) + if power_ctrl_flag == 1: self.current_istep_major = KERNEL_COMPLETE_ISTEP_MAJOR self.current_istep_minor = KERNEL_COMPLETE_ISTEP_MAJOR - if (skiboot_flags != 0) or (power_ctrl_flag == 1): self.activateMonitoringPrev = True self.activateMonitoring = True if (host_state_value != HOST_STATUS_RUNNING) and (self.activateMonitoring == True): host_state_iface.Set("xyz.openbmc_project.State.Host", "CurrentHostState", HOST_STATUS_RUNNING) - self.setSkibootBootFlags(2) self.Set(DBUS_NAME, "current_istep", "") self.Set(DBUS_NAME, "current_status", "UNKNOWN") @@ -115,32 +120,6 @@ class IPLStatus(DbusProperties, DbusObjectManager): return result - # BMC bits OEM1, OEM2, and OEM3 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 - # OEM3 is unconditionally set at kernel boot completion and is only cleared by the BMC IPL monitor - def getSkibootBootFlags(self): - result = 0 - try: - proc = subprocess.Popen(["devmem", "0x1e789060", "16"], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False) - (out, err) = proc.communicate() - result = (int(out, 16) & 28) >> 2 - except: - pass - - return result - - def setSkibootBootFlags(self, value): - try: - proc = subprocess.Popen(["devmem", "0x1e789060", "16"], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False) - (out, err) = proc.communicate() - reg_data = (int(out, 16) & (~28)) | ((value & 7) << 2) - proc = subprocess.Popen(["devmem", "0x1e789060", "16", str(reg_data)], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False) - (out, err) = proc.communicate() - except: - print "IPLStatus unable to reset skiboot / kernel flags!" - pass - def readIPLStatus(self): try: # Set up defaults @@ -155,22 +134,30 @@ class IPLStatus(DbusProperties, DbusObjectManager): self.Set(DBUS_NAME, "current_status", current_status) self.IPLStatusChanged(current_status) self.last_status = current_status - self.setSkibootBootFlags(0) if (self.last_istep != current_istep): self.Set(DBUS_NAME, "current_istep", current_istep) self.IPLStepChanged(current_istep) self.last_istep = current_istep - self.setSkibootBootFlags(0) self.activateMonitoringPrev = self.activateMonitoring return True; if (self.activateMonitoring == True) and (self.activateMonitoringPrev == False): - if (self.consoleProcess is None): - self.consoleProcess = subprocess.Popen(["/usr/bin/obmc-console-client"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) - # set the O_NONBLOCK flag of self.consoleProcess.stdout file descriptor: - stdout_flags = fcntl(self.consoleProcess.stdout, F_GETFL) # get current p.stdout flags - fcntl(self.consoleProcess.stdout, F_SETFL, stdout_flags | O_NONBLOCK) + if (self.port_81_fifo is None): + self.port_81_fifo = os.open(PORT81_SNOOP_FIFO, os.O_RDONLY | os.O_NONBLOCK, 0); + if (self.port_82_fifo is None): + self.port_82_fifo = os.open(PORT82_SNOOP_FIFO, os.O_RDONLY | os.O_NONBLOCK, 0); + # Drain FIFOs + while True: + try: + os.read(self.port_81_fifo, 1) + except: + break + while True: + try: + os.read(self.port_82_fifo, 1) + except: + break current_status = "IPL_RUNNING" self.current_istep_major = IPL_SBE_START_ISTEP_MAJOR self.current_istep_minor = IPL_SBE_START_ISTEP_MINOR @@ -179,50 +166,40 @@ class IPLStatus(DbusProperties, DbusObjectManager): self.IPLStepChanged(current_istep) self.last_istep = current_istep elif (self.activateMonitoring == False) and (self.activateMonitoringPrev == True): - if (self.consoleProcess is not None): - self.consoleProcess.kill() - self.consoleProcess = None - self.consoleReadBuffer = "" - self.current_istep_major = 0 - self.current_istep_minor = 0 + # Close FIFOs if still open + if (self.port_81_fifo is not None): + os.close(self.port_81_fifo); + self.port_81_fifo = None; + if (self.port_82_fifo is not None): + os.close(self.port_82_fifo); + self.port_82_fifo = None; + self.current_istep_major = 0 + self.current_istep_minor = 0 # Check for output - if (self.consoleProcess is not None): + if (self.port_82_fifo is not None): all_lines_processed = False while all_lines_processed == False: - candidate_character = '' + istep_major = None + istep_minor = None try: - while True: - candidate_character = self.consoleProcess.stdout.read(1) - self.consoleReadBuffer += candidate_character - if (candidate_character == '\n'): - break; + value = os.read(self.port_82_fifo, 1) + istep_minor = int(hexlify(value), 16) except: - # ENODATA is expected all_lines_processed = True - break; - - self.consoleReadBuffer += candidate_character - if (candidate_character != '\n'): - return True - - candidate_line = self.consoleReadBuffer.decode('utf-8', 'ignore').rstrip().lstrip() - self.consoleReadBuffer = "" - if ("|ISTEP " in candidate_line): - candidate_line = candidate_line.replace(" ", "") + if not all_lines_processed: try: - (timestamp_seconds, timestamp_fraction, istep_major, istep_minor, istep_name) = [t(s) for t, s in zip((int, int, int, int, str), re.search('^(\d+).(\d+)\|ISTEP(\d+).(\d+)-(\S+)$', candidate_line).groups())] + value = os.read(self.port_81_fifo, 1) + istep_major = int(hexlify(value), 16) except: - self.activateMonitoringPrev = self.activateMonitoring - return True - else: - self.activateMonitoringPrev = self.activateMonitoring - return True + all_lines_processed = True - # Figure out system status - self.current_istep_major = istep_major - self.current_istep_minor = istep_minor + if not all_lines_processed: + if (istep_major != None) and (istep_minor != None): + # Figure out system status + self.current_istep_major = istep_major + self.current_istep_minor = istep_minor # Assemble status strings current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor) @@ -230,36 +207,13 @@ class IPLStatus(DbusProperties, DbusObjectManager): if ((self.current_istep_major > 0) or (self.current_istep_minor > 0 )): current_status = "IPL_RUNNING" if (self.current_istep_major >= IPL_COMPLETE_ISTEP_MAJOR): - # Disconnect console if still active - if (self.consoleProcess is not None): - self.consoleProcess.kill() - self.consoleProcess = None - self.consoleReadBuffer = "" - - # Monitor remainder of IPL via status flags - skiboot_flags = self.getSkibootBootFlags() - if (skiboot_flags == 0): - current_status = "IPL_RUNNING" - self.current_istep_major = SKIBOOT_RUNNING_ISTEP_MAJOR - self.current_istep_minor = SKIBOOT_RUNNING_ISTEP_MINOR - current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor) - elif (skiboot_flags == 1): - current_status = "IPL_RUNNING" - self.current_istep_major = KERNEL_RUNNING_ISTEP_MAJOR - self.current_istep_minor = KERNEL_RUNNING_ISTEP_MINOR - current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor) - else: + # Monitor remainder of IPL for completion + if (self.current_istep_major == KERNEL_COMPLETE_ISTEP_MAJOR) and (self.current_istep_minor == KERNEL_COMPLETE_ISTEP_MINOR): current_status = "IPL_COMPLETE" - self.current_istep_major = KERNEL_COMPLETE_ISTEP_MAJOR - self.current_istep_minor = KERNEL_COMPLETE_ISTEP_MINOR - current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor) # Check for status changes 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'): @@ -276,9 +230,6 @@ class IPLStatus(DbusProperties, DbusObjectManager): os.remove(IPL_FLAG_DIR + IPL_FLAG_FILE) except: pass - if (current_status == "IPL_RUNNING"): - if (self.current_istep_major < IPL_COMPLETE_ISTEP_MAJOR): - self.setSkibootBootFlags(0) # Publish status if (self.last_status != current_status): @@ -305,13 +256,15 @@ class IPLStatus(DbusProperties, DbusObjectManager): if (value == HOST_STATUS_RUNNING): self.activateMonitoring = True else: - # Disconnect console if still active - if (self.consoleProcess is not None): - self.consoleProcess.kill() - self.consoleProcess = None - self.consoleReadBuffer = "" - self.current_istep_major = 0 - self.current_istep_minor = 0 + # Close FIFOs if still open + if (self.port_81_fifo is not None): + os.close(self.port_81_fifo); + self.port_81_fifo = None; + if (self.port_82_fifo is not None): + os.close(self.port_82_fifo); + self.port_82_fifo = None; + self.current_istep_major = 0 + self.current_istep_minor = 0 # Remove IPL complete flag if present try: @@ -319,7 +272,6 @@ class IPLStatus(DbusProperties, DbusObjectManager): except: pass - self.setSkibootBootFlags(0) self.activateMonitoring = False @dbus.service.method(DBUS_NAME, in_signature='', out_signature='s') |