[202012] [Fastboot] Delay LLDP service for better fastboot performance (#10568) (#10744)

This PR is to backport a fix #10568
This PR is dependent on PR: #10745

- Why I did it
Profiling the system state on init after fast-reboot during create_switch function execution, it is possible to see few python scripts running at the same time.
This parallel execution consume CPU time and the duration of create_switch is longer than it should be.
Following this finding, and the motivation to ensure these services will not interfere in the future, LLDP is delayed in 90 seconds until the system finish the init flow after fastboot.

- How I did it
Add a timer for LLDP service.
Copy the timer file to the host bin image.

- How to verify it
Run fast-reboot on MLNX platform and observe faster create_switch execution time.
This commit is contained in:
shlomibitton 2022-05-15 15:05:29 +03:00 committed by GitHub
parent 4f326e8779
commit bca8a244c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 7 deletions

View File

@ -21,7 +21,7 @@
{%- set features = [("bgp", "enabled", false, "enabled"), {%- set features = [("bgp", "enabled", false, "enabled"),
("database", "always_enabled", false, "always_enabled"), ("database", "always_enabled", false, "always_enabled"),
("dhcp_relay", "enabled", false, "enabled"), ("dhcp_relay", "enabled", false, "enabled"),
("lldp", "enabled", false, "enabled"), ("lldp", "enabled", true, "enabled"),
("pmon", "enabled", false, "enabled"), ("pmon", "enabled", false, "enabled"),
("radv", "enabled", false, "enabled"), ("radv", "enabled", false, "enabled"),
("snmp", "enabled", true, "enabled"), ("snmp", "enabled", true, "enabled"),

View File

@ -0,0 +1 @@
per_namespace/lldp.timer.j2

View File

@ -21,6 +21,3 @@ ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'tru
ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %} ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %}
Restart=always Restart=always
RestartSec=30 RestartSec=30
[Install]
WantedBy=sonic.target

View File

@ -0,0 +1,12 @@
[Unit]
# This delay is for fast/warm reboot performance
Description=Delays LLDP docker until SONiC has started
PartOf=lldp{% if multi_instance == 'true' %}@%i{% endif %}.service
[Timer]
OnUnitActiveSec=0 sec
OnBootSec=1min 30 sec
Unit=lldp{% if multi_instance == 'true' %}@%i{% endif %}.service
[Install]
WantedBy=timers.target sonic.target sonic-delayed.target

View File

@ -700,6 +700,19 @@ if [ -f {{service}} ]; then
echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE echo "{{service}}" | sudo tee -a $GENERATED_SERVICE_FILE
fi fi
{% endfor %} {% endfor %}
{% for timer in installer_timers.split(' ') -%}
if [ -f {{timer}} ]; then
sudo cp {{timer}} $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM
{% if "@" in timer %}
MULTI_INSTANCE="{{timer}}"
SINGLE_INSTANCE=${MULTI_INSTANCE/"@"}
sudo cp $SINGLE_INSTANCE $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM
{% endif %}
echo "{{timer}}" | sudo tee -a $GENERATED_SERVICE_FILE
fi
{% endfor %}
if [ -f iccpd.service ]; then if [ -f iccpd.service ]; then
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable iccpd.service sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable iccpd.service
fi fi

View File

@ -36,12 +36,19 @@ function startplatform() {
} }
function waitplatform() { function waitplatform() {
if [[ x"$sonic_asic_platform" == x"mellanox" ]]; then if [[ x"$sonic_asic_platform" == x"mellanox" ]]; then
debug "Starting pmon service..." debug "Starting pmon service..."
/bin/systemctl start pmon /bin/systemctl start pmon
debug "Started pmon service" debug "Started pmon service"
fi fi
if [[ x"$BOOT_TYPE" = @(x"fast"|x"warm"|x"fastfast") ]]; then
debug "LLDP service is delayed by a timer for better fast/warm boot performance"
else
debug "Starting lldp service..."
/bin/systemctl start lldp
debug "Started lldp service"
fi
} }
function stopplatform1() { function stopplatform1() {
@ -56,7 +63,7 @@ function stopplatform1() {
debug "${TYPE} shutdown syncd process ..." debug "${TYPE} shutdown syncd process ..."
/usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE}
# wait until syncd quits gracefully or force syncd to exit after # wait until syncd quits gracefully or force syncd to exit after
# waiting for 20 seconds # waiting for 20 seconds
start_in_secs=${SECONDS} start_in_secs=${SECONDS}
end_in_secs=${SECONDS} end_in_secs=${SECONDS}
@ -68,7 +75,7 @@ function stopplatform1() {
done done
if [[ $((end_in_secs - start_in_secs)) -gt $timer_threshold ]]; then if [[ $((end_in_secs - start_in_secs)) -gt $timer_threshold ]]; then
debug "syncd process in container syncd$DEV did not exit gracefully" debug "syncd process in container syncd$DEV did not exit gracefully"
fi fi
/usr/bin/docker exec -i syncd$DEV /bin/sync /usr/bin/docker exec -i syncd$DEV /bin/sync

View File

@ -975,6 +975,14 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
$(eval $(docker:-dbg.gz=.gz)_GLOBAL = yes) $(eval $(docker:-dbg.gz=.gz)_GLOBAL = yes)
) )
fi fi
if [ -f files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer.j2 ]; then
j2 files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer
# Set the flag GLOBAL_TIMER for all the global system-wide dockers timers.
$(if $(shell ls files/build_templates/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer.j2 2>/dev/null),\
$(eval $(docker:-dbg.gz=.gz)_GLOBAL_TIMER = yes)
)
fi
# Any service template, inside instance directory, will be used to generate .service and @.service file. # Any service template, inside instance directory, will be used to generate .service and @.service file.
if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then
export multi_instance="true" export multi_instance="true"
@ -985,6 +993,16 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
export multi_instance="false" export multi_instance="false"
j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service
fi fi
# Any timer template, inside instance directory, will be used to generate .timer and @.timer file.
if [ -f files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer.j2 ]; then
export multi_instance="true"
j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME)@.timer
$(if $(shell ls files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer.j2 2>/dev/null),\
$(eval $(docker:-dbg.gz=.gz)_TEMPLATE_TIMER = yes)
)
export multi_instance="false"
j2 files/build_templates/per_namespace/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer.j2 > $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).timer
fi
# Any service template, inside share_image directory, will be used to generate -chassis.service file. # Any service template, inside share_image directory, will be used to generate -chassis.service file.
# TODO: need better way to name the image-shared service # TODO: need better way to name the image-shared service
if [ -f files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then if [ -f files/build_templates/share_image/$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).service.j2 ]; then
@ -1017,7 +1035,20 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
$(eval SERVICES += "$(addsuffix -chassis.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))") $(eval SERVICES += "$(addsuffix -chassis.service, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")
) )
) )
# Marks template timers with an "@" according to systemd convention
# If the $($docker)_TEMPLATE_TIMER) variable is set, the timer will be treated as a template
# If the $($docker)_GLOBAL_TIMER) and $($docker)_TEMPLATE_TIMER) variables are set the timer will be added both as a global and template timer.
$(foreach docker, $($*_DOCKERS),\
$(if $($(docker:-dbg.gz=.gz)_TEMPLATE_TIMER),\
$(if $($(docker:-dbg.gz=.gz)_GLOBAL_TIMER),\
$(eval TIMERS += "$(addsuffix .timer, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")\
)\
$(eval TIMERS += "$(addsuffix @.timer, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))"),\
$(eval TIMERS += "$(addsuffix .timer, $($(docker:-dbg.gz=.gz)_CONTAINER_NAME))")
)
)
export installer_services="$(SERVICES)" export installer_services="$(SERVICES)"
export installer_timers="$(TIMERS)"
export installer_extra_files="$(foreach docker, $($*_DOCKERS), $(foreach file, $($(docker:-dbg.gz=.gz)_BASE_IMAGE_FILES), $($(docker:-dbg.gz=.gz)_PATH)/base_image_files/$(file)))" export installer_extra_files="$(foreach docker, $($*_DOCKERS), $(foreach file, $($(docker:-dbg.gz=.gz)_BASE_IMAGE_FILES), $($(docker:-dbg.gz=.gz)_PATH)/base_image_files/$(file)))"