diff --git a/dockers/docker-database/base_image_files/redis-cli b/dockers/docker-database/base_image_files/redis-cli index 6ce1951cd4b..481cb454280 100755 --- a/dockers/docker-database/base_image_files/redis-cli +++ b/dockers/docker-database/base_image_files/redis-cli @@ -7,4 +7,10 @@ if [ -t 1 ] ; then DOCKER_EXEC_FLAGS+="t" fi -docker exec -$DOCKER_EXEC_FLAGS database redis-cli "$@" +[ "$1" -eq "$1" ] 2> /dev/null # check if the first argument is a number +if [ $? -eq 0 ]; then # if it's a number, set the database instance to operate on + DEV="$1" + shift +fi + +docker exec -$DOCKER_EXEC_FLAGS database$DEV redis-cli "$@" diff --git a/dockers/docker-fpm-frr/bgpd.conf.default.j2 b/dockers/docker-fpm-frr/bgpd.conf.default.j2 index 371f1fe3dd3..52308a36790 100644 --- a/dockers/docker-fpm-frr/bgpd.conf.default.j2 +++ b/dockers/docker-fpm-frr/bgpd.conf.default.j2 @@ -22,7 +22,24 @@ route-map TO_BGP_PEER_V4 permit 100 ! route-map TO_BGP_PEER_V6 permit 100 ! +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} +route-map HIDE_INTERNAL permit 10 + set community local-AS +! +{% endif %} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} +route-map OVERRIDE_ORIGINATOR_ID permit 10 +{% for (name, prefix) in LOOPBACK_INTERFACE|pfx_filter %} +{% if prefix | ipv4 and name == 'Loopback0' %} + set originator-id {{ prefix | ip }} +{% endif %} +{% endfor %} +! +{% endif %} router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalFrontend' %} + redistribute connected route-map HIDE_INTERNAL +{% endif %} bgp log-neighbor-changes bgp bestpath as-path multipath-relax no bgp default ipv4-unicast @@ -64,6 +81,9 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} {% if bgp_session['asn'] | int != 0 %} neighbor {{ neighbor_addr }} remote-as {{ bgp_session['asn'] }} neighbor {{ neighbor_addr }} description {{ bgp_session['name'] }} +{% if DEVICE_METADATA['localhost']['type'] == 'InternalBackend' %} + neighbor {{ neighbor_addr }} route-map OVERRIDE_ORIGINATOR_ID in +{% endif %} {# set the bgp neighbor timers if they have not default values #} {% if (bgp_session['keepalive'] is defined and bgp_session['keepalive'] | int != 60) or (bgp_session['holdtime'] is defined and bgp_session['holdtime'] | int != 180) %} @@ -87,7 +107,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} neighbor {{ neighbor_addr }} route-reflector-client {% endif %} {% if bgp_session['nhopself'] | int != 0 %} - neighbor {{ neighbor_addr }} next-hop-self + neighbor {{ neighbor_addr }} next-hop-self all {% endif %} maximum-paths 64 exit-address-family @@ -103,7 +123,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }} neighbor {{ neighbor_addr }} route-reflector-client {% endif %} {% if bgp_session['nhopself'] | int != 0 %} - neighbor {{ neighbor_addr }} next-hop-self + neighbor {{ neighbor_addr }} next-hop-self all {% endif %} {% if bgp_session['asn'] != DEVICE_METADATA['localhost']['bgp_asn'] %} neighbor {{ neighbor_addr }} route-map set-next-hop-global-v6 in diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index 9966728988b..9d47077e7c0 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -56,11 +56,11 @@ function preStartAction() WARM_DIR=/host/warmboot if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then # Load redis content from /host/warmboot/dump.rdb - docker cp $WARM_DIR/dump.rdb database:/var/lib/redis/dump.rdb + docker cp $WARM_DIR/dump.rdb database$DEV:/var/lib/redis/dump.rdb else # Create an emtpy file and overwrite any RDB if already there echo -n > /tmp/dump.rdb - docker cp /tmp/dump.rdb database:/var/lib/redis/ + docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/ fi {%- else %} : # nothing @@ -72,33 +72,39 @@ function postStartAction() {%- if docker_container_name == "database" %} # Wait until redis starts REDIS_SOCK="/var/run/redis/redis.sock" - until [[ $(/usr/bin/docker exec database redis-cli -s $REDIS_SOCK ping | grep -c PONG) -gt 0 ]]; do + EXT_REDIS_SOCK="/var/run/redis$DEV/redis.sock" # location of redis socket in the base image + until [[ $(/usr/bin/redis-cli $DEV -s $REDIS_SOCK ping | grep -c PONG) -gt 0 ]]; do sleep 1; done if [[ ("$BOOT_TYPE" == "warm" || "$BOOT_TYPE" == "fastfast") && -f $WARM_DIR/dump.rdb ]]; then rm -f $WARM_DIR/dump.rdb else # If there is a config db dump file, load it - if [ -r /etc/sonic/config_db.json ]; then - sonic-cfggen -j /etc/sonic/config_db.json --write-to-db + if [ -r /etc/sonic/config_db$DEV.json ]; then + sonic-cfggen -j /etc/sonic/config_db$DEV.json --write-to-db --redis-unix-sock-file $EXT_REDIS_SOCK fi - redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1" + redis-cli $DEV -n 4 -s $REDIS_SOCK SET "CONFIG_DB_INITIALIZED" "1" fi if [[ -x /usr/bin/db_migrator.py ]]; then # Migrate the DB to the latest schema version if needed - /usr/bin/db_migrator.py -o migrate + /usr/bin/db_migrator.py -o migrate -s $EXT_REDIS_SOCK + + # Save in memory config_db to config_db.json for 2 reasons: + # 1. Persist the DB migration result. + # 2. Save in memory DB after warm reboot. + /usr/bin/config save -y fi {%- elif docker_container_name == "swss" %} - docker exec swss rm -f /ready # remove cruft + docker exec swss$DEV rm -f /ready # remove cruft if [[ "$BOOT_TYPE" == "fast" ]] && [[ -d /host/fast-reboot ]]; then - test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss:/ - test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss:/ - test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss:/ + test -e /host/fast-reboot/fdb.json && docker cp /host/fast-reboot/fdb.json swss$DEV:/ + test -e /host/fast-reboot/arp.json && docker cp /host/fast-reboot/arp.json swss$DEV:/ + test -e /host/fast-reboot/default_routes.json && docker cp /host/fast-reboot/default_routes.json swss$DEV:/ rm -fr /host/fast-reboot fi - docker exec swss touch /ready # signal swssconfig.sh to go + docker exec swss$DEV touch /ready # signal swssconfig.sh to go {%- elif docker_container_name == "pmon" %} DEVPATH="/usr/share/sonic/device" @@ -111,7 +117,13 @@ function postStartAction() fi fi {%- elif docker_container_name == "snmp" %} - docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + if [ -z "$(ip netns)" ]; then + {%- for i in range(6) %} + redis-cli {{i}} -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + {%- endfor %} + else + redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s) + fi {%- else %} : # nothing {%- endif %} @@ -129,25 +141,26 @@ start() { HWSKU="" {%- else %} # Obtain our HWSKU as we will mount directories with these names in each docker - HWSKU=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hwsku"]'` - HOSTNAME=`sonic-cfggen -d -v 'DEVICE_METADATA["localhost"]["hostname"]'` + HWSKU=`sonic-cfggen -d -s /var/run/redis$DEV/redis.sock -v 'DEVICE_METADATA["localhost"]["hwsku"]'` + HOSTNAME=`sonic-cfggen -d -s /var/run/redis$DEV/redis.sock -v 'DEVICE_METADATA["localhost"]["hostname"]'` {%- endif %} if [ -z "$HOSTNAME" ] || ! [[ $HOSTNAME =~ ^[a-zA-Z0-9.\-]*$ ]]; then HOSTNAME=`hostname` fi - DOCKERCHECK=`docker inspect --type container {{docker_container_name}} 2>/dev/null` - if [ "$?" -eq "0" ]; then - {%- if docker_container_name == "database" %} + + DOCKERCHECK=`docker inspect --type container {{docker_container_name}}$DEV 2>/dev/null` + if [ "$?" -eq "0" ]; then + {%- if docker_container_name == "database" %} DOCKERMOUNT="" - {%- else %} + {%- else %} DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"` - {%- endif %} - if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then - {%- if docker_container_name == "database" %} - echo "Starting existing {{docker_container_name}} container" - {%- else %} - echo "Starting existing {{docker_container_name}} container with HWSKU $HWSKU" + {%- endif %} + if [ x"$DOCKERMOUNT" == x"$HWSKU" ]; then + {%- if docker_container_name == "database" %} + echo "Starting existing {{docker_container_name}}$DEV container" + {%- else %} + echo "Starting existing {{docker_container_name}}$DEV container with HWSKU $HWSKU" {%- endif %} preStartAction docker start {{docker_container_name}} @@ -189,7 +202,10 @@ start() { --tmpfs /tmp \ {%- endif %} {%- endif %} - -v /var/run/redis:/var/run/redis:rw \ +{%- if docker_container_name == "bgp" %} + -v /etc/sonic/frr$DEV:/etc/frr:rw \ +{%- endif %} + -v /var/run/redis$DEV:/var/run/redis:rw \ -v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \ {%- if docker_container_name != "database" %} -v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \ @@ -205,7 +221,7 @@ start() { } preStartAction - docker start {{docker_container_name}} + docker start {{docker_container_name}}$DEV postStartAction } @@ -214,9 +230,15 @@ wait() { } stop() { - docker stop {{docker_container_name}} + docker stop {{docker_container_name}}$DEV + {%- if docker_container_name == "namespace" %} + ip netns delete "{{docker_container_name}}$DEV" + {%- endif %} } +OP=$1 # operation to perform (start/wait/stop) +DEV=$2 # namespace/device number to operate on + case "$1" in start|wait|stop|updateHostName) cmd=$1 diff --git a/files/build_templates/multi_instance/bgp@.service.j2 b/files/build_templates/multi_instance/bgp@.service.j2 new file mode 100644 index 00000000000..0d2ea1e7494 --- /dev/null +++ b/files/build_templates/multi_instance/bgp@.service.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=BGP container +#Requires=updategraph.service +#After=updategraph.service +After=database@%i.service +Requires=database@%i.service +Before=ntp-config.service +PartOf=namespace@%i.target + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start %i +ExecStart=/usr/bin/{{docker_container_name}}.sh wait %i +ExecStop=/usr/bin/{{docker_container_name}}.sh stop %i + +[Install] +RequiredBy=namespace@%i.target diff --git a/files/build_templates/multi_instance/database@.service.j2 b/files/build_templates/multi_instance/database@.service.j2 new file mode 100644 index 00000000000..9a828e44c03 --- /dev/null +++ b/files/build_templates/multi_instance/database@.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=Database container +Requires=docker.service namespace@%i.service +After=docker.service namespace@%i.service +PartOf=namespace@%i.target + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start %i +ExecStart=/usr/bin/{{docker_container_name}}.sh wait %i +ExecStop=/usr/bin/{{docker_container_name}}.sh stop %i +Restart=on-failure +TimeoutStartSec=120 + +[Install] +RequiredBy=namespace@%i.target diff --git a/files/build_templates/multi_instance/swss@.service.j2 b/files/build_templates/multi_instance/swss@.service.j2 new file mode 100644 index 00000000000..64e3937426f --- /dev/null +++ b/files/build_templates/multi_instance/swss@.service.j2 @@ -0,0 +1,28 @@ +[Unit] +Description=switch state service +Requires=database@%i.service +#updategraph.service +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-9-2-amd64.service +{% endif %} +After=database@%i.service +#updategraph.service +After=interfaces-config@%i.service +Before=ntp-config.service +PartOf=namespace@%i.target +StartLimitIntervalSec=1200 +StartLimitBurst=3 + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/swss.sh start %i +ExecStart=/usr/local/bin/swss.sh wait %i +ExecStop=/usr/local/bin/swss.sh stop %i +Restart=always +RestartSec=30 + +[Install] +RequiredBy=namespace@%i.target diff --git a/files/build_templates/multi_instance/syncd@.service.j2 b/files/build_templates/multi_instance/syncd@.service.j2 new file mode 100644 index 00000000000..448f42c5068 --- /dev/null +++ b/files/build_templates/multi_instance/syncd@.service.j2 @@ -0,0 +1,32 @@ +[Unit] +Description=syncd service +Requires=database@%i.service +#updategraph.service +{% if sonic_asic_platform == 'broadcom' %} +Requires=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +Requires=nps-modules-4.9.0-8-2-amd64.service +{% endif %} +After=database.service +#updategraph.service +After=interfaces-config.service +{% if sonic_asic_platform == 'broadcom' %} +After=opennsl-modules.service +{% elif sonic_asic_platform == 'nephos' %} +After=nps-modules-4.9.0-8-2-amd64.service +{% endif %} +After=swss@%i.service +Before=ntp-config.service + +[Service] +User=root +Environment=sonic_asic_platform={{ sonic_asic_platform }} +ExecStartPre=/usr/local/bin/syncd.sh start %i +ExecStart=/usr/local/bin/syncd.sh wait %i +ExecStop=/usr/local/bin/syncd.sh stop %i +{% if sonic_asic_platform == 'mellanox' %} +TimeoutStartSec=150 +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/files/build_templates/multi_instance/teamd@.service.j2 b/files/build_templates/multi_instance/teamd@.service.j2 new file mode 100644 index 00000000000..6d9ea7f301e --- /dev/null +++ b/files/build_templates/multi_instance/teamd@.service.j2 @@ -0,0 +1,18 @@ +[Unit] +Description=TEAMD container +#Requires=updategraph.service +Requires=swss@%i.service +#After=updategraph.service +After=swss@%i.service +Before=ntp-config.service +PartOf=namespace@%i.target + +[Service] +User=root +ExecStartPre=/usr/bin/{{docker_container_name}}.sh start %i +ExecStart=/usr/bin/{{docker_container_name}}.sh wait %i +ExecStop=/usr/bin/{{docker_container_name}}.sh stop %i + +[Install] +WantedBy=swss@%i.service +RequiredBy=namespace@%i.target diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 0f27c15273c..b683b13fc29 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -170,10 +170,14 @@ echo "warmboot-finalizer.service" | sudo tee -a $GENERATED_SERVICE_FILE # Copy rsyslog configuration files and templates sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config@.service $FILESYSTEM_ROOT/etc/systemd/system/ +sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog@.service $FILESYSTEM_ROOT/etc/systemd/system sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.conf.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ sudo cp $IMAGE_CONFIGS/rsyslog/rsyslog.d/* $FILESYSTEM_ROOT/etc/rsyslog.d/ echo "rsyslog-config.service" | sudo tee -a $GENERATED_SERVICE_FILE +echo "rsyslog-config@.service" | sudo tee -a $GENERATED_SERVICE_FILE +echo "rsyslog@.service" | sudo tee -a $GENERATED_SERVICE_FILE # Copy logrotate.d configuration files sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate.d/ @@ -182,9 +186,11 @@ sudo cp -f $IMAGE_CONFIGS/logrotate/logrotate.d/* $FILESYSTEM_ROOT/etc/logrotate sudo cp -f $IMAGE_CONFIGS/systemd/journald.conf $FILESYSTEM_ROOT/etc/systemd/ # Copy interfaces configuration files and templates +sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config@.service $FILESYSTEM_ROOT/etc/systemd/system/ sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.service $FILESYSTEM_ROOT/etc/systemd/system/ sudo cp $IMAGE_CONFIGS/interfaces/interfaces-config.sh $FILESYSTEM_ROOT/usr/bin/ sudo cp $IMAGE_CONFIGS/interfaces/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ +echo "interfaces-config@.service" | sudo tee -a $GENERATED_SERVICE_FILE echo "interfaces-config.service" | sudo tee -a $GENERATED_SERVICE_FILE # Copy initial interfaces configuration file, will be overwritten on first boot @@ -344,6 +350,13 @@ sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh +# Copy network namespace wrapper script +sudo LANG=C cp $SCRIPTS_DIR/namespace.sh $FILESYSTEM_ROOT/usr/local/bin/namespace + +# Copy namespace target +sudo cp $IMAGE_CONFIGS/namespace/namespace@.target $FILESYSTEM_ROOT/etc/systemd/system/ +echo "namespace@.target" | sudo tee -a $GENERATED_SERVICE_FILE + # Copy systemd timer configuration # It implements delayed start of services sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/ @@ -372,6 +385,14 @@ sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/mlnx-fw-upgrade.sh {% endif %} {%- if SONIC_ROUTING_STACK == "frr" %} + {% for i in range(6) %} +sudo mkdir $FILESYSTEM_ROOT/etc/sonic/frr{{i}} +sudo touch $FILESYSTEM_ROOT/etc/sonic/frr{{i}}/frr.conf +sudo touch $FILESYSTEM_ROOT/etc/sonic/frr{{i}}/vtysh.conf +sudo chown -R $FRR_USER_UID:$FRR_USER_GID $FILESYSTEM_ROOT/etc/sonic/frr{{i}} +sudo chmod -R 640 $FILESYSTEM_ROOT/etc/sonic/frr{{i}}/ +sudo chmod 750 $FILESYSTEM_ROOT/etc/sonic/frr{{i}} + {%- endfor %} sudo mkdir $FILESYSTEM_ROOT/etc/sonic/frr sudo touch $FILESYSTEM_ROOT/etc/sonic/frr/frr.conf sudo touch $FILESYSTEM_ROOT/etc/sonic/frr/vtysh.conf diff --git a/files/image_config/interfaces/interfaces-config.service b/files/image_config/interfaces/interfaces-config.service index 71178affdee..fa2077c4e49 100644 --- a/files/image_config/interfaces/interfaces-config.service +++ b/files/image_config/interfaces/interfaces-config.service @@ -8,4 +8,4 @@ Type=oneshot ExecStart=/usr/bin/interfaces-config.sh [Install] -WantedBy=multi-user.target +RequiredBy=multi-user.target diff --git a/files/image_config/interfaces/interfaces-config.sh b/files/image_config/interfaces/interfaces-config.sh index a702917419c..bc4f5a50fbd 100755 --- a/files/image_config/interfaces/interfaces-config.sh +++ b/files/image_config/interfaces/interfaces-config.sh @@ -1,11 +1,21 @@ #!/bin/bash -ifdown --force eth0 +NS=$1 -sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces +if [ -z "$(ip netns)" ]; then + ifdown --force eth0 + sonic-cfggen -d -t /usr/share/sonic/templates/interfaces.j2 > /etc/network/interfaces + [ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid + systemctl restart networking + ifdown lo && ifup lo +else + INTF_LIST=`redis-cli $NS -n 4 KEYS 'LOOPBACK_INTERFACE*'` + for ENTRY in $INTF_LIST; do + IFS='|' read -ra ADDR_ARRAY <<< "$ENTRY" + ADDR=${ADDR_ARRAY[2]} + namespace $NS ip addr add $ADDR dev lo + done +fi -[ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid -systemctl restart networking -ifdown lo && ifup lo diff --git a/files/image_config/interfaces/interfaces-config@.service b/files/image_config/interfaces/interfaces-config@.service new file mode 100644 index 00000000000..96335931ba4 --- /dev/null +++ b/files/image_config/interfaces/interfaces-config@.service @@ -0,0 +1,14 @@ +[Unit] +Description=Update interfaces configuration +Requires=database@%i.service +After=database@%i.service +#Requires=updategraph.service +#After=updategraph.service +PartOf=namespace@%i.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/interfaces-config.sh %i + +[Install] +RequiredBy=namespace@%i.target diff --git a/files/image_config/namespace/namespace@.target b/files/image_config/namespace/namespace@.target new file mode 100644 index 00000000000..58cef23bf87 --- /dev/null +++ b/files/image_config/namespace/namespace@.target @@ -0,0 +1,9 @@ +[Unit] +Description=Synchronization Target for Individual Namespace +Wants=topology.service +Requires=namespace@i.service +After=topology.service namespace@i.service +PartOf=namespace@%i.service + +[Install] +WantedBy=multi-user.target diff --git a/files/image_config/rsyslog/rsyslog-config.sh b/files/image_config/rsyslog/rsyslog-config.sh index c8ba7b99453..83f556cee42 100755 --- a/files/image_config/rsyslog/rsyslog-config.sh +++ b/files/image_config/rsyslog/rsyslog-config.sh @@ -1,4 +1,4 @@ #!/bin/bash -sonic-cfggen -d -t /usr/share/sonic/templates/rsyslog.conf.j2 >/etc/rsyslog.conf +sonic-cfggen -s /var/run/redis$1/redis.sock -d -t /usr/share/sonic/templates/rsyslog.conf.j2 >/etc/rsyslog$1.conf systemctl restart rsyslog diff --git a/files/image_config/rsyslog/rsyslog-config@.service b/files/image_config/rsyslog/rsyslog-config@.service new file mode 100644 index 00000000000..9f8d03345b8 --- /dev/null +++ b/files/image_config/rsyslog/rsyslog-config@.service @@ -0,0 +1,14 @@ +[Unit] +Description=Update rsyslog configuration +Requires=database@%i.service +After=database@%i.service +#Requires=updategraph.service +#After=updategraph.service +PartOf=namespace@%i.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/rsyslog-config.sh %i + +[Install] +RequiredBy=namespace@%i.target diff --git a/files/image_config/rsyslog/rsyslog@.service b/files/image_config/rsyslog/rsyslog@.service new file mode 100644 index 00000000000..36841652026 --- /dev/null +++ b/files/image_config/rsyslog/rsyslog@.service @@ -0,0 +1,14 @@ +[Unit] +Description=Network Namespace Compatible Logging Service +Requires=syslog.socket +After=rsyslog-config@%i.service + +[Service] +Type=notify +User=root +ExecStart=/bin/ip netns exec namespace%i /usr/sbin/rsyslogd -n -i /var/run/rsyslogd%i.pid -f /etc/rsyslog%i.conf +StandardOutput=null +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/files/scripts/namespace.sh b/files/scripts/namespace.sh new file mode 100755 index 00000000000..43916544828 --- /dev/null +++ b/files/scripts/namespace.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +NS=$1 +shift + +sudo ip netns exec asic$NS $@ diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh index 88bce037b9c..5fea9db6240 100755 --- a/files/scripts/swss.sh +++ b/files/scripts/swss.sh @@ -1,9 +1,5 @@ #!/bin/bash -SERVICE="swss" -PEER="syncd" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -30,8 +26,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`/usr/bin/redis-cli $DEV -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`/usr/bin/redis-cli $DEV -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" else @@ -42,7 +38,7 @@ function check_warm_boot() function validate_restore_count() { if [[ x"$WARM_BOOT" == x"true" ]]; then - RESTORE_COUNT=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` + RESTORE_COUNT=`/usr/bin/redis-cli $DEV -n 6 hget "WARM_RESTART_TABLE|orchagent" restore_count` # We have to make sure db data has not been flushed. if [[ -z "$RESTORE_COUNT" ]]; then WARM_BOOT="false" @@ -53,12 +49,12 @@ function validate_restore_count() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + until [[ $(/usr/bin/redis-cli $DEV ping | grep -c PONG) -gt 0 ]]; do sleep 1; done # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/redis-cli $DEV -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -68,7 +64,7 @@ function wait_for_database_service() # $2 the string of a list of table prefixes function clean_up_tables() { - redis-cli -n $1 EVAL " + redis-cli $DEV -n $1 EVAL " local tables = {$2} for i = 1, table.getn(tables) do local matches = redis.call('KEYS', tables[i]) @@ -82,7 +78,11 @@ startPeerService() { check_warm_boot if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl start ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl start ${PEER}@$DEV + else + /bin/systemctl start ${PEER} + fi fi } @@ -100,15 +100,15 @@ start() { # Don't flush DB during warm boot if [[ x"$WARM_BOOT" != x"true" ]]; then debug "Flushing APP, ASIC, COUNTER, CONFIG, and partial STATE databases ..." - /usr/bin/docker exec database redis-cli -n 0 FLUSHDB - /usr/bin/docker exec database redis-cli -n 1 FLUSHDB - /usr/bin/docker exec database redis-cli -n 2 FLUSHDB - /usr/bin/docker exec database redis-cli -n 5 FLUSHDB + /usr/bin/redis-cli $DEV -n 0 FLUSHDB + /usr/bin/redis-cli $DEV -n 1 FLUSHDB + /usr/bin/redis-cli $DEV -n 2 FLUSHDB + /usr/bin/redis-cli $DEV -n 5 FLUSHDB clean_up_tables 6 "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*'" fi # start service docker - /usr/bin/${SERVICE}.sh start + /usr/bin/${SERVICE}.sh start $DEV debug "Started ${SERVICE} service..." # Unlock has to happen before reaching out to peer service @@ -117,7 +117,7 @@ start() { wait() { startPeerService - /usr/bin/${SERVICE}.sh wait + /usr/bin/${SERVICE}.sh wait $DEV } stop() { @@ -129,7 +129,7 @@ stop() { check_warm_boot debug "Warm boot flag: ${SERVICE} ${WARM_BOOT}." - /usr/bin/${SERVICE}.sh stop + /usr/bin/${SERVICE}.sh stop $DEV debug "Stopped ${SERVICE} service..." # Unlock has to happen before reaching out to peer service @@ -137,10 +137,21 @@ stop() { # if warm start enabled or peer lock exists, don't stop peer service docker if [[ x"$WARM_BOOT" != x"true" ]]; then - /bin/systemctl stop ${PEER} + if [[ ! -z $DEV ]]; then + /bin/systemctl stop ${PEER}@$DEV + else + /bin/systemctl stop ${PEER} + fi fi } +DEV=$2 + +SERVICE="swss" +PEER="syncd" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" + case "$1" in start|wait|stop) $1 diff --git a/files/scripts/syncd.sh b/files/scripts/syncd.sh index d4536b4d8b9..a5e2e5f624a 100755 --- a/files/scripts/syncd.sh +++ b/files/scripts/syncd.sh @@ -1,9 +1,5 @@ #!/bin/bash -SERVICE="syncd" -PEER="swss" -DEBUGLOG="/tmp/swss-syncd-debug.log" -LOCKFILE="/tmp/swss-syncd-lock" function debug() { @@ -30,8 +26,8 @@ function unlock_service_state_change() function check_warm_boot() { - SYSTEM_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` - SERVICE_WARM_START=`/usr/bin/redis-cli -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` + SYSTEM_WARM_START=`/usr/bin/redis-cli $DEV -n 6 hget "WARM_RESTART_ENABLE_TABLE|system" enable` + SERVICE_WARM_START=`/usr/bin/redis-cli $DEV -n 6 hget "WARM_RESTART_ENABLE_TABLE|${SERVICE}" enable` # SYSTEM_WARM_START could be empty, always make WARM_BOOT meaningful. if [[ x"$SYSTEM_WARM_START" == x"true" ]] || [[ x"$SERVICE_WARM_START" == x"true" ]]; then WARM_BOOT="true" @@ -43,12 +39,12 @@ function check_warm_boot() function wait_for_database_service() { # Wait for redis server start before database clean - until [[ $(/usr/bin/docker exec database redis-cli ping | grep -c PONG) -gt 0 ]]; + until [[ $(/usr/bin/redis-cli $DEV ping | grep -c PONG) -gt 0 ]]; do sleep 1; done # Wait for configDB initialization - until [[ $(/usr/bin/docker exec database redis-cli -n 4 GET "CONFIG_DB_INITIALIZED") ]]; + until [[ $(/usr/bin/redis-cli $DEV -n 4 GET "CONFIG_DB_INITIALIZED") ]]; do sleep 1; done } @@ -127,14 +123,14 @@ start() { fi # start service docker - /usr/bin/${SERVICE}.sh start + /usr/bin/${SERVICE}.sh start $DEV debug "Started ${SERVICE} service..." unlock_service_state_change } wait() { - /usr/bin/${SERVICE}.sh wait + /usr/bin/${SERVICE}.sh wait $DEV } stop() { @@ -152,18 +148,18 @@ stop() { if [[ x$sonic_asic_platform != x"mellanox" ]] || [[ x$TYPE != x"cold" ]]; then debug "${TYPE} shutdown syncd process ..." - /usr/bin/docker exec -i syncd /usr/bin/syncd_request_shutdown --${TYPE} + /usr/bin/docker exec -i syncd$DEV /usr/bin/syncd_request_shutdown --${TYPE} # wait until syncd quits gracefully - while docker top syncd | grep -q /usr/bin/syncd; do + while docker top syncd$DEV | grep -q /usr/bin/syncd; do sleep 0.1 done - /usr/bin/docker exec -i syncd /bin/sync + /usr/bin/docker exec -i syncd$DEV /bin/sync debug "Finished ${TYPE} shutdown syncd process ..." fi - /usr/bin/${SERVICE}.sh stop + /usr/bin/${SERVICE}.sh stop $DEV debug "Stopped ${SERVICE} service..." # platform specific tasks @@ -181,6 +177,14 @@ stop() { unlock_service_state_change } +OP=$1 +DEV=$2 + +SERVICE="syncd" +PEER="swss" +DEBUGLOG="/tmp/swss-syncd-debug$DEV.log" +LOCKFILE="/tmp/swss-syncd-lock$DEV" + case "$1" in start|wait|stop) $1 diff --git a/platform/vs/sonic.xml b/platform/vs/sonic.xml index ebf9f542607..9d72d0e91f7 100644 --- a/platform/vs/sonic.xml +++ b/platform/vs/sonic.xml @@ -1,8 +1,7 @@ sonic - 2048000 - 2048000 - 1 + 8 + 2 /machine diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk index 1d158effe7f..1651772fc53 100644 --- a/rules/docker-fpm-frr.mk +++ b/rules/docker-fpm-frr.mk @@ -24,7 +24,6 @@ SONIC_STRETCH_DBG_DOCKERS += $(DOCKER_FPM_FRR_DBG) $(DOCKER_FPM_FRR)_CONTAINER_NAME = bgp $(DOCKER_FPM_FRR)_RUN_OPT += --net=host --privileged -t $(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro -$(DOCKER_FPM_FRR)_RUN_OPT += -v /etc/sonic/frr:/etc/frr:rw $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += vtysh:/usr/bin/vtysh $(DOCKER_FPM_FRR)_BASE_IMAGE_FILES += TSA:/usr/bin/TSA