mirror of
https://github.com/openwrt/packages.git
synced 2026-10-14 03:27:03 +04:00
Include more inline comments to document the nut-server initscript and usb hotplug. Also trim an extraneous space in a comment. Signed-off-by: Daniel F. Dickinson <dfdpublic@wildtechgarden.ca>
770 lines
21 KiB
Bash
770 lines
21 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# Copyright © 2012-2026 OpenWrt.org
|
|
#
|
|
# Startup script for NUT (UPS) server
|
|
#
|
|
# This is free software, licensed under the GNU General Public License v2.
|
|
# See /LICENSE for more information.
|
|
#
|
|
|
|
# In recent (relevant) versions of shellcheck busybox is a valid shell type
|
|
# shellcheck shell=busybox
|
|
|
|
# shellcheck disable=SC2034
|
|
START=70
|
|
STOP=30
|
|
|
|
# We use the script functions and variables definitions from
|
|
# /etc/rc.common that are added by USE_PROCD except with a modified
|
|
# start and rc_procd. We cannot simply override USE_PROCD's
|
|
# implementation of start and rc_procd as rc.common sources this
|
|
# initscript before the definitions are applied by USE_PROCD
|
|
#
|
|
# The modified rc_procd uses "set" for procd_close_service, which
|
|
# registers the service with procd, if the service for this
|
|
# initscript (nut-server) is not registered with procd (active) at all,
|
|
# otherwise it uses "add" which adds an instance to the registered
|
|
# (active) service.
|
|
#
|
|
# USE_PROCD=1
|
|
|
|
# IPKG_INSTROOT is intentionally only set when building an image and
|
|
# is intentionally empty on a live OpenWrt device
|
|
|
|
# The shellcheck source directives are used during development by external
|
|
# tools to find the source files on the development system. They do not
|
|
# affect runtime behaviour.
|
|
|
|
# Also the filenames in the shellcheck source directives may differ from the
|
|
# production names that are sourced on live OpenWrt devices.
|
|
|
|
# shellcheck source=net/nut/files/functions.sh.functions
|
|
. "${IPKG_INSTROOT}"/lib/functions.sh || {
|
|
# Before our sourcing error logging definitions are sourced
|
|
logger -t "nut-server[$$]" "FATAL: Unable to source 'functions.sh' in 'nut-server'"
|
|
exit 1
|
|
}
|
|
|
|
# 'shellcheck' complains about nut-common.sh due to a case pattern it does not understand, even
|
|
# though it is correctly POSIX compliant
|
|
# shellcheck disable=SC1094
|
|
# shellcheck source=net/nut/files/nut-common.sh.functions
|
|
. "${IPKG_INSTROOT}"/lib/functions/nut/nut-common.sh || {
|
|
# Before our sourcing error logging definitions are sourced
|
|
logger -t "nut-server[$$]" "FATAL: Unable to source 'nut-common.sh' in 'nut-server'"
|
|
exit 1
|
|
}
|
|
|
|
# shellcheck source=/dev/null
|
|
. "${IPKG_INSTROOT}"/lib/functions/network.sh || {
|
|
log_source_error "network.sh" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
# shellcheck source=net/nut/files/nut-server-config.sh.functions
|
|
. "${IPKG_INSTROOT}"/lib/functions/nut/nut-server-config.sh || {
|
|
log_source_error "nut-server-config.sh" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
# shellcheck source=/dev/null
|
|
. "${IPKG_INSTROOT}"/usr/share/libubox/jshn.sh || {
|
|
log_source_error "jshn.sh" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
# shellcheck source=net/nut/files/nut-service.sh.functions
|
|
. "${IPKG_INSTROOT}"/lib/functions/nut/nut-service.sh || {
|
|
log_source_error "nut-service.sh" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
# shellcheck source=net/nut/files/nut-server-service.sh.functions
|
|
. "${IPKG_INSTROOT}"/lib/functions/nut/nut-server-service.sh || {
|
|
log_source_error "nut-server-service.sh" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
# shellcheck source=/dev/null
|
|
. "${IPKG_INSTROOT}"/lib/functions/procd.sh || {
|
|
log_source_error "procd.sh" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
restore_umask_on_exit
|
|
|
|
extra_command "running" "Check if service is running"
|
|
extra_command "status" "Service status"
|
|
extra_command "trace" "Start with syscall trace"
|
|
extra_command "info" "Dump procd service info"
|
|
|
|
basescript=$(readlink "$initscript")
|
|
|
|
has_running_driver() {
|
|
local instances instance
|
|
|
|
# have_driver_instance and have_upsd_instance are 'pseudo-globals' -
|
|
# they are local to the _caller_ and visible/modifiable in this
|
|
# function in order to get the value back to the caller.
|
|
|
|
instances="$(list_running_instances "nut-server")"
|
|
[ -n "$instances" ] || return 0
|
|
set -f
|
|
for instance in $instances; do
|
|
if [ "$instance" = "upsd" ]; then
|
|
have_upsd_instance="true"
|
|
continue
|
|
fi
|
|
have_driver_instance="true"
|
|
break
|
|
done
|
|
set +f
|
|
}
|
|
|
|
start_server_service() {
|
|
procd_open_instance upsd
|
|
procd_set_param respawn
|
|
procd_set_param stderr 1
|
|
procd_set_param stdout 1
|
|
procd_set_param env NUT_DEBUG_SYSLOG="stderr"
|
|
procd_set_param env NUT_QUIET_INIT_UPSNOTIFY=true
|
|
procd_set_param env NUT_STATEPATH="$STATEPATH"
|
|
procd_set_param command /usr/sbin/upsd
|
|
procd_append_param command -FF
|
|
procd_append_param command -u "$RUNAS"
|
|
procd_close_instance
|
|
}
|
|
|
|
# Start upsd instance
|
|
start_server_instance() {
|
|
if [ -f "$NUT_KILLPOWER" ]; then
|
|
return 1
|
|
fi
|
|
|
|
local have_driver_instance="false"
|
|
local have_upsd_instance="false"
|
|
has_running_driver
|
|
|
|
# upsd will crash if started with no available UPS, so only start if
|
|
# we have one, and we do not already have a upsd instance
|
|
if [ "$have_driver_instance" = "true" ] && [ "$have_upsd_instance" = "false" ]; then
|
|
rc_procd start_server_service || return 1
|
|
fi
|
|
}
|
|
|
|
start_ups_service() {
|
|
procd_open_instance "$ups"
|
|
procd_set_param respawn
|
|
procd_set_param stderr 1
|
|
procd_set_param stdout 1
|
|
procd_set_param env NUT_DEBUG_SYSLOG="stderr"
|
|
procd_set_param env NUT_QUIET_INIT_UPSNOTIFY=true
|
|
procd_set_param env NUT_STATEPATH="${STATEPATH}"
|
|
procd_set_param command "/usr/libexec/nut/${driver}"
|
|
procd_append_param command -FF -a "$ups"
|
|
procd_append_param command -u "$RUNAS"
|
|
procd_close_instance
|
|
}
|
|
|
|
# Start a ups driver instance
|
|
start_ups_driver() {
|
|
local ups="$1"
|
|
local requested="$2"
|
|
local driver=""
|
|
|
|
# If wanting a specific instance, only start that instance; this is a normal
|
|
# operating event, so do not log and do not error
|
|
if [ -n "$requested" ] && [ "$requested" != "$ups" ]; then
|
|
return 0
|
|
fi
|
|
|
|
# For non-USB devices this is effectively a no-op
|
|
# For USB devices, if the USB productid and USB vendorid of the configured
|
|
# driver instance (UPS) match a USB device in sysfs, set the permissions
|
|
# on the USB device node in /dev/bus/usb/... to allow NUT to access and
|
|
# control the device.
|
|
ensure_usb_ups_access "$ups" || {
|
|
usb_ups_access_error="true"
|
|
log_error "Error enabling USB access for UPS '$ups'" "nut-server" "nut-server"
|
|
return 1
|
|
}
|
|
|
|
config_get driver "$ups" driver
|
|
|
|
[ -n "$driver" ] || {
|
|
log_error "Missing driver when starting UPS '$ups'" "nut-server" "nut-server"
|
|
return 1
|
|
}
|
|
|
|
rc_procd start_ups_service "$@" || {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
have_upsd_section() {
|
|
have_upsd_section="true"
|
|
}
|
|
|
|
common_preconditions() {
|
|
local ret
|
|
|
|
# No config, or error loading config is fatal
|
|
config_load nut_server || {
|
|
log_config_load_error "nut_server" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
# Only find statepath and runas once per service start or reload
|
|
if have_section_named "upsd" "upsd"; then
|
|
STATEPATH="$(find_statepath "upsd" "nut_server")" || {
|
|
log_error_exit "Failed to determine STATEPATH" "nut-server" "nut-server"
|
|
}
|
|
RUNAS="$(find_runas "upsd" "nut_server")" || {
|
|
log_error_exit "Failed to determine RUNAS" "nut-server" "nut-server"
|
|
}
|
|
else
|
|
# If there is no 'upsd' section in the nut_server config file, use
|
|
# default settings
|
|
STATEPATH=/var/run/nut
|
|
RUNAS=nut
|
|
fi
|
|
|
|
# NUT_KILLPOWER is an external sentinel that indicates a forced shutdown
|
|
if [ -f "$NUT_KILLPOWER" ]; then
|
|
return 1
|
|
fi
|
|
|
|
build_config
|
|
ret=$?
|
|
|
|
return $ret
|
|
}
|
|
|
|
stop_no_longer_configured_instances() {
|
|
local have_driver_instance=false
|
|
local have_upsd_instance=false
|
|
local had_running_instance="false"
|
|
local instance instances
|
|
|
|
# Stop any driver instances which are no longer configured
|
|
# This can occur when the configuration is changed and the service
|
|
# is restarted or reloaded, as this script is not notified of what has
|
|
# changed if the configuration changes; the script will simply
|
|
# generate a new configuration in that event.
|
|
# We can only reliably do this for instances managed by procd
|
|
instances="$(list_running_instances "nut-server")"
|
|
[ -n "$instances" ] || return 0
|
|
set -f
|
|
# Check that all instances are associated with a configured driver or
|
|
# the upsd daemon
|
|
for instance in $instances; do
|
|
# upsd should be stopped last, if it is stopped at all
|
|
if [ "$instance" = "upsd" ]; then
|
|
continue
|
|
fi
|
|
# Set to true if any instance was running, whether stopped here, or left
|
|
# running. have_driver_instance (set in has_running_driver) lets us know
|
|
# if any driver is still running.
|
|
had_running_instance="true"
|
|
config_get driver "$instance" driver
|
|
# Only stop not configured but running instances
|
|
if [ -z "$driver" ] && [ -n "$instance" ] && procd_running "nut-server" "$instance" >/dev/null 2>&1; then
|
|
log_msg "Stopping no longer configured ups '$instance'" "nut-server" "nut-server" notice
|
|
procd_kill "nut-server" "$instance"
|
|
fi
|
|
done
|
|
set +f
|
|
|
|
# Need to stop drivers before stopping upsd
|
|
# The has_running_driver check is required in case some instances failed to
|
|
# stop in the first loop (so we cannot just track instances in the above loop).
|
|
# In addition, it is possible for hotplug triggered drivers starting to start
|
|
# instances between the stop above, and this loop.
|
|
has_running_driver
|
|
|
|
# If we have no UPS instances we must stop upsd or it will crash
|
|
# The "nut-server" service remains active and will 'see' configuration
|
|
# changes and execute reload_service when they are detected, but avoid
|
|
# signalling upsd if it is not running ('had_running_instance' != "true")
|
|
if [ "$have_upsd_instance" = "true" ] && [ "$have_driver_instance" = "false" ] && [ "$had_running_instance" = "true" ]; then
|
|
log_msg "Stopping upsd because no driver instances configured" "nut-server" "nut-server" "notice"
|
|
signal_instance "upsd" "upsd" "stop" "TERM" "${STATEPATH}/upsd.pid" "" "nut-server" "procd_kill" "nut-server" "upsd"
|
|
elif [ "$have_upsd_instance" = "false" ] && [ "$have_driver_instance" = "true" ]; then
|
|
start_server_instance
|
|
fi
|
|
}
|
|
|
|
stop_all_instances() {
|
|
local instance instances
|
|
|
|
instances="$(list_running_instances "nut-server")"
|
|
[ -n "$instances" ] || return 0
|
|
set -f
|
|
for instance in $instances; do
|
|
# stop upsd last
|
|
if [ "$instance" = "upsd" ]; then
|
|
continue
|
|
fi
|
|
config_get driver "$instance" driver
|
|
[ -n "$driver" ] || continue
|
|
|
|
signal_instance "$instance" "/usr/libexec/nut/${driver}" "stop" "TERM" \
|
|
"${STATEPATH}/${driver}-${instance}.pid" "" "nut-server" "procd_kill" "nut-server" "$instance"
|
|
done
|
|
set +f
|
|
# stop_server_instance
|
|
signal_instance "upsd" "upsd" "stop" "TERM" "${STATEPATH}/upsd.pid" "" "nut-server" "procd_kill" "nut-server" "upsd"
|
|
return 0
|
|
}
|
|
|
|
service_preconditions() {
|
|
local action="$1"
|
|
local should_stop_srv=false
|
|
local should_start_srv=true
|
|
local ret=0
|
|
|
|
case "$action" in
|
|
start)
|
|
common_preconditions
|
|
ret=$?
|
|
|
|
case $ret in
|
|
0)
|
|
check_interface_up "upsd" || should_start_srv=false
|
|
;;
|
|
*)
|
|
should_start_srv=false
|
|
;;
|
|
esac
|
|
;;
|
|
reload)
|
|
common_preconditions
|
|
ret=$?
|
|
|
|
case $ret in
|
|
0 | 2)
|
|
check_interface_up "upsd" || should_stop_srv=true
|
|
;;
|
|
*)
|
|
should_stop_srv=true
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
log_error "Unknown action '$action' in service_preconditions" "nut-server" "nut-server"
|
|
ret=1
|
|
;;
|
|
esac
|
|
|
|
# If server not configured or no interfaces are up, diagnostic should already have been logged.
|
|
# Do not spam log more, but remove config and exit.
|
|
if [ "$should_start_srv" = "false" ]; then
|
|
remove_var_config
|
|
return 1
|
|
fi
|
|
|
|
# Stop all instances, remove config, and exit with error, if should_stop_srv is true
|
|
if [ "$should_stop_srv" = "true" ]; then
|
|
stop_all_instances || true
|
|
remove_var_config
|
|
return $ret
|
|
fi
|
|
|
|
# NUT_KILLPOWER is an external sentinel that may be set between now and
|
|
# the previous check
|
|
if [ -f "$NUT_KILLPOWER" ]; then
|
|
return 1
|
|
fi
|
|
|
|
# If we're here we should have good new config; activate it
|
|
mv -f "$USERS_C.new" "$USERS_C" || return 1
|
|
mv -f "$UPS_C.new" "$UPS_C" || return 1
|
|
mv -f "$UPSD_C.new" "$UPSD_C" || return 1
|
|
return 0
|
|
}
|
|
|
|
remove_var_config() {
|
|
for rm_file in "$USERS_C" "$UPS_C" "$UPSD_C" \
|
|
"$USERS_C.new" "$UPS_C.new" "$UPSD_C.new"; do
|
|
rm -f "$rm_file"
|
|
done
|
|
}
|
|
|
|
# Stop NUT drivers and upsd (NUT server)
|
|
# We do not error exit (only log issues) because we do not want to prevent
|
|
# processing of further drivers.
|
|
stop_ups_driver() {
|
|
local ups="$1" # The ups (driver instance)
|
|
local requested="$2"
|
|
local driver
|
|
|
|
# If wanting a specific instance, only stop it
|
|
if [ -n "$requested" ] && [ "$requested" != "$ups" ]; then
|
|
return 0
|
|
fi
|
|
|
|
config_get driver "$ups" driver
|
|
|
|
if [ -z "$driver" ]; then
|
|
log_error "No driver specified for UPS '$ups'. Attempting procd_kill." "nut-server" "nut-server"
|
|
procd_kill "nut-server" "$ups" || log_error "No driver specified for UPS '$ups' and procd_kill fallback failed" "nut-server" "nut-server"
|
|
return 0
|
|
fi
|
|
|
|
# If there is a running driver instance for this UPS
|
|
if procd_running "nut-server" "$ups" >/dev/null 2>&1; then
|
|
signal_instance "$ups" "/usr/libexec/nut/${driver}" exit "TERM" "${STATEPATH}/${driver}-${ups}.pid" "${ups}" "nut-server"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Reload NUT drivers and upsd (NUT server)
|
|
# We do not error exit (only log issues) because we do not want to prevent
|
|
# processing of further drivers.
|
|
reload_ups_driver() {
|
|
local ups="$1"
|
|
local requested="$2"
|
|
local driver
|
|
|
|
# If wanting a specific instance, only reload that instance
|
|
if [ -n "$requested" ] && [ "$requested" != "$ups" ]; then
|
|
return 0
|
|
fi
|
|
|
|
if [ -f "$NUT_KILLPOWER" ]; then
|
|
stop_ups_driver "$ups"
|
|
return 0
|
|
fi
|
|
|
|
config_get driver "$ups" driver
|
|
|
|
# Try to reload, otherwise exit politely
|
|
if procd_running "nut-server" "$ups"; then
|
|
signal_instance "$ups" "/usr/libexec/nut/${driver}" "reload-or-exit" "HUP" "${STATEPATH}/${driver}-${ups}.pid" "${ups}" "nut-server"
|
|
# Fall through to start driver, if it exited due to 'reload-or-exit'
|
|
# finding a configuration condition which requires a stop and start
|
|
# for the configuration to be applied.
|
|
fi
|
|
|
|
# If the driver instance (UPS) was terminated, or stopped 'naturally',
|
|
# start it up again
|
|
if ! procd_running "nut-server" "$ups" >/dev/null 2>&1; then
|
|
start_ups_driver "$ups" "$ups"
|
|
fi
|
|
|
|
# If the server instance (upsd) was terminated, or stopped 'naturally',
|
|
# start it up again
|
|
start_server_instance
|
|
return 0
|
|
}
|
|
|
|
stop_service_if_no_instances() {
|
|
if service_active_no_instances "nut-server"; then
|
|
log_msg "nut-server active with no instances" nut-server "nut-server" notice
|
|
# If "nut-server" is active with no instances
|
|
# We don't care about the exit code of procd_kill, and logging its
|
|
# stderr can aid debugging.
|
|
procd_kill "nut-server" 2>&1 | logger -t "nut-server"
|
|
fi
|
|
}
|
|
|
|
# Stop or reload active instances
|
|
manage_instances() {
|
|
local action="$1"
|
|
|
|
case "$action" in
|
|
start)
|
|
config_foreach start_ups_driver driver
|
|
start_server_instance
|
|
;;
|
|
reload)
|
|
if service_active_no_instances "nut-server"; then
|
|
log_msg "nut-server active with no instances. Reloading." "nut-server" "nut-server" "info"
|
|
fi
|
|
|
|
config_foreach reload_ups_driver driver
|
|
stop_no_longer_configured_instances
|
|
;;
|
|
stop)
|
|
stop_all_instances
|
|
stop_service_if_no_instances
|
|
remove_var_config
|
|
;;
|
|
stop-instances)
|
|
stop_all_instances
|
|
remove_var_config
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Manage NUT drivers and upsd (NUT server) services
|
|
manage_service() {
|
|
local action="$1"
|
|
# If we have no second parameter, we use the "") case and affect all instances
|
|
shift || true
|
|
# We only consume a single additional parameter (if not acting on all
|
|
# instances, we act only on one instance).
|
|
local instance="$1"
|
|
local ret=0
|
|
local service_active
|
|
|
|
case "$action" in
|
|
start)
|
|
service_preconditions "$action"
|
|
ret=$?
|
|
case "$instance" in
|
|
"")
|
|
if [ "$ret" = "0" ]; then
|
|
manage_instances start
|
|
else
|
|
return 1
|
|
fi
|
|
;;
|
|
# We only start one service (upsd or one driver) from a given invocation
|
|
upsd)
|
|
if [ "$ret" = "0" ]; then
|
|
start_server_instance
|
|
fi
|
|
;;
|
|
# We only start one service (upsd or one driver) from a given invocation
|
|
*)
|
|
if [ "$ret" = "0" ]; then
|
|
config_foreach start_ups_driver driver "$instance"
|
|
start_server_instance
|
|
fi
|
|
;;
|
|
esac
|
|
# Ensure drivers no longer present in config, but which are still running
|
|
# get stopped. This is required because we are not notified of what was
|
|
# removed when configuration is removed.
|
|
stop_no_longer_configured_instances
|
|
return $ret
|
|
;;
|
|
reload)
|
|
service_preconditions "$action"
|
|
ret=$?
|
|
|
|
if [ "$ret" != "1" ]; then
|
|
manage_instances reload
|
|
fi
|
|
|
|
if [ "$ret" = "1" ]; then
|
|
return 1
|
|
fi
|
|
;;
|
|
stop)
|
|
case "$instance" in
|
|
"")
|
|
manage_instances stop
|
|
ret=$?
|
|
|
|
service_active_no_instances "$(basename "${basescript:-$initscript}")"
|
|
service_active=$?
|
|
|
|
if [ "$service_active" -eq 1 ]; then
|
|
# Prevent NUT hotplug events when service is not running
|
|
rm -f "$NUT_HOTPLUG_BOOT_COMPLETE_PATH"
|
|
elif [ "$service_active" -eq 3 ]; then
|
|
return 1
|
|
fi
|
|
return $ret
|
|
;;
|
|
upsd)
|
|
if procd_running "nut-server" upsd >/dev/null 2>&1; then
|
|
signal_instance "upsd" "upsd" "stop" "TERM" "${STATEPATH}/upsd.pid" "" "nut-server" "procd_kill" "nut-server" "upsd"
|
|
fi
|
|
;;
|
|
*)
|
|
# We only handle the first parameter, so do not pass in all parameters
|
|
config_foreach stop_ups_driver driver "$instance"
|
|
;;
|
|
esac
|
|
;;
|
|
stop-instances)
|
|
case "$instance" in
|
|
"")
|
|
manage_instances stop-instances
|
|
;;
|
|
upsd)
|
|
if procd_running "nut-server" upsd >/dev/null 2>&1; then
|
|
signal_instance "upsd" "upsd" "stop" "TERM" "${STATEPATH}/upsd.pid" "" "nut-server" "procd_kill" "nut-server" "upsd"
|
|
fi
|
|
;;
|
|
*)
|
|
# We only handle the first parameter, so do not pass in all parameters
|
|
config_foreach stop_ups_driver driver "$instance"
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
}
|
|
|
|
allow_hotplug() {
|
|
local ret="$1"
|
|
|
|
[ "$ret" -eq 0 ] || return "$ret"
|
|
|
|
# Allow hotplug events to (re)start drivers/upsd only if starting
|
|
# nut-server service was successful
|
|
touch "$NUT_HOTPLUG_BOOT_COMPLETE_PATH"
|
|
|
|
# Ensure drivers/upsd started once hotplug has been allowed
|
|
local usb_ups_access_error="false"
|
|
config_foreach start_ups_driver driver
|
|
if [ "$usb_ups_access_error" = "false" ]; then
|
|
start_server_instance
|
|
ret=$?
|
|
else
|
|
ret=1
|
|
fi
|
|
|
|
# Re-disable hotplug if starting drivers and/or upsd failed after
|
|
# enabling hotplug.
|
|
if [ "$ret" -ne 0 ]; then
|
|
rm -f "$NUT_HOTPLUG_BOOT_COMPLETE_PATH"
|
|
fi
|
|
|
|
return "$ret"
|
|
}
|
|
|
|
# Start NUT drivers and upsd (NUT server)
|
|
start_service() {
|
|
local ret
|
|
manage_service start "$@"
|
|
ret=$?
|
|
|
|
# Only change allowing hotplug events for the
|
|
# start all instances case
|
|
if [ -z "$1" ]; then
|
|
allow_hotplug "$ret"
|
|
fi
|
|
}
|
|
|
|
# Reload NUT drivers and upsd (NUT server)
|
|
reload_service() {
|
|
local ret
|
|
|
|
manage_service reload "$@"
|
|
ret=$?
|
|
|
|
# Only change allowing hotplug events for the
|
|
# reload all instances case
|
|
if [ -z "$1" ]; then
|
|
# Allow hotplug events to (re)start drivers/upsd when reloading
|
|
# (successfully) after a failed start
|
|
allow_hotplug "$ret"
|
|
fi
|
|
}
|
|
|
|
# Stop NUT drivers and upsd (NUT server)
|
|
stop_service() {
|
|
manage_service stop "$@"
|
|
}
|
|
|
|
service_triggers() {
|
|
# No config, or error loading config is fatal
|
|
config_load nut_server || {
|
|
log_config_load_error "nut_server" "nut-server" "nut-server"
|
|
exit 1
|
|
}
|
|
|
|
config_get interface_reload_delay upsd interface_reload_delay $DEFAULT_PROCD_INTERFACE_RELOAD_DELAY
|
|
if ! check_unsigned_int "$interface_reload_delay" || [ -z "$interface_reload_delay" ]; then
|
|
log_msg "interface_reload_delay must be an unsigned integer" nut-server nut-server warn
|
|
interface_reload_delay="$DEFAULT_PROCD_INTERFACE_RELOAD_DELAY"
|
|
fi
|
|
|
|
add_interface_triggers "upsd" "$interface_reload_delay" "nut-server" "upsd" || {
|
|
log_error "Failed to add interface triggers" nut-server nut-server
|
|
}
|
|
procd_add_reload_trigger "nut_server"
|
|
}
|
|
|
|
rc_procd() {
|
|
local method service_active
|
|
|
|
service_active_no_instances "$(basename "${basescript:-$initscript}")"
|
|
service_active=$?
|
|
|
|
# Always use set if nut-server service is not active, even if this
|
|
# function is executed from reload or restart. In the default
|
|
# implementation from USE_PROCD=1, rc_procd is only called from
|
|
# start, so set is only used on a start action. In addition, the
|
|
# default rc_procd only uses add when called with a second parameter
|
|
if [ "$service_active" -eq 1 ]; then
|
|
log_msg "$(basename "${basescript:-$initscript}") was not active, so start it" "nut-server" "nut-server" "debug"
|
|
method="set"
|
|
elif [ "$service_active" -eq 3 ]; then
|
|
# log error message was already issued in service_active_no_instances
|
|
return 1
|
|
elif [ "$service_active" -eq 0 ] || [ "$service_active" -eq 2 ]; then
|
|
method="add"
|
|
else
|
|
log_error "Unexpected return value from 'service_active_no_instances'" "nut-server" "nut-server"
|
|
return 1
|
|
fi
|
|
procd_open_service "$(basename "${basescript:-$initscript}")" "$initscript"
|
|
"$@"
|
|
procd_close_service "$method"
|
|
|
|
return 0
|
|
}
|
|
|
|
# Define start in a way that avoids nesting rc_procd
|
|
start() {
|
|
# Ensure start actions occur one at a time
|
|
procd_lock
|
|
|
|
# Ensure service is started even if no instances are started
|
|
if rc_procd :; then
|
|
start_service "$@"
|
|
fi
|
|
}
|
|
|
|
boot() {
|
|
start
|
|
}
|
|
|
|
trace() {
|
|
TRACE_SYSCALLS=1
|
|
start "$@"
|
|
}
|
|
|
|
info() {
|
|
json_init
|
|
json_add_string name "$(basename "${basescript:-$initscript}")"
|
|
json_add_boolean verbose "1"
|
|
_procd_ubus_call list
|
|
}
|
|
|
|
stop() {
|
|
procd_lock
|
|
stop_service "$@"
|
|
procd_kill "$(basename "${basescript:-$initscript}")" "$1"
|
|
if eval "type service_stopped" 2>/dev/null >/dev/null; then
|
|
service_stopped
|
|
fi
|
|
}
|
|
|
|
reload() {
|
|
if eval "type reload_service" 2>/dev/null >/dev/null; then
|
|
procd_lock
|
|
reload_service "$@"
|
|
else
|
|
start
|
|
fi
|
|
}
|
|
|
|
running() {
|
|
service_running "$@"
|
|
}
|
|
|
|
status() {
|
|
if eval "type status_service" 2>/dev/null >/dev/null; then
|
|
status_service "$@"
|
|
else
|
|
_procd_status "$(basename "${basescript:-$initscript}")" "$1"
|
|
fi
|
|
}
|