2017-01-29 13:33:33 -06:00
|
|
|
#!/bin/bash
|
|
|
|
|
2017-09-14 10:43:02 -05:00
|
|
|
function getMountPoint()
|
|
|
|
{
|
2018-11-02 09:20:07 -05:00
|
|
|
echo $1 | python -c "import sys, json, os; mnts = [x for x in json.load(sys.stdin)[0]['Mounts'] if x['Destination'] == '/usr/share/sonic/hwsku']; print '' if len(mnts) == 0 else os.path.basename(mnts[0]['Source'])" 2>/dev/null
|
|
|
|
}
|
|
|
|
|
|
|
|
function getBootType()
|
|
|
|
{
|
2018-12-04 12:11:24 -06:00
|
|
|
local BOOT_TYPE
|
|
|
|
case "$(cat /proc/cmdline | grep -o 'SONIC_BOOT_TYPE=\S*' | cut -d'=' -f2)" in
|
|
|
|
warm*)
|
2018-11-02 09:20:07 -05:00
|
|
|
TYPE='warm'
|
|
|
|
;;
|
2018-12-04 12:11:24 -06:00
|
|
|
fastfast)
|
|
|
|
TYPE='fastfast'
|
|
|
|
;;
|
|
|
|
fast*)
|
|
|
|
TYPE='fast'
|
|
|
|
;;
|
2018-11-02 09:20:07 -05:00
|
|
|
*)
|
2018-11-22 17:13:35 -06:00
|
|
|
TYPE='cold'
|
2018-11-02 09:20:07 -05:00
|
|
|
esac
|
2018-12-04 12:11:24 -06:00
|
|
|
echo "${TYPE}"
|
2017-09-14 10:43:02 -05:00
|
|
|
}
|
|
|
|
|
2018-11-22 17:13:35 -06:00
|
|
|
function preStartAction()
|
|
|
|
{
|
|
|
|
{%- if docker_container_name == "database" %}
|
|
|
|
WARM_DIR=/host/warmboot
|
|
|
|
if [[ "$BOOT_TYPE" == "warm" && -f $WARM_DIR/dump.rdb ]]; then
|
2018-12-04 12:11:24 -06:00
|
|
|
# Load redis content from /host/warmboot/dump.rdb
|
2018-11-22 17:13:35 -06:00
|
|
|
docker cp $WARM_DIR/dump.rdb database:/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/
|
|
|
|
fi
|
|
|
|
{%- else %}
|
|
|
|
: # nothing
|
|
|
|
{%- endif %}
|
|
|
|
}
|
|
|
|
|
2017-09-14 10:43:02 -05:00
|
|
|
function postStartAction()
|
|
|
|
{
|
2018-02-26 13:23:29 -06:00
|
|
|
{%- if docker_container_name == "database" %}
|
2018-11-22 17:13:35 -06:00
|
|
|
# Wait until redis starts
|
2018-11-02 09:20:07 -05:00
|
|
|
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
|
2018-11-22 17:13:35 -06:00
|
|
|
sleep 1;
|
2017-09-14 10:43:02 -05:00
|
|
|
done
|
2018-11-22 17:13:35 -06:00
|
|
|
if [[ "$BOOT_TYPE" == "warm" && -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
|
|
|
|
fi
|
|
|
|
|
|
|
|
redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1"
|
2018-11-02 09:20:07 -05:00
|
|
|
fi
|
2018-02-26 13:23:29 -06:00
|
|
|
{%- elif docker_container_name == "swss" %}
|
|
|
|
docker exec swss rm -f /ready # remove cruft
|
2018-12-04 12:11:24 -06:00
|
|
|
if [[ "$BOOT_TYPE" == "fast" || "$BOOT_TYPE" == "fastfast" ]] && [[ -d /host/fast-reboot ]]; then
|
2018-02-26 13:23:29 -06:00
|
|
|
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:/
|
|
|
|
rm -fr /host/fast-reboot
|
|
|
|
fi
|
|
|
|
docker exec swss touch /ready # signal swssconfig.sh to go
|
2018-06-22 12:48:44 -05:00
|
|
|
{%- elif docker_container_name == "pmon" %}
|
|
|
|
|
|
|
|
DEVPATH="/usr/share/sonic/device"
|
|
|
|
REBOOT="platform_reboot"
|
|
|
|
PSENSOR="/usr/local/bin/platform_sensors.py"
|
|
|
|
if [ -d ${DEVPATH}/${PLATFORM} ] && [ -f $PSENSOR ]; then
|
|
|
|
exist=`docker exec -i pmon ls /usr/bin/platform_sensors.py "$@" 2>/dev/null`
|
|
|
|
if [ -z "$exist" ]; then
|
|
|
|
docker cp $PSENSOR pmon:/usr/bin/
|
|
|
|
fi
|
|
|
|
fi
|
2018-02-26 13:23:29 -06:00
|
|
|
{%- elif docker_container_name == "snmp" %}
|
2017-12-19 18:02:26 -06:00
|
|
|
docker exec -i database redis-cli -n 6 HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s)
|
2018-02-26 13:23:29 -06:00
|
|
|
{%- else %}
|
2018-02-26 19:42:20 -06:00
|
|
|
: # nothing
|
2017-12-19 18:02:26 -06:00
|
|
|
{%- endif %}
|
2017-09-14 10:43:02 -05:00
|
|
|
}
|
|
|
|
|
2018-10-12 10:39:06 -05:00
|
|
|
start() {
|
2018-11-22 17:13:35 -06:00
|
|
|
# Obtain boot type from kernel arguments
|
|
|
|
BOOT_TYPE=`getBootType`
|
|
|
|
|
2018-10-12 10:39:06 -05:00
|
|
|
# Obtain our platform as we will mount directories with these names in each docker
|
|
|
|
PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`
|
2017-09-14 10:43:02 -05:00
|
|
|
|
2018-10-12 10:39:06 -05:00
|
|
|
{%- if docker_container_name == "database" %}
|
|
|
|
# Don't mount HWSKU in {{docker_container_name}} container.
|
|
|
|
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"]'`
|
|
|
|
{%- endif %}
|
2017-02-27 02:13:36 -06:00
|
|
|
|
2017-09-14 10:43:02 -05:00
|
|
|
DOCKERCHECK=`docker inspect --type container {{docker_container_name}} 2>/dev/null`
|
2017-01-29 13:33:33 -06:00
|
|
|
if [ "$?" -eq "0" ]; then
|
2017-09-14 10:43:02 -05:00
|
|
|
DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"`
|
|
|
|
if [ "$DOCKERMOUNT" == "$HWSKU" ]; then
|
|
|
|
echo "Starting existing {{docker_container_name}} container with HWSKU $HWSKU"
|
2018-11-22 17:13:35 -06:00
|
|
|
preStartAction
|
2017-09-14 10:43:02 -05:00
|
|
|
docker start {{docker_container_name}}
|
|
|
|
postStartAction
|
2018-11-02 09:20:07 -05:00
|
|
|
exit $?
|
2017-09-14 10:43:02 -05:00
|
|
|
fi
|
|
|
|
|
|
|
|
# docker created with a different HWSKU, remove and recreate
|
|
|
|
echo "Removing obsolete {{docker_container_name}} container with HWSKU $DOCKERMOUNT"
|
2018-05-25 22:04:08 -05:00
|
|
|
docker rm -f {{docker_container_name}}
|
2017-09-14 10:43:02 -05:00
|
|
|
fi
|
2017-03-23 14:18:52 -05:00
|
|
|
|
2017-09-14 10:43:02 -05:00
|
|
|
{%- if docker_container_name == "database" %}
|
2018-11-22 17:13:35 -06:00
|
|
|
echo "Creating new {{docker_container_name}} container"
|
2017-09-14 10:43:02 -05:00
|
|
|
{%- else %}
|
2018-11-22 17:13:35 -06:00
|
|
|
echo "Creating new {{docker_container_name}} container with HWSKU $HWSKU"
|
2017-09-14 10:43:02 -05:00
|
|
|
{%- endif %}
|
2018-11-22 17:13:35 -06:00
|
|
|
docker create {{docker_image_run_opt}} \
|
2017-05-05 19:44:36 -05:00
|
|
|
{%- if '--log-driver=json-file' in docker_image_run_opt or '--log-driver' not in docker_image_run_opt %}
|
2017-09-14 10:43:02 -05:00
|
|
|
--log-opt max-size=2M --log-opt max-file=5 \
|
2018-04-02 22:24:59 -05:00
|
|
|
{%- endif %}
|
|
|
|
{%- if docker_container_name == "syncd" and sonic_asic_platform == "mellanox" %}
|
|
|
|
-e SX_SNIFFER_ENABLE \
|
|
|
|
-e SX_SNIFFER_TARGET \
|
|
|
|
-e PRM_SNIFFER \
|
|
|
|
-e PRM_SNIFFER_FILE_PATH \
|
|
|
|
-v /var/log/mellanox/sniffer:/var/log/mellanox/sniffer:rw \
|
2017-05-05 19:44:36 -05:00
|
|
|
{%- endif %}
|
2017-09-14 10:43:02 -05:00
|
|
|
-v /var/run/redis:/var/run/redis:rw \
|
|
|
|
-v /usr/share/sonic/device/$PLATFORM:/usr/share/sonic/platform:ro \
|
2017-09-12 16:13:27 -05:00
|
|
|
{%- if docker_container_name != "database" %}
|
2017-09-14 10:43:02 -05:00
|
|
|
-v /usr/share/sonic/device/$PLATFORM/$HWSKU:/usr/share/sonic/hwsku:ro \
|
2017-09-12 16:13:27 -05:00
|
|
|
{%- endif %}
|
2018-01-17 01:20:13 -06:00
|
|
|
--tmpfs /tmp \
|
|
|
|
--tmpfs /var/tmp \
|
2018-07-24 23:46:55 -05:00
|
|
|
--name={{docker_container_name}} {{docker_image_name}}:latest || {
|
|
|
|
echo "Failed to docker run" >&1
|
|
|
|
exit 4
|
|
|
|
}
|
2017-09-14 10:43:02 -05:00
|
|
|
|
2018-11-22 17:13:35 -06:00
|
|
|
preStartAction
|
|
|
|
docker start {{docker_container_name}}
|
2017-09-14 10:43:02 -05:00
|
|
|
postStartAction
|
2017-01-29 13:33:33 -06:00
|
|
|
}
|
|
|
|
|
[oneimage]: Fix race condition in systemd container services (#421)
When Type=simple, systemd will consider the service activated immediately
after specified in ExecStart process is started. If there is downstream
service depending on the state prepared in ExecStart, there will be race condition.
For example, issue #390. In this case, database.service calls database.sh, which
calls docker run or docker start -a to start database container. However, systemd
considers database.service successfully started at the time database.sh begins,
not after docker run finishes. As database.service is consider started, bgp.service
can be started. The redis database, which bgp service depends on, might or might not
have been started at this time point.
To fix this issue (and still keeping the functionality to monitor docker status with
systemd), we split the ExecStart process into an ExecStartPre part and an ExecStart
part. docker run is splitted into docker run -d then docker attach , while docker start
-a is splitted into docker start and then docker attach. In this way, we make sure
the downstream services are blocked until container is successfully started.
2017-03-22 15:04:48 -05:00
|
|
|
attach() {
|
|
|
|
docker attach --no-stdin {{docker_container_name}}
|
|
|
|
}
|
|
|
|
|
2017-01-29 13:33:33 -06:00
|
|
|
stop() {
|
|
|
|
docker stop {{docker_container_name}}
|
|
|
|
}
|
|
|
|
|
|
|
|
case "$1" in
|
[oneimage]: Fix race condition in systemd container services (#421)
When Type=simple, systemd will consider the service activated immediately
after specified in ExecStart process is started. If there is downstream
service depending on the state prepared in ExecStart, there will be race condition.
For example, issue #390. In this case, database.service calls database.sh, which
calls docker run or docker start -a to start database container. However, systemd
considers database.service successfully started at the time database.sh begins,
not after docker run finishes. As database.service is consider started, bgp.service
can be started. The redis database, which bgp service depends on, might or might not
have been started at this time point.
To fix this issue (and still keeping the functionality to monitor docker status with
systemd), we split the ExecStart process into an ExecStartPre part and an ExecStart
part. docker run is splitted into docker run -d then docker attach , while docker start
-a is splitted into docker start and then docker attach. In this way, we make sure
the downstream services are blocked until container is successfully started.
2017-03-22 15:04:48 -05:00
|
|
|
start|stop|attach)
|
2017-01-29 13:33:33 -06:00
|
|
|
$1
|
|
|
|
;;
|
|
|
|
*)
|
[oneimage]: Fix race condition in systemd container services (#421)
When Type=simple, systemd will consider the service activated immediately
after specified in ExecStart process is started. If there is downstream
service depending on the state prepared in ExecStart, there will be race condition.
For example, issue #390. In this case, database.service calls database.sh, which
calls docker run or docker start -a to start database container. However, systemd
considers database.service successfully started at the time database.sh begins,
not after docker run finishes. As database.service is consider started, bgp.service
can be started. The redis database, which bgp service depends on, might or might not
have been started at this time point.
To fix this issue (and still keeping the functionality to monitor docker status with
systemd), we split the ExecStart process into an ExecStartPre part and an ExecStart
part. docker run is splitted into docker run -d then docker attach , while docker start
-a is splitted into docker start and then docker attach. In this way, we make sure
the downstream services are blocked until container is successfully started.
2017-03-22 15:04:48 -05:00
|
|
|
echo "Usage: $0 {start|stop|attach}"
|
2017-01-29 13:33:33 -06:00
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|