diff --git a/sonic-pcied/scripts/pcied b/sonic-pcied/scripts/pcied new file mode 100644 index 000000000000..428cc37b0b88 --- /dev/null +++ b/sonic-pcied/scripts/pcied @@ -0,0 +1,136 @@ +#!/usr/bin/env python2 + +""" + pcied + PCIe device monitoring daemon for SONiC +""" + +try: + import os + import signal + import subprocess + import sys + import threading + + import swsssdk + from sonic_daemon_base.daemon_base import Logger + from sonic_daemon_base.daemon_base import DaemonBase +except ImportError, e: + raise ImportError(str(e) + " - required module not found") + +# +# Constants ==================================================================== +# +SYSLOG_IDENTIFIER = "pcied" + +PCIE_RESULT_REGEX = "PCIe Device Checking All Test" +PCIE_TABLE_NAME = "PCIE_STATUS" + +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PCIE_CONF_FILE = 'pcie.yaml' +SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen' +HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku' +PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform' + +PCIED_MAIN_THREAD_SLEEP_SECS = 60 +REDIS_HOSTIP = "127.0.0.1" + +# Global logger class instance +logger = Logger(SYSLOG_IDENTIFIER) + +# +# Daemon ======================================================================= +# + + +class DaemonPcied(DaemonBase): + def __init__(self): + DaemonBase.__init__(self) + + platform, hwsku = DaemonBase.get_platform_and_hwsku(self) + pciefilePath = "/".join([PLATFORM_ROOT_PATH, platform, "plugins", PCIE_CONF_FILE]) + sys.path.append(os.path.abspath(pciefilePath)) + if not os.path.exists(pciefilePath): + logger.log_error("Platform pcie configuration file doesn't exist! exit pcied") + sys.exit("Platform PCIe Configuration file doesn't exist!") + + self.timeout = PCIED_MAIN_THREAD_SLEEP_SECS + self.stop_event = threading.Event() + + self.state_db = swsssdk.SonicV2Connector(host=REDIS_HOSTIP) + self.state_db.connect("STATE_DB") + + def check_pcie_devices(self): + cmd = [ 'sudo', 'pcieutil', 'pcie-check' ] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + resultInfo, err = p.communicate() + pcie_db_state = self.read_state_db("PCIE_STATUS|", "PCIE_DEVICES") + + for line in resultInfo.splitlines(): + if PCIE_RESULT_REGEX in line: + if "PASSED" in line and "PASSED" not in pcie_db_state: + self.update_state_db("PCIE_STATUS|", "PCIE_DEVICES", "PASSED") + logger.log_info("PCIe device status check : PASSED") + elif "FAILED" in line and "PASSED" in pcie_db_state: + self.update_state_db("PCIE_STATUS|", "PCIE_DEVICES", "FAILED") + logger.log_info("PCIe device status check : FAILED") + + def read_state_db(self, key1, key2): + return self.state_db.get('STATE_DB', key1, key2) + + def update_state_db(self, key1, key2, value): + self.state_db.set('STATE_DB', key1, key2, value) + + # Signal handler + def signal_handler(self, sig, frame): + if sig == signal.SIGHUP: + logger.log_info("Caught SIGHUP - ignoring...") + elif sig == signal.SIGINT: + logger.log_info("Caught SIGINT - exiting...") + self.stop_event.set() + elif sig == signal.SIGTERM: + logger.log_info("Caught SIGTERM - exiting...") + self.stop_event.set() + else: + logger.log_warning("Caught unhandled signal '" + sig + "'") + + # Initialize daemon + def init(self): + logger.log_info("Start daemon init...") + + # Deinitialize daemon + def deinit(self): + logger.log_info("Start daemon deinit...") + + # Run daemon + def run(self): + logger.log_info("Starting up...") + + # Start daemon initialization sequence + self.init() + + # Start main loop + logger.log_info("Start daemon main loop") + + while not self.stop_event.wait(self.timeout): + # Check the Pcie device status + self.check_pcie_devices() + + logger.log_info("Stop daemon main loop") + + # Start daemon deinitialization sequence + self.deinit() + + logger.log_info("Shutting down...") + +# +# Main ========================================================================= +# + + +def main(): + pcied = DaemonPcied() + pcied.run() + +if __name__ == '__main__': + main() diff --git a/sonic-pcied/setup.py b/sonic-pcied/setup.py new file mode 100644 index 000000000000..b5b2577ae501 --- /dev/null +++ b/sonic-pcied/setup.py @@ -0,0 +1,29 @@ +from setuptools import setup + +setup( + name='sonic-pcied', + version='1.0', + description='PCIe check daemon for SONiC', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-platform-daemons', + maintainer='Sujin Kang', + maintainer_email='sujkang@microsoft.com', + scripts=[ + 'scripts/pcied', + ], + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: No Input/Output (Daemon)', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: System :: Hardware', + ], + keywords='sonic SONiC PCIe pcie PCIED pcied', +)