From b36dd4e80c76dbb6bb5da6c36f1ddac83bb0fe9f Mon Sep 17 00:00:00 2001 From: "Anand Mehra (anamehra)" Date: Thu, 13 Nov 2025 00:16:43 -0800 Subject: [PATCH 1/2] Restart chrony/ntp service on interfaces-config restart Signed-off-by: Anand Mehra (anamehra) --- src/usr/lib/ztp/ztp-engine.py | 44 ++++++++++++++++++++++++++++++++-- src/usr/lib/ztp/ztp-profile.sh | 40 +++++++++++++++++++++++++++---- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/usr/lib/ztp/ztp-engine.py b/src/usr/lib/ztp/ztp-engine.py index 3edd5e1..7b40e3c 100755 --- a/src/usr/lib/ztp/ztp-engine.py +++ b/src/usr/lib/ztp/ztp-engine.py @@ -77,6 +77,27 @@ def signal_handler(signum, frame): sys.exit(0) +def get_ntp_service_name(): + '''! + Detect which NTP service is available on the system. + Checks in priority order: chrony, ntp + + Returns: + str: Name of the available NTP service, or None if none found + ''' + ntp_services = ['chrony', 'ntp'] + for service in ntp_services: + try: + rc = runCommand('systemctl is-enabled ' + service, capture_stdout=True) + if rc == 0: + logger.info('Detected NTP service: %s' % service) + return service + except: + continue + + logger.warning('No NTP service detected (ntp/ntpsec/chrony)') + return None + class ZTPEngine(): '''! \brief This class performs core functions of ZTP service. @@ -795,6 +816,25 @@ def __forceRestartDiscovery(self, msg): # Restart link-scan self.__intf_state = dict() + def __restart_network_services(self): + '''! + Restart the necessary services: stop and start NTP, and restart interfaces-config. + Detects which NTP service is available (ntp, ntpsec, or chrony). + ''' + ntp_service = get_ntp_service_name() + + if ntp_service: + logger.info('Stopping %s service...' % ntp_service) + runCommand('systemctl stop ' + ntp_service, capture_stdout=False) + + logger.info('Restarting interfaces-config service...') + runCommand('systemctl restart interfaces-config', capture_stdout=False) + + if ntp_service: + logger.info('Starting %s service...' % ntp_service) + runCommand('systemctl start ' + ntp_service, capture_stdout=False) + logger.info('%s service restarted successfully.' % ntp_service) + def executeLoop(self, test_mode=False): '''! ZTP service loop which peforms provisioning data discovery and initiates processing. @@ -860,7 +900,7 @@ def executeLoop(self, test_mode=False): if self.__link_scan(): updateActivity('Restarting network discovery after link scan') logger.info('Restarting network discovery after link scan.') - runCommand('systemctl restart interfaces-config', capture_stdout=False) + self.__restart_network_services() logger.info('Restarted network discovery after link scan.') _start_time = time.time() continue @@ -876,7 +916,7 @@ def executeLoop(self, test_mode=False): # Remove existing leases to source new provisioning data self.__cleanup_dhcp_leases() logger.info('Restarting network discovery.') - runCommand('systemctl restart interfaces-config', capture_stdout=False) + self.__restart_network_services() logger.info('Restarted network discovery.') _start_time = time.time() continue diff --git a/src/usr/lib/ztp/ztp-profile.sh b/src/usr/lib/ztp/ztp-profile.sh index d8afbe8..bd06b8a 100755 --- a/src/usr/lib/ztp/ztp-profile.sh +++ b/src/usr/lib/ztp/ztp-profile.sh @@ -41,6 +41,18 @@ PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) HW_KEY=${PRESET[0]} +# Function to detect which NTP service is available +# Different SONiC releases use: ntp, ntpsec, or chrony +get_ntp_service() { + for service in chrony ntp; do + if systemctl is-enabled $service >/dev/null 2>&1; then + echo "$service" + return 0 + fi + done + return 1 +} + # Command usage and help usage() { @@ -221,9 +233,20 @@ if [ "$CMD" = "install" ] ; then # Restart interface configuration again to pickup newly created interfaces # to start DHCP discovery if [ "$(ztp status -c)" = "4:IN-PROGRESS" ]; then - echo "Restarting network configuration." - updateActivity "Restarting network configuration" + NTP_SERVICE=$(get_ntp_service) + if [ -n "$NTP_SERVICE" ]; then + echo "Stopping $NTP_SERVICE." + updateActivity "Stopping $NTP_SERVICE" + systemctl stop $NTP_SERVICE + fi + echo "Restarting interfaces-config." + updateActivity "Restarting interfaces-config" + systemctl restart interfaces-config + if [ -n "$NTP_SERVICE" ]; then + systemctl start $NTP_SERVICE + echo "Restarted $NTP_SERVICE." + fi echo "Restarted network configuration." fi fi @@ -259,9 +282,18 @@ if [ "$CMD" = "remove" ] ; then sonic-db-cli CONFIG_DB DEL "ZTP|mode" > /dev/null fi - updateActivity "Restarting network configuration" - # Restart interface configuration to stop DHCP + NTP_SERVICE=$(get_ntp_service) + if [ -n "$NTP_SERVICE" ]; then + updateActivity "Restarting network configuration and $NTP_SERVICE" + # Restart interface configuration to stop DHCP + systemctl stop $NTP_SERVICE + else + updateActivity "Restarting network configuration" + fi systemctl restart interfaces-config + if [ -n "$NTP_SERVICE" ]; then + systemctl start $NTP_SERVICE + fi fi # Remove ZTP DHCP policy From 024b2ba7326bcec395611f441a7a9ea93d155085 Mon Sep 17 00:00:00 2001 From: "Anand Mehra (anamehra)" Date: Mon, 20 Jul 2026 09:30:51 -0700 Subject: [PATCH 2/2] Address NTP restart review feedback Signed-off-by: Anand Mehra (anamehra) --- src/usr/lib/ztp/ztp-engine.py | 29 +++++++++-------- src/usr/lib/ztp/ztp-profile.sh | 59 +++++++++++++++++----------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/usr/lib/ztp/ztp-engine.py b/src/usr/lib/ztp/ztp-engine.py index 79bca9e..7561c15 100755 --- a/src/usr/lib/ztp/ztp-engine.py +++ b/src/usr/lib/ztp/ztp-engine.py @@ -79,23 +79,23 @@ def signal_handler(signum, frame): def get_ntp_service_name(): '''! - Detect which NTP service is available on the system. + Detect which NTP service is active on the system. Checks in priority order: chrony, ntp Returns: - str: Name of the available NTP service, or None if none found + str: Name of the active NTP service, or None if none found ''' ntp_services = ['chrony', 'ntp'] for service in ntp_services: try: - rc = runCommand('systemctl is-enabled ' + service, capture_stdout=True) + rc = runCommand('systemctl is-active --quiet ' + service, capture_stdout=False) if rc == 0: logger.info('Detected NTP service: %s' % service) return service except: continue - logger.warning('No NTP service detected (ntp/ntpsec/chrony)') + logger.warning('No active NTP service detected (ntp/chrony)') return None class ZTPEngine(): @@ -837,8 +837,7 @@ def __forceRestartDiscovery(self, msg): def __restart_network_services(self): '''! - Restart the necessary services: stop and start NTP, and restart interfaces-config. - Detects which NTP service is available (ntp, ntpsec, or chrony). + Restart interfaces-config while rebinding the active NTP service, if any. ''' ntp_service = get_ntp_service_name() @@ -846,13 +845,17 @@ def __restart_network_services(self): logger.info('Stopping %s service...' % ntp_service) runCommand('systemctl stop ' + ntp_service, capture_stdout=False) - logger.info('Restarting interfaces-config service...') - runCommand('systemctl restart interfaces-config', capture_stdout=False) - - if ntp_service: - logger.info('Starting %s service...' % ntp_service) - runCommand('systemctl start ' + ntp_service, capture_stdout=False) - logger.info('%s service restarted successfully.' % ntp_service) + try: + logger.info('Restarting interfaces-config service...') + rc = runCommand('systemctl restart interfaces-config', capture_stdout=False) + if rc != 0: + logger.warning('interfaces-config restart failed with return code %d' % rc) + return rc + finally: + if ntp_service: + logger.info('Starting %s service...' % ntp_service) + runCommand('systemctl start ' + ntp_service, capture_stdout=False) + logger.info('%s service restarted successfully.' % ntp_service) def executeLoop(self, test_mode=False): '''! diff --git a/src/usr/lib/ztp/ztp-profile.sh b/src/usr/lib/ztp/ztp-profile.sh index bd06b8a..cbb9390 100755 --- a/src/usr/lib/ztp/ztp-profile.sh +++ b/src/usr/lib/ztp/ztp-profile.sh @@ -41,11 +41,11 @@ PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` PRESET=(`head -n 1 /usr/share/sonic/device/$PLATFORM/default_sku`) HW_KEY=${PRESET[0]} -# Function to detect which NTP service is available -# Different SONiC releases use: ntp, ntpsec, or chrony +# Function to detect which NTP service is active +# Different SONiC releases use: ntp or chrony get_ntp_service() { for service in chrony ntp; do - if systemctl is-enabled $service >/dev/null 2>&1; then + if systemctl is-active --quiet "$service"; then echo "$service" return 0 fi @@ -53,6 +53,30 @@ get_ntp_service() { return 1 } +restart_interfaces_config_with_ntp() { + local ntp_service + local rc + + ntp_service=$(get_ntp_service) + if [ -n "$ntp_service" ]; then + echo "Stopping $ntp_service." + updateActivity "Stopping $ntp_service" + systemctl stop "$ntp_service" + fi + + echo "Restarting interfaces-config." + updateActivity "Restarting interfaces-config" + systemctl restart interfaces-config + rc=$? + + if [ -n "$ntp_service" ]; then + systemctl start "$ntp_service" + echo "Restarted $ntp_service." + fi + + return $rc +} + # Command usage and help usage() { @@ -233,20 +257,7 @@ if [ "$CMD" = "install" ] ; then # Restart interface configuration again to pickup newly created interfaces # to start DHCP discovery if [ "$(ztp status -c)" = "4:IN-PROGRESS" ]; then - NTP_SERVICE=$(get_ntp_service) - if [ -n "$NTP_SERVICE" ]; then - echo "Stopping $NTP_SERVICE." - updateActivity "Stopping $NTP_SERVICE" - systemctl stop $NTP_SERVICE - fi - echo "Restarting interfaces-config." - updateActivity "Restarting interfaces-config" - - systemctl restart interfaces-config - if [ -n "$NTP_SERVICE" ]; then - systemctl start $NTP_SERVICE - echo "Restarted $NTP_SERVICE." - fi + restart_interfaces_config_with_ntp echo "Restarted network configuration." fi fi @@ -282,18 +293,8 @@ if [ "$CMD" = "remove" ] ; then sonic-db-cli CONFIG_DB DEL "ZTP|mode" > /dev/null fi - NTP_SERVICE=$(get_ntp_service) - if [ -n "$NTP_SERVICE" ]; then - updateActivity "Restarting network configuration and $NTP_SERVICE" - # Restart interface configuration to stop DHCP - systemctl stop $NTP_SERVICE - else - updateActivity "Restarting network configuration" - fi - systemctl restart interfaces-config - if [ -n "$NTP_SERVICE" ]; then - systemctl start $NTP_SERVICE - fi + # Restart interface configuration to stop DHCP + restart_interfaces_config_with_ntp fi # Remove ZTP DHCP policy