From 020dfd4541760a4e3060ceb2dd337b502a80caf8 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Mon, 26 Aug 2019 23:18:05 -0400 Subject: [PATCH 01/11] nut: Remove unecessary libwrap dependency CONFIG_ARGS has --without-wrap so libwrap as a dependency is extraneous as it is not actually used. Signed-off-by: Daniel F. Dickinson --- net/nut/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/nut/Makefile b/net/nut/Makefile index bd96d27b7..4f682eb4a 100644 --- a/net/nut/Makefile +++ b/net/nut/Makefile @@ -87,8 +87,7 @@ define Package/nut-common DEPENDS:= nut \ +NUT_DRIVER_SNMP:libnetsnmp \ +NUT_DRIVER_USB:libusb-compat \ - +NUT_SSL:libopenssl \ - +PACKAGE_libwrap:libwrap + +NUT_SSL:libopenssl endef define Package/nut-common/description From d06bd2d7e3853fe025cd92b37a5d7218a0345a5f Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Mon, 26 Aug 2019 23:38:10 -0400 Subject: [PATCH 02/11] nut: Fix unset of runas user (upsmon) Running as non-root was failing due to misplace local keyword causing runas to be unset from calling value. Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-monitor.init | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/nut/files/nut-monitor.init b/net/nut/files/nut-monitor.init index 56c12c0ae..f094a82ba 100755 --- a/net/nut/files/nut-monitor.init +++ b/net/nut/files/nut-monitor.init @@ -6,11 +6,13 @@ UPSMON_C=/var/etc/nut/upsmon.conf nut_upsmon_conf() { local cfg="$1" + local RUNAS val optval echo "# Config file automatically generated from UCI config" > "$UPSMON_C" - config_get runas "$cfg" runas - [ -n "$runas" ] && echo "RUN_AS_USER $runas" >> $UPSMON_C + config_get RUNAS "$cfg" runas + [ -n "$RUNAS" ] && echo "RUN_AS_USER $RUNAS" >> "$UPSMON_C" + runas="$RUNAS" config_get val "$cfg" minsupplies 1 echo "MINSUPPLIES $val" >> "$UPSMON_C" @@ -143,7 +145,6 @@ nut_upsmon_add() { } build_config() { - local runas mkdir -m 0750 -p "$(dirname "$UPSMON_C")" config_load nut_monitor @@ -162,6 +163,7 @@ build_config() { } start_service() { + local runas local havemon havems build_config @@ -178,6 +180,7 @@ start_service() { reload_service() { if pgrep upsmon >/dev/null 2>/dev/null; then + local runas build_config /usr/sbin/upsmon -c reload else From c963f0c2971dcd7876ff9b52d77fe6d17fd040db Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Mon, 26 Aug 2019 23:43:16 -0400 Subject: [PATCH 03/11] nut: Fix upsmon init actions 1) For upsmon start and stop were at wrong position in rc.d 2) Stop needs more than just killing the procd instead but rather needs a stop command to be issued. 3) Interface up/down was causing not to enter a crashloop (we fix this with procd trigger on interface changes). Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-monitor.init | 46 ++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/net/nut/files/nut-monitor.init b/net/nut/files/nut-monitor.init index f094a82ba..1e3ab2930 100755 --- a/net/nut/files/nut-monitor.init +++ b/net/nut/files/nut-monitor.init @@ -1,6 +1,7 @@ #!/bin/sh /etc/rc.common -START=51 +START=82 +STOP=28 USE_PROCD=1 UPSMON_C=/var/etc/nut/upsmon.conf @@ -162,6 +163,32 @@ build_config() { [ -s "$UPSMON_C" ] && chgrp $(id -gn ${runas:-root}) "$UPSMON_C" } +interface_triggers() { + local action="$1" + local triggerlist trigger + + config_get triggerlist "upsmon" triggerlist + + . "${IPKG_INSTROOT}"/lib/functions/network.sh + + if [ -n "$triggerlist" ]; then + for trigger in $triggerlist; do + if [ "$action" = "add_trigger" ]; then + procd_add_interface_trigger "interface.*" "$trigger" /etc/init.d/nut-monitor restart + else + network_is_up "$trigger" && return 0 + fi + done + else + if [ "$action" = "add_trigger" ]; then + procd_add_raw_trigger "interface.*.up" 2000 /etc/init.d/nut-monitor restart + else + ubus call network.device status | grep -q '"up": true' && return 0 + fi + fi + [ "$action" = "add_trigger" ] || return 1 +} + start_service() { local runas local havemon havems @@ -169,11 +196,12 @@ start_service() { [ "$havemon" != 1 ] && return [ "$havems" != 1 ] && return + interface_triggers "check_interface_up" || return 0 procd_open_instance "upsmon" - procd_set_param respawn - procd_set_param stderr 0 - procd_set_param stdout 1 + procd_set_param respawn 10 20 6 + procd_set_param stderr 1 + procd_set_param stdout 0 procd_set_param command /usr/sbin/upsmon -D procd_close_instance } @@ -184,12 +212,16 @@ reload_service() { build_config /usr/sbin/upsmon -c reload else - stop - sleep 2 - start_service + restart fi } +stop_service() { + upsmon -c stop +} + service_triggers() { + config_load nut_monitor + interface_triggers "add_trigger" procd_add_reload_trigger "nut_monitor" } From ccdec71b5c457b4c414738f1ef7abf4326272372 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Mon, 26 Aug 2019 23:48:49 -0400 Subject: [PATCH 04/11] nut: Fix bad check for conf exists We were `cat`ing the file instead of just checking for non-empty existance. Fix that. Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-monitor.init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nut/files/nut-monitor.init b/net/nut/files/nut-monitor.init index 1e3ab2930..72458f21a 100755 --- a/net/nut/files/nut-monitor.init +++ b/net/nut/files/nut-monitor.init @@ -153,7 +153,7 @@ build_config() { config_foreach nut_upsmon_add master master config_foreach nut_upsmon_add slave slave - [ ! -s "$(cat /var/etc/nut/nut.conf)" ] && { + [ ! -s /var/etc/nut/nut.conf ] && { echo "MODE=netclient" >>/var/etc/nut/nut.conf chmod 640 /var/etc/nut/nut.conf chgrp $(id -gn ${runas:-root}) /var/etc/nut/nut.conf From 5f69f9a0654b616d90fc4494188f01a5e3aabcac Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Tue, 27 Aug 2019 00:15:12 -0400 Subject: [PATCH 05/11] nut: Fix unset of runas user (ups server) Running as non-root was failing due to misplace local keyword causing runas to be unset from calling value. Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-server.init | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/net/nut/files/nut-server.init b/net/nut/files/nut-server.init index d878e3641..611d79e06 100755 --- a/net/nut/files/nut-server.init +++ b/net/nut/files/nut-server.init @@ -39,12 +39,11 @@ upsd_statepath() { } upsd_runas() { - local cfg="$1" local runas - [ -n "$RUNAS" ] && return + [ -n "$RUNAS" ] && return 0 - config_get runas "$cfg" runas + config_get runas upsd runas RUNAS="$runas" } @@ -223,7 +222,6 @@ build_global_driver_config() { get_write_driver_config "$cfg" synchronous config_get runas "$cfg" user RUNAS="$runas" - upsd_runas echo "" >>$UPS_C } @@ -239,11 +237,13 @@ build_config() { config_load nut_server config_foreach upsd_statepath upsd + upsd_runas config_foreach build_global_driver_config driver_global config_foreach build_driver_config driver [ -n "$RUNAS" ] && chgrp $(id -gn $RUNAS) "$UPS_C" build_server_config + [ -n "$RUNAS" ] && chgrp "$(id -gn "$RUNAS")" "$UPS_C" } start_driver_instance() { @@ -284,8 +284,7 @@ start_driver_instance() { } start_server_instance() { - local RUNAS - build_config + local cfg="$1" [ "$haveserver" != 1 ] && return @@ -300,7 +299,6 @@ start_server_instance() { start_service() { local havedriver haveserver local STATEPATH=/var/run/nut - local RUNAS # Avoid hotplug inadvertenly restarting driver during # forced shutdown From e97684652125844c451e7fbf127b8f0a35653492 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Tue, 27 Aug 2019 00:19:03 -0400 Subject: [PATCH 06/11] nut: Fix statepath handling The statepath was getting the wrong permission and/or not created at the right time. This commit includes fixes for handling the statepath (typically /var/run/nut). Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-server.init | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/net/nut/files/nut-server.init b/net/nut/files/nut-server.init index 611d79e06..8062861fd 100755 --- a/net/nut/files/nut-server.init +++ b/net/nut/files/nut-server.init @@ -31,10 +31,9 @@ get_write_driver_config() { } upsd_statepath() { - local cfg="$1" local statepath - config_get statepath "$cfg" statepath "/var/run/nut" + config_get statepath upsd statepath /var/run/nut STATEPATH="$statepath" } @@ -64,7 +63,7 @@ upsd_config() { config_get runas "$cfg" runas RUNAS="$runas" - config_get statepath "$cfg" statepath "/var/run/nut" + config_get statepath "$cfg" statepath /var/run/nut STATEPATH="$statepath" config_get maxage "$cfg" maxage @@ -128,13 +127,14 @@ build_server_config() { chmod 0644 /var/etc/nut/nut.conf [ -d "${STATEPATH}" ] || { - mkdir -m 0750 -p "${STATEPATH}" + mkdir -p "${STATEPATH}" + chmod 0750 "${STATEPATH}" } if [ -n "$RUNAS" ]; then - chown $RUNAS:$(id -gn $RUNAS) "${STATEPATH}" - chgrp $(id -gn $RUNAS) "$USERS_C" - chgrp $(id -gn $RUNAS) "$UPSD_C" + chown "$RUNAS":"$(id -gn "$RUNAS")" "${STATEPATH}" + chgrp "$(id -gn "$RUNAS")" "$USERS_C" + chgrp "$(id -gn "$RUNAS")" "$UPSD_C" fi haveserver=1 } @@ -235,13 +235,11 @@ build_config() { chmod 0640 "$UPS_C" config_load nut_server - config_foreach upsd_statepath upsd upsd_runas config_foreach build_global_driver_config driver_global config_foreach build_driver_config driver - [ -n "$RUNAS" ] && chgrp $(id -gn $RUNAS) "$UPS_C" - + upsd_statepath build_server_config [ -n "$RUNAS" ] && chgrp "$(id -gn "$RUNAS")" "$UPS_C" } @@ -260,18 +258,19 @@ start_driver_instance() { mkdir -m 0755 -p "$(dirname "$UPS_C")" - [ ! -s "$UPS_C" ] && build_config + upsd_statepath + build_config # Avoid hotplug inadvertenly restarting driver during # forced shutdown [ -f /var/run/killpower ] && return 0 - [ -d /var/run/nut ] && [ -f /var/run/nut/disable-hotplug ] && return 0 - - - config_foreach upsd_statepath upsd + if [ -d /var/run/nut ] && [ -f /var/run/nut/disable-hotplug ]; then + return 0 + fi if [ -n "$RUNAS" ]; then - chown $RUNAS:$(id -gn $RUNAS) "${STATEPATH}" + chown "$RUNAS":"$(id -gn "$RUNAS")" "${STATEPATH}" + chgrp "$(id -gn "$RUNAS")" "$UPS_C" fi config_get driver "$cfg" driver "usbhid-ups" From 77519cd204b6d6289bc4c034f96d792d58e900d9 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Tue, 27 Aug 2019 00:43:25 -0400 Subject: [PATCH 07/11] nut: Fix permissions with runas Fix directory and conf file creation and owner/mode setting for when running as non-root. Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-server.init | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/nut/files/nut-server.init b/net/nut/files/nut-server.init index 8062861fd..f2edef683 100755 --- a/net/nut/files/nut-server.init +++ b/net/nut/files/nut-server.init @@ -109,7 +109,8 @@ nut_user_add() { } build_server_config() { - mkdir -m 0755 -p "$(dirname "$UPSD_C")" + mkdir -p "$(dirname "$UPSD_C")" + chmod 0640 "$UPS_C" rm -f "$USERS_C" rm -f "$UPSD_C" rm -f /var/etc/nut/nut.conf @@ -229,7 +230,7 @@ build_global_driver_config() { build_config() { local STATEPATH=/var/run/nut - mkdir -m 0755 -p "$(dirname "$UPS_C")" + mkdir -p "$(dirname "$UPS_C")" rm -f "$UPS_C" echo "# Config file automatically generated from UCI config" > "$UPS_C" chmod 0640 "$UPS_C" @@ -256,7 +257,8 @@ start_driver_instance() { # If wanting a specific instance, only start it [ "$requested" != "$cfg" ] && [ x"$requested" != x ] && return 0 - mkdir -m 0755 -p "$(dirname "$UPS_C")" + mkdir -p "$(dirname "$UPS_C")" + chmod 0755 "$UPS_C" upsd_statepath build_config From ef0bd01409f3bd0b41a0d14425388e4e7af796d8 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Tue, 27 Aug 2019 00:49:46 -0400 Subject: [PATCH 08/11] nut: Fix extra diver params config Extra parameters for the UPS driver were not being handled correctly. Fix that (was wrong variable name). Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-server.init | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/nut/files/nut-server.init b/net/nut/files/nut-server.init index f2edef683..95bc1fc48 100755 --- a/net/nut/files/nut-server.init +++ b/net/nut/files/nut-server.init @@ -181,6 +181,7 @@ build_driver_config() { local overvar="$1" local defover="$2" local overtype="$(echo "$overvar" | tr '.' '_')" + local overval config_get overval "${defover}_${overtype}" value [ -n "$overval" ] && echo "${defover}.${overvar} = $overval" >>"$UPS_C" @@ -192,20 +193,19 @@ build_driver_config() { other() { local othervar="$1" local othervarflag="$2" + local otherval if [ "$othervarflag" = "otherflag" ]; then - config_get_bool otherval "${othervarflag}_${overtype}" value - [ "$otherval" = "1" ] && echo "${othervarflag}_${othervar}" >>"$UPS_C" + config_get_bool otherval "${othervarflag}_${othervar}" value + [ "$otherval" = "1" ] && echo "${othervar}" >>"$UPS_C" else - config_get otherval "${othervarflag}_${overtype}" value - [ -n "$otherval" ] && echo "${othervarflag}_${othervar} = $otherval" >>"$UPS_C" + config_get otherval "${othervarflag}_${othervar}" value + [ -n "$otherval" ] && echo "${othervar} = $otherval" >>"$UPS_C" fi } - config_list_foreach "$cfg" override defoverride override - config_list_foreach "$cfg" default defoverride default - config_list_foreach "$cfg" default other other - config_list_foreach "$cfg" default other otherflag + config_list_foreach "$cfg" other other + config_list_foreach "$cfg" other otherflag echo "" >>$UPS_C havedriver=1 } From a2ab989c121a1177536004eafbfd64165280edf6 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Tue, 27 Aug 2019 00:53:42 -0400 Subject: [PATCH 09/11] nut: Fix init actions (server/driver) The server and driver were not starting/restarting reliably. In addition on interface changes NUT got very confused. So we fix handling of restarts and add a reload trigger for interface changes. Signed-off-by: Daniel F. Dickinson --- net/nut/files/nut-server.init | 60 +++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/net/nut/files/nut-server.init b/net/nut/files/nut-server.init index 95bc1fc48..5b003fb4c 100755 --- a/net/nut/files/nut-server.init +++ b/net/nut/files/nut-server.init @@ -4,7 +4,8 @@ # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # -START=50 +START=70 +STOP=30 USERS_C=/var/etc/nut/upsd.users UPSD_C=/var/etc/nut/upsd.conf @@ -255,7 +256,9 @@ start_driver_instance() { [ "$havedriver" != 1 ] && return # If wanting a specific instance, only start it - [ "$requested" != "$cfg" ] && [ x"$requested" != x ] && return 0 + if [ "$requested" != "$cfg" ] && [ "$request" != "" ]; then + return 0 + fi mkdir -p "$(dirname "$UPS_C")" chmod 0755 "$UPS_C" @@ -284,12 +287,39 @@ start_driver_instance() { procd_close_instance } +interface_triggers() { + local action="$1" + local triggerlist trigger + + config_get triggerlist upsd triggerlist + + . /lib/functions/network.sh + + if [ -n "$triggerlist" ]; then + for trigger in $triggerlist; do + if [ "$action" = "add_trigger" ]; then + procd_add_interface_trigger "interface.*" "$trigger" /etc/init.d/nut-server reload + else + network_is_up "$trigger" && return 0 + fi + done + else + if [ "$action" = "add_trigger" ]; then + procd_add_raw_trigger "interface.*.up" 2000 /etc/init.d/nut-server reload + else + ubus call network.device status | grep -q '"up": true' && return 0 + fi + fi + [ "$action" = "add_trigger" ] || return 1 +} + start_server_instance() { local cfg="$1" [ "$haveserver" != 1 ] && return + interface_triggers "check_interface_up" || return - procd_open_instance "upsd" + procd_open_instance "$cfg" procd_set_param respawn procd_set_param stderr 0 procd_set_param stdout 1 @@ -298,29 +328,39 @@ start_server_instance() { } start_service() { - local havedriver haveserver local STATEPATH=/var/run/nut # Avoid hotplug inadvertenly restarting driver during # forced shutdown [ -f /var/run/killpower ] && return 0 - [ -f /var/run/nut/disable-hotplug ] && return 0 config_load nut_server build_config - config_foreach start_driver_instance driver "$@" - start_server_instance "upsd" + case $@ in + "") + config_foreach start_driver_instance driver "$@" + start_server_instance upsd + ;; + *upsd*) + start_server_instance upsd + ;; + *) + config_foreach start_driver_instance driver "$@" + ;; + esac } reload_service() { - stop + stop_service "$@" sleep 2 - local havedriver haveserver - start + start_service "$@" } service_triggers() { + config_load nut_server + + interface_triggers "add_trigger" procd_add_reload_trigger "nut_server" } From 361e6aaaab0e44a07cef8410301716131e4b360d Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Tue, 27 Aug 2019 00:56:42 -0400 Subject: [PATCH 10/11] nut: Handle FSD properly Make sure we force shutdown of UPS only when we should, and when we should that shutdown happens. Signed-off-by: Daniel F. Dickinson --- net/nut/files/nutshutdown | 56 +++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/net/nut/files/nutshutdown b/net/nut/files/nutshutdown index e4fd962cd..86fe01bb9 100755 --- a/net/nut/files/nutshutdown +++ b/net/nut/files/nutshutdown @@ -4,11 +4,6 @@ # See /LICENSE for more information. # -. /lib/functions.sh - -mount -o remount,ro /overlay /overlay -mount -o remount,ro / / - stop_instance() { /etc/init.d/nut-server stop "$1" } @@ -16,26 +11,41 @@ stop_instance() { shutdown_instance() { local cfg="$1" config_get driver "$cfg" driver "usbhid-ups" - /lib/nut/${driver} -a "$cfg" -k + + # Only FSD if killpower was indicated + if [ -f /var/run/killpower ]; then + /lib/nut/"${driver}" -a "$cfg" -k + fi } -[ -f /var/run/killpower ] && { - [ -f /etc/config/nut_server ] && { - config_load nut_server +do_fsd() { + if [ -f /var/run/killpower ]; then + # Only make FS readonly if we are doing an FSD + mount -o remount,ro /overlay /overlay + mount -o remount,ro / / - # Can't FSD unless drivers are stopped - config_foreach stop_instance driver - # Driver will wait 'offdelay' before shutting down - config_foreach shutdown_instance driver - # So this can happen + . ${IPKG_INSTOOT}/lib/functions.sh + + if [ -f /etc/config/nut_server ]; then + config_load nut_server + + # Can't FSD unless drivers are stopped + config_foreach stop_instance driver + # Driver will wait 'offdelay' before shutting down + config_foreach shutdown_instance driver + # So this can happen + rm -f /var/run/killpower + poweroff + # And just in case + sleep 120 + # Uh-oh failed to poweroff UPS + reboot -f + else + poweroff + fi + else poweroff - # And just in case - sleep 120 - # Uh-oh failed to poweroff UPS - reboot -f - } || { - poweroff - } -} || { - poweroff + fi } + +do_fsd From c1aa1f784c737283b281da7a541921a88a81e684 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Tue, 27 Aug 2019 01:22:41 -0400 Subject: [PATCH 11/11] nut: Bump PKG_RELEASE Signed-off-by: Daniel F. Dickinson --- net/nut/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nut/Makefile b/net/nut/Makefile index 4f682eb4a..afb9c0975 100644 --- a/net/nut/Makefile +++ b/net/nut/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nut PKG_VERSION:=2.7.4 -PKG_RELEASE:=9 +PKG_RELEASE:=10 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://www.networkupstools.org/source/2.7/