Cole Walker b50b361d9f [PTP] No longer consider clockClass 7 and 135 as locked
PTP-notification was treating clockClass values 7 and 135 as indicators
of a locked status, which is incorrect as per ITU-T G.8275.1. This was
resulting in ptp-notification delivering locked status to clients when
it should instead be transitioning to holdover/freerun.

Removed clockClass 7 and 135 from the list of valid locked clockClasses.
PTP-notification is now able to properly transition states when these
classes are observed.

Test plan:
PASS: Build and deploy image
PASS: Verify correct state transitions when clockClass 6, 7, 135 are
observed

Partial-Bug: 1995014

Signed-off-by: Cole Walker <cole.walker@windriver.com>
Change-Id: If68df991c3d6555f09e19a0d11f2c71e077c2587
2022-10-31 10:52:59 -04:00

108 lines
3.5 KiB
Python

#! /usr/bin/python3
#
# Copyright (c) 2021-2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
#
# This script provides the PTP synchronization status
# for PTP NIC configured as subordinate (slave mode)
# It relies on Linux ptp4l (PMC) module in order to work
# Sync status provided as: 'Locked', 'Holdover', 'Freerun'
#
#
import os
import re
import subprocess
import logging
from trackingfunctionsdk.common.helpers import constants
from trackingfunctionsdk.common.helpers import log_helper
LOG = logging.getLogger(__name__)
log_helper.config_logger(LOG)
# run subprocess and returns out, err, errcode
def run_shell2(dir, ctx, args):
cwd = os.getcwd()
os.chdir(dir)
process = subprocess.Popen(args, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = process.communicate()
errcode = process.returncode
os.chdir(cwd)
return out, err, errcode
def check_critical_resources(ptp4l_service_name, phc2sys_service_name):
pmc = False
ptp4l = False
phc2sys = False
ptp4lconf = False
if os.path.isfile('/usr/sbin/pmc'):
pmc = True
if os.path.isfile('/var/run/ptp4l-%s.pid' % ptp4l_service_name):
ptp4l = True
if os.path.isfile('/var/run/phc2sys-%s.pid' % phc2sys_service_name):
phc2sys = True
if os.path.isfile(constants.PTP_CONFIG_PATH +
('ptp4l-%s.conf' % ptp4l_service_name)):
ptp4lconf = True
return pmc, ptp4l, phc2sys, ptp4lconf
def check_results(result, total_ptp_keywords, port_count):
# sync state is in 'Locked' state and will be overwritten if
# it is not the case
sync_state = constants.LOCKED_PHC_STATE
local_gm = False
# check for a healthy result
if len(result) != total_ptp_keywords:
sync_state = constants.FREERUN_PHC_STATE
LOG.warning('results are not complete, returning FREERUN')
return sync_state
# determine the current sync state
if (result[constants.GM_PRESENT].lower() != constants.GM_IS_PRESENT
and result[constants.GRANDMASTER_IDENTITY] != result[constants.CLOCK_IDENTITY]):
sync_state = constants.FREERUN_PHC_STATE
elif result[constants.GRANDMASTER_IDENTITY] == result[constants.CLOCK_IDENTITY]:
local_gm = True
LOG.debug("Local node is a GM")
for port in range(1, port_count + 1):
if result[constants.PORT.format(port)].lower() == constants.SLAVE_MODE:
break
elif local_gm and result[constants.PORT.format(port)].lower() == constants.MASTER_MODE:
break
else:
sync_state = constants.FREERUN_PHC_STATE
if (result[constants.TIME_TRACEABLE] != constants.TIME_IS_TRACEABLE1
and result[constants.TIME_TRACEABLE].lower != constants.TIME_IS_TRACEABLE2):
sync_state = constants.FREERUN_PHC_STATE
if (result[constants.GM_CLOCK_CLASS] not in
[constants.CLOCK_CLASS_VALUE6]):
sync_state = constants.FREERUN_PHC_STATE
return sync_state
def parse_resource_address(resource_address):
# The format of resource address is:
# /{clusterName}/{siteName}(/optional/hierarchy/..)/{nodeName}/{resource}
# Assume no optional hierarchy for now
clusterName = resource_address.split('/')[1]
nodeName = resource_address.split('/')[2]
resource_path = '/' + re.split('[/]', resource_address, 3)[3]
return clusterName, nodeName, resource_path
def format_resource_address(node_name, resource):
# Return a resource_address
resource_address = '/./' + node_name + resource
return resource_address