#!/bin/sh UUS_EXEC="/usr/bin/ubios-udapi-server" UUS_PIDFILE="/var/run/ubios-udapi-server.pid" UUS_WD_PIDFILE="/var/run/ubios-udapi-server-watchdog.pid" UUS_HEARTBEAT_FILE="/var/run/ubios-udapi-server.heartbeat" UUS_LOCK_FILES="/var/run/ubios-udapi-server.*.lock" UUS_ARGS="" INIT_LOG_ID="ubios-udapi-server-init" # Timeout parameters in seconds UUS_STOP_WAIT_TIME=30 UUS_KILL_WAIT_TIME=5 UUS_HEARTBEAT_WARNING_TIME=30 UUS_HEARTBEAT_RESTART_TIME=60 # Process control parameters UUS_OOM_THRESHOLD=-800 UUS_MEM_HIGH=50M UUS_MEM_MAX=80M UUS_MEM_SWAP_MAX=120M . /usr/bin/set_process_control_funcs [ -r /etc/default/ubios-udapi-server ] && . /etc/default/ubios-udapi-server # @brief Logs error. # # @param 1 - The error message. function log_error() { logger -s -t ${INIT_LOG_ID} -p 3 "${@}" } # @brief Logs warning. # # @param 1 - The warning message. function log_warn() { logger -s -t ${INIT_LOG_ID} -p 2 "${@}" } # @brief Logs info message. # # @param 1 - The info message. function log_info() { logger -t ${INIT_LOG_ID} "${@}" } # @brief Gets system uptime. function get_uptime() { local curr_time=0 read -d "." curr_time 2>/dev/null < /proc/uptime echo ${curr_time} } # @brief Gets uus heartbeat value. function get_heartbeat_value() { local hb_time=0 read hb_time 2>/dev/null < ${UUS_HEARTBEAT_FILE} hb_time=$(expr ${hb_time} / 1000) echo ${hb_time} } # @brief Gets uus lock reason. function get_lock_reason() { local lock_file=$(ls -tc ${UUS_LOCK_FILES} 2> /dev/null | head -1) local lock_reason= read lock_reason 2>/dev/null < ${lock_file} if [ -z "${lock_reason}" ]; then lock_reason="unknown reason" fi echo ${lock_reason} } # @brief Cleans old service files. function clean_artifacts() { rm -f "${UUS_PIDFILE}" "${UUS_HEARTBEAT_FILE}" for lock_file in $(ls -tc ${UUS_LOCK_FILES} 2> /dev/null); do mv ${lock_file} ${lock_file}.old done } function prepare() { # Getting the SSH Server resources ready # If /etc/dropbear is a symlink to /var/run/dropbear, and # - the filesystem is RO (i.e. we can not rm the symlink), # create the directory pointed to by the symlink. # - the filesystem is RW (i.e. we can rm the symlink), # replace the symlink with an actual directory if [ -L /etc/dropbear \ -a "$(readlink /etc/dropbear)" = "/var/run/dropbear" ] then if rm -f /etc/dropbear >/dev/null 2>&1; then mkdir -p /etc/dropbear else mkdir -p "$(readlink /etc/dropbear)" fi fi if which ubnt-ssh-keys-install >/dev/null 2>&1; then ubnt-ssh-keys-install fi # PPP requires ppp_generic (other modules autoload) # QoS requires ifb, sch_htb autoloads, but we need it now to enable rate estimator for mod in ppp_generic sch_htb ifb; do modprobe -q $mod || echo "$0: modprobe $mod failed" done # Needed for HTB rate counters echo 1 > /sys/module/sch_htb/parameters/htb_rate_est } # @brief Starts the service. function start_uus() { # Cleanup old files clean_artifacts # Start the service start-stop-daemon -S --quiet --background --make-pidfile --pidfile $UUS_PIDFILE --exec $UUS_EXEC -- $UUS_ARGS local rc=$? # Configure process control local pid="$(cat "${UUS_PIDFILE}")" #set_process_control_v2 "uus" "${pid}" "${UUS_MEM_HIGH}" "${UUS_MEM_MAX}" "${UUS_MEM_SWAP_MAX}" "${UUS_OOM_THRESHOLD}" return ${rc} } # @brief Stops the service. function stop_uus() { # Stop the service start-stop-daemon -K --quiet --pidfile $UUS_PIDFILE --exec $UUS_EXEC local rc=$? return ${rc} } # @brief Kills the service forcibly. function kill_uus() { kill -9 $(cat ${UUS_PIDFILE}) local rc=$? return ${rc} } # @brief Tests if the service is running. # # @return 1 if the service is not running. function test_uus() { # Test if the service is running start-stop-daemon -K --quiet --pidfile $UUS_PIDFILE --exec $UUS_EXEC --test local rc=$? return ${rc} } # @brief Waits for the service to be stopped. # # @param 1 - Time to wait for the service to stop. # @param 2 - Put 1 for printing a progress to stdout. # @return 1 if the service is not running. function wait_uus() { local wait_time=$(expr ${1} + $(get_uptime)) local verbose=${2} local stopped=0 while [ ${wait_time} -gt $(get_uptime) ]; do sleep 0.3 test_uus stopped=$? [ ${stopped} -eq 1 ] && break [ ${verbose} -eq 1 ] && echo -n "." done return ${stopped} } function init_wd() { # Init udapi-server's watchdog local heartbeat_value=-1 local heartbeat_value_timestamp=-1 while : ; do sleep 5 # WD by pidfile if [ ! -f /proc/$(cat "${UUS_PIDFILE}")/exe ]; then log_error "Watchdog: ubios-udapi-server is not running! Starting it again..." start_uus heartbeat_value=-1 heartbeat_value_timestamp=-1 continue fi # HB verify and update local heartbeat_value_new=$(get_heartbeat_value) if [ ${heartbeat_value} -ne ${heartbeat_value_new} ]; then heartbeat_value=${heartbeat_value_new} heartbeat_value_timestamp=$(get_uptime) continue fi # WD by heartbeat local heartbeat_delay=$(expr $(get_uptime) - ${heartbeat_value_timestamp}) if [ ${heartbeat_delay} -ge ${UUS_HEARTBEAT_RESTART_TIME} ]; then local reason="$(get_lock_reason)" log_error "Watchdog: ubios-udapi-server is not responsive for ${heartbeat_delay} seconds due to ${reason}! Stopping it..." stop_uus wait_uus ${UUS_STOP_WAIT_TIME} 0 if [ $? -ne 1 ]; then log_error "Watchdog: ubios-udapi-server is failed to stop! Killing it..." kill_uus wait_uus ${UUS_KILL_WAIT_TIME} 0 [ $? -ne 1 ] && log_error "Watchdog: ubios-udapi-server is failed to get killed!" fi heartbeat_value=-1 heartbeat_value_timestamp=-1 continue fi # HB warning if [ ${heartbeat_delay} -ge ${UUS_HEARTBEAT_WARNING_TIME} ]; then local reason="$(get_lock_reason)" local heartbeat_restart_notice=$(expr ${UUS_HEARTBEAT_RESTART_TIME} - ${heartbeat_delay}) log_warn "Watchdog: ubios-udapi-server is not responsive for ${heartbeat_delay} seconds due to ${reason}! Restarting it in ${heartbeat_restart_notice} seconds." continue fi done & echo $! > ${UUS_WD_PIDFILE} } function start() { prepare printf "Starting ubios-udapi-server: " start_uus if [ $? -eq 0 ]; then echo "OK" log_info "ubios-udapi-server is starting in the background..." else echo "FAIL" log_error "Failed to start ubios-udapi-server" fi init_wd echo "Starting ubios-udapi-server watchdog: OK" log_info "ubios-udapi-server watchdog started" } function stop() { printf "Stopping ubios-udapi-server watchdog: " kill "$(cat "${UUS_WD_PIDFILE}")" if [ $? -eq 0 ]; then echo "OK" log_info "ubios-udapi-server watchdog stopped" else echo "FAIL" log_error "Failed to stop ubios-udapi-server watchdog" fi printf "Stopping ubios-udapi-server: " stop_uus wait_uus ${UUS_STOP_WAIT_TIME} 1 local stopped=$? if [ ${stopped} -ne 1 ]; then echo "FAIL" printf "Killing ubios-udapi-server: " kill_uus wait_uus ${UUS_KILL_WAIT_TIME} 1 stopped=$? fi if [ ${stopped} -eq 1 ]; then echo "OK" log_info "ubios-udapi-server stopped" else echo "FAIL" log_error "Failed to stop ubios-udapi-server" fi } case "$1" in start) start ;; stop) stop ;; restart|reload) stop start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit $?