Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[multi-asic]: Update reload of systemd services to support multi-asic platforms #856

Merged
110 changes: 58 additions & 52 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@
SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen'
SYSLOG_IDENTIFIER = "config"
VLAN_SUB_INTERFACE_SEPARATOR = '.'
ASIC_CONF_FILENAME = 'asic.conf'

INIT_CFG_FILE = '/etc/sonic/init_cfg.json'

SYSTEMCTL_STOP="stop"
lguohan marked this conversation as resolved.
Show resolved Hide resolved
SYSTEMCTL_RESTART="restart"
SYSTEMCTL_RESET_FAILED="reset-failed"

# ========================== Syslog wrappers ==========================

def log_debug(msg):
Expand Down Expand Up @@ -69,6 +74,35 @@ def log_error(msg):
# Helper functions
#

# Execute action on list of systemd services
def execute_systemctl(list_of_services, action):
num_asic = _get_num_asic()
generated_services_list, generated_multi_instance_services = _get_sonic_generated_services()
if ((generated_services_list == []) and
(generated_multi_instance_services == [])):
log_error("Failed to get generated services")
return

for service in list_of_services:
if ((service + '.service' in generated_services_list) or
lguohan marked this conversation as resolved.
Show resolved Hide resolved
((service + '.service' in generated_multi_instance_services) and
(num_asic == 1))):
try:
click.echo("Executing {} action on service {}...".format(action, service))
run_command("systemctl {} {}".format(action, service))
except SystemExit as e:
log_error("Failed to execute {} for service {}".format(action, service))
raise
if ((service + '.service' in generated_multi_instance_services) and
(num_asic > 1)):
for inst in range(num_asic):
try:
click.echo("Executing {} action on service {}@{}...".format(action, service, inst))
run_command("systemctl {} {}@{}.service".format(action, service, inst))
except SystemExit as e:
log_error("Failed to execute {} for service {}@{}".format(action, service, e))
raise


def run_command(command, display_cmd=False, ignore_error=False):
"""Run bash command and print output to stdout
Expand Down Expand Up @@ -395,14 +429,33 @@ def _get_platform():
return tokens[1].strip()
return ''

def _get_num_asic():
platform = _get_platform()
asic_conf_file = os.path.join('/usr/share/sonic/device/', platform, ASIC_CONF_FILENAME)
if not os.path.isfile(asic_conf_file):
num_asic=1
lguohan marked this conversation as resolved.
Show resolved Hide resolved
else:
with open(asic_conf_file) as conf_file:
for line in conf_file:
line_info=line.split('=')
lguohan marked this conversation as resolved.
Show resolved Hide resolved
if line_info[0].lower() == "num_asic":
print line_info[1]
lguohan marked this conversation as resolved.
Show resolved Hide resolved
num_asic=int(line_info[1])
lguohan marked this conversation as resolved.
Show resolved Hide resolved
return num_asic

def _get_sonic_generated_services():
if not os.path.isfile(SONIC_GENERATED_SERVICE_PATH):
return None
generated_services_list = []
generated_multi_instance_services = []
with open(SONIC_GENERATED_SERVICE_PATH) as generated_service_file:
for line in generated_service_file:
generated_services_list.append(line.rstrip('\n'))
return None if not generated_services_list else generated_services_list
if '@' in line:
line=line.replace('@', '')
generated_multi_instance_services.append(line.rstrip('\n'))
else:
generated_services_list.append(line.rstrip('\n'))
lguohan marked this conversation as resolved.
Show resolved Hide resolved
return generated_services_list, generated_multi_instance_services

# Callback for confirmation prompt. Aborts if user enters "n"
def _abort_if_false(ctx, param, value):
Expand All @@ -419,25 +472,7 @@ def _stop_services():
'hostcfgd',
'nat'
]
generated_services_list = _get_sonic_generated_services()

if generated_services_list is None:
log_error("Failed to get generated services")
return

if asic_type == 'mellanox' and 'pmon' in services_to_stop:
services_to_stop.remove('pmon')
lguohan marked this conversation as resolved.
Show resolved Hide resolved

for service in services_to_stop:
if service + '.service' not in generated_services_list:
continue
try:
click.echo("Stopping service {} ...".format(service))
run_command("systemctl stop {}".format(service))

except SystemExit as e:
log_error("Stopping {} failed with error {}".format(service, e))
raise
execute_systemctl(services_to_stop, SYSTEMCTL_STOP)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please check the return results and act accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

execute_systemctl() - this function prints error message or handles exception itself, should we further get return value and act?


def _reset_failed_services():
services_to_reset = [
Expand All @@ -458,22 +493,9 @@ def _reset_failed_services():
'nat',
'sflow'
]
execute_systemctl(services_to_reset, SYSTEMCTL_RESET_FAILED)

generated_services_list = _get_sonic_generated_services()

if generated_services_list is None:
log_error("Failed to get generated services")
return

for service in services_to_reset:
if service + '.service' not in generated_services_list:
continue
try:
click.echo("Resetting failed status for service {} ...".format(service))
run_command("systemctl reset-failed {}".format(service))
except SystemExit as e:
log_error("Failed to reset failed status for service {}".format(service))
raise

def _restart_services():
# on Mellanox platform pmon is started by syncd
Expand All @@ -490,24 +512,8 @@ def _restart_services():
'nat',
'sflow',
]
generated_services_list = _get_sonic_generated_services()

if generated_services_list is None:
log_error("Failed to get generated services")
return
execute_systemctl(services_to_restart, SYSTEMCTL_RESTART)

if asic_type == 'mellanox' and 'pmon' in services_to_restart:
services_to_restart.remove('pmon')

for service in services_to_restart:
if service + '.service' not in generated_services_list:
continue
try:
click.echo("Restarting service {} ...".format(service))
run_command("systemctl restart {}".format(service))
except SystemExit as e:
log_error("Restart {} failed with error {}".format(service, e))
raise

def is_ipaddress(val):
""" Validate if an entry is a valid IP """
Expand Down