From d7db15459f222ef1b5878c543a01a78fb55a73a7 Mon Sep 17 00:00:00 2001 From: "Daniel F. Dickinson" Date: Wed, 16 Jan 2019 07:09:13 -0500 Subject: [PATCH] nut: initscripts hotplug: Fix many small semantic issues Small but important tweaks to fix the operation of the nut initscripts and hotplug scripts. All hail shellcheck and proofreading and dogfooding. Signed-off-by: Daniel F. Dickinson --- net/nut/Makefile | 12 +-- net/nut/files/30-libhid-ups.head | 13 ++- net/nut/files/30-libhid-ups.tail | 2 +- net/nut/files/nut-cgi.init | 9 ++- net/nut/files/nut-monitor.init | 69 +++++++++------- net/nut/files/nut-sendmail-notify | 4 +- net/nut/files/nut-sendmail-notify.default | 2 +- net/nut/files/nut-server.init | 96 +++++++++++++---------- net/nut/files/nut_serial.hotplug | 33 +++++--- net/nut/files/nut_server | 1 + net/nut/files/nutshutdown | 49 ++++++------ 11 files changed, 165 insertions(+), 125 deletions(-) diff --git a/net/nut/Makefile b/net/nut/Makefile index 5dd635c27..555f97357 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:=14 +PKG_RELEASE:=15 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://www.networkupstools.org/source/2.7/ @@ -73,12 +73,12 @@ define Package/nut-server/install $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/nut/cmdvartab $(1)/usr/share/nut/ $(INSTALL_DIR) $(1)/etc/config $(INSTALL_CONF) ./files/nut_server $(1)/etc/config/nut_server - ln -sf /var/etc/nut/upsd.users $(1)/etc/nut/upsd.users - ln -sf /var/etc/nut/upsd.conf $(1)/etc/nut/upsd.conf + ln -sf ../../var/etc/nut/upsd.users $(1)/etc/nut/upsd.users + ln -sf ../../var/etc/nut/upsd.conf $(1)/etc/nut/upsd.conf # Driver common portion $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/upsdrvctl $(1)/usr/sbin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/share/nut/driver.list $(1)/usr/share/nut/ - ln -sf /var/etc/nut/ups.conf $(1)/etc/nut/ups.conf + ln -sf ../../var/etc/nut/ups.conf $(1)/etc/nut/ups.conf # Mangle libhid.usermap into a format (hotplug shell script) useful for OpenWrt $(INSTALL_DIR) $(1)/etc/hotplug.d/usb $(INSTALL_DIR) $(1)/etc/hotplug.d/tty @@ -376,10 +376,10 @@ define DriverPackage # new version of nut we will need to provide descriptions for any new # drivers. define Package/nut-driver-$(2)/description - + endef define Package/nut-driver-$(2)/install - $(INSTALL_DIR) $$(1)/lib/nut + $(INSTALL_DIR) $$(1)/lib/nut $(CP) $$(PKG_INSTALL_DIR)/lib/nut/$(2) $$(1)/lib/nut/ $(if $(filter $(2),clone),$(CP) $$(PKG_INSTALL_DIR)/lib/nut/$(2)-outlet $$(1)/lib/nut/) endef diff --git a/net/nut/files/30-libhid-ups.head b/net/nut/files/30-libhid-ups.head index a65094646..eebda998c 100755 --- a/net/nut/files/30-libhid-ups.head +++ b/net/nut/files/30-libhid-ups.head @@ -1,7 +1,5 @@ #!/bin/sh -. /lib/functions.sh - nut_driver_config() { local cfg="$1" local nomatch="$2" @@ -10,23 +8,19 @@ nut_driver_config() { config_get vendorid "$cfg" vendorid config_get productid "$cfg" productid - [ "$ACTION" = "add" ] &&[ -n "$DEVNAME" ] && { + [ "$ACTION" = "add" ] && [ -n "$DEVNAME" ] && { chmod 0660 /dev/"$DEVNAME" - chown ${runas:-root}:$(id -gn "${runas:-root}") /dev/"$DEVNAME" + chown "${runas:-root}":"$(id -gn "${runas:-root}")" /dev/"$DEVNAME" } if [ "$nomatch" = "1" ]; then [ "$ACTION" = "add" ] && { /etc/init.d/nut-server start "$cfg" } - [ "$ACTION" = "remove" ] && { - /etc/init.d/nut-server stop "$cfg" - } elif [ "$(printf "%04x" 0x"$pvendid")" = "$vendorid" ] && \ [ "$(printf "%04x" 0x"$pprodid")" = "$productid" ]; then [ "$ACTION" = "add" ] && { /etc/init.d/nut-server start "$cfg" - /etc/init.d/nut-server reload upsd } [ "$ACTION" = "remove" ] && { /etc/init.d/nut-server stop "$cfg" @@ -36,6 +30,8 @@ nut_driver_config() { } perform_libhid_action() { + . /lib/functions.sh + local vendorid productid runas local pvendid pprodid found @@ -47,6 +43,7 @@ perform_libhid_action() { config_load nut_server config_foreach nut_driver_config driver 0 [ "$found" != "1" ] && config_foreach nut_driver_config driver 1 + /etc/init.d/nut-server start upsd } [ -n "$PRODUCT" ] && case "$PRODUCT" in diff --git a/net/nut/files/30-libhid-ups.tail b/net/nut/files/30-libhid-ups.tail index 343fd0963..3846bc3ee 100644 --- a/net/nut/files/30-libhid-ups.tail +++ b/net/nut/files/30-libhid-ups.tail @@ -1,5 +1,5 @@ "") - [ ! -f /var/run/nut/disable-hotplug ] && \ + [ -f /var/run/nut/disable-hotplug ] || \ /etc/init.d/nut-server enabled && perform_libhid_action ;; esac diff --git a/net/nut/files/nut-cgi.init b/net/nut/files/nut-cgi.init index 9d408bb6a..68d39f668 100755 --- a/net/nut/files/nut-cgi.init +++ b/net/nut/files/nut-cgi.init @@ -4,7 +4,8 @@ # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # -START=60 +START=87 +STOP=23 USE_PROCD=1 DEFAULT=/etc/default/nut @@ -17,11 +18,11 @@ nut_upscgi_upsset() { config_get_bool enable "$cfg" enable 0 - [ $enable -eq 1 ] && { + if [ "$enable" -eq 1 ]; then ln -sf /etc/nut/upsset.conf.enable "$UPSCGI_S" - } || { + else ln -sf /etc/nut/upsset.conf.disable "$UPSCGI_S" - } + fi } nut_upscgi_add() { diff --git a/net/nut/files/nut-monitor.init b/net/nut/files/nut-monitor.init index e1448c7fa..bc463d7f5 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 @@ -12,7 +13,7 @@ nut_upsmon_conf() { config_get RUNAS "$cfg" runas "nutmon" [ -n "$RUNAS" ] && echo "RUN_AS_USER $RUNAS" >> "$UPSMON_C" - runas=$RUNAS + runas="$RUNAS" config_get val "$cfg" minsupplies 1 echo "MINSUPPLIES $val" >> "$UPSMON_C" @@ -86,16 +87,18 @@ nut_upsmon_conf() { val="" config_list_foreach "$cfg" defaultnotify notifylist default="$optval" - echo "NOTIFYFLAG ONLINE $(setnotify "$cfg" onlinenotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG ONBATT $(setnotify "$cfg" onbattnotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG LOWBATT $(setnotify "$cfg" lowbatnotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG FSD $(setnotify "$cfg" fsdnotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG COMMOK $(setnotify "$cfg" commoknotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG COMMBAD $(setnotify "$cfg" commbadnotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG SHUTDOWN $(setnotify "$cfg" shutdownnotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG REPLBATT $(setnotify "$cfg" repolbattnotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG NOCOMM $(setnotify "$cfg" nocommnotify)" >> "$UPSMON_C" - echo "NOTIFYFLAG NOPARENT $(setnotify "$cfg" noparentnotify)" >> "$UPSMON_C" + { + echo "NOTIFYFLAG ONLINE $(setnotify "$cfg" onlinenotify)" ; \ + echo "NOTIFYFLAG ONBATT $(setnotify "$cfg" onbattnotify)" ; \ + echo "NOTIFYFLAG LOWBATT $(setnotify "$cfg" lowbatnotify)" ; \ + echo "NOTIFYFLAG FSD $(setnotify "$cfg" fsdnotify)" ; \ + echo "NOTIFYFLAG COMMOK $(setnotify "$cfg" commoknotify)" ; \ + echo "NOTIFYFLAG COMMBAD $(setnotify "$cfg" commbadnotify)" ; \ + echo "NOTIFYFLAG SHUTDOWN $(setnotify "$cfg" shutdownnotify)" ; \ + echo "NOTIFYFLAG REPLBATT $(setnotify "$cfg" repolbattnotify)" ; \ + echo "NOTIFYFLAG NOCOMM $(setnotify "$cfg" nocommnotify)" ; \ + echo "NOTIFYFLAG NOPARENT $(setnotify "$cfg" noparentnotify)" ; \ + } >> "$UPSMON_C" config_get val "$cfg" rbwarntime 43200 echo "RBWARNTIME $val" >> "$UPSMON_C" @@ -145,7 +148,7 @@ nut_upsmon_add() { } build_config() { - local runas + local runas=nutmon mkdir -m 0750 -p "$(dirname "$UPSMON_C")" config_load nut_monitor @@ -153,14 +156,14 @@ 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 + chgrp "$(id -gn "${runas:-nutmon}")" /var/etc/nut/nut.conf } [ -s "$UPSMON_C" ] && chmod 640 "$UPSMON_C" - [ -s "$UPSMON_C" ] && chgrp $(id -gn ${runas:-root}) "$UPSMON_C" + [ -s "$UPSMON_C" ] && chgrp "$(id -gn "${runas:-nutmon}")" "$UPSMON_C" } interface_triggers() { @@ -169,19 +172,19 @@ interface_triggers() { config_get triggerlist "upsmon" triggerlist - . /lib/functions/network.sh + . "${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 reload + 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 reload + 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 @@ -193,16 +196,26 @@ start_service() { local havemon havems build_config - [ "$havemon" != 1 ] && return - [ "$havems" != 1 ] && return - interface_triggers "check_interface_up" || return + [ "$havemon" != 1 ] && return 1 + [ "$havems" != 1 ] && return 1 + 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 + + return 0 +} + +restart() { + trap '' TERM + stop "$@" + sleep 2 + trap - TERM + start "$@" } reload_service() { @@ -210,14 +223,12 @@ reload_service() { build_config /usr/sbin/upsmon -c reload else - stop - sleep 2 - start_service + restart fi } service_triggers() { - confg_load nut_monitor + config_load nut_monitor interface_triggers "add_trigger" procd_add_reload_trigger "nut_monitor" } diff --git a/net/nut/files/nut-sendmail-notify b/net/nut/files/nut-sendmail-notify index 749aa9bf6..f21e41e89 100755 --- a/net/nut/files/nut-sendmail-notify +++ b/net/nut/files/nut-sendmail-notify @@ -1,6 +1,7 @@ #!/bin/sh -/usr/sbin/sendmail root <>"$UPS_C" @@ -190,6 +192,7 @@ build_driver_config() { other() { local othervar="$1" local othervarflag="$2" + local otherval if [ "$othervarflag" = "otherflag" ]; then config_get_bool otherval "${othervarflag}_${othervar}" value @@ -217,29 +220,28 @@ build_global_driver_config() { get_write_driver_config "$cfg" retrydelay get_write_driver_config "$cfg" pollinterval get_write_driver_config "$cfg" synchronous - config_get runas "$cfg" user "nut" + config_get runas "$cfg" user nut RUNAS="$runas" - upsd_runas - echo "" >>$UPS_C + echo "" >>"$UPS_C" } 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" 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" } start_driver_instance() { @@ -252,22 +254,26 @@ 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 -m 0755 -p "$(dirname "$UPS_C")" + mkdir -p "$(dirname "$UPS_C")" + chmod 0755 "$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" @@ -275,7 +281,7 @@ start_driver_instance() { procd_set_param respawn procd_set_param stderr 0 procd_set_param stdout 1 - procd_set_param command /lib/nut/${driver} -D -a "$cfg" ${RUNAS:+-u $RUNAS} + procd_set_param command /lib/nut/"${driver}" -D -a "$cfg" ${RUNAS:+-u "$RUNAS"} procd_close_instance } @@ -283,7 +289,7 @@ interface_triggers() { local action="$1" local triggerlist trigger - config_get triggerlist "upsd" triggerlist + config_get triggerlist upsd triggerlist . /lib/functions/network.sh @@ -306,43 +312,47 @@ interface_triggers() { } start_server_instance() { - local RUNAS=nut - build_config + 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 - procd_set_param command /usr/sbin/upsd -D ${RUNAS:+-u $RUNAS} + procd_set_param command /usr/sbin/upsd -D ${RUNAS:+-u "$RUNAS"} procd_close_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() { diff --git a/net/nut/files/nut_serial.hotplug b/net/nut/files/nut_serial.hotplug index f320d09a6..fa3bafeb8 100644 --- a/net/nut/files/nut_serial.hotplug +++ b/net/nut/files/nut_serial.hotplug @@ -2,20 +2,33 @@ nut_serial() { local cfg="$cfg" - config_get runas upsd runas "nut" + local runas enable_usb_serial port config_get_bool enable_usb_serial "$cfg" enable_usb_serial 0 + config_get port "$cfg" port + config_get runas "$cfg" runas "nut" + + [ -z "$runas" ] && config_get runas upsd runas "nut" + + [ "$enable_usb_serial" -eq 1 ] && { + # If port is specified only change tty's matching port + if [ -n "$port" ] && [ "$port" != /dev/"$DEVNAME" ]; then + return 0 + fi + [ -n "$runas" ] && chgrp "$(id -gn "${runas}")" /dev/"$DEVNAME" + chmod g+rw /dev/"$DEVNAME" + } } -[ "$ACTION" = "add" ] && [ -n "$DEVNAME" ] && [ -z "${DEVNAME%ttyUSB*}" ] && { +nut_on_hotplug_add() { + . "${IPKG_INSTROOT}"/lib/functions.sh + config load nut_server config_foreach nut_serial driver +} - [ -z "$RUNAS" ] && { - RUNAS="$runas" - } - - [ "$enable_usb_serial" -eq 1 ] && { - chown "${RUNAS:-nut}" /dev/$DEVNAME - chmod g+rw /dev/$DEVNAME - } +[ "$ACTION" = "add" ] && [ -n "$DEVNAME" ] && { + # On add of a serial port with name ttyUSB* + [ -z "${DEVNAME%ttyUSB*}" ] && nut_on_hutplug_add + # On add of a serial port with name ttyAMA* + [ -z "${DEVNAME%ttyAMA*}" ] && nut_on_hutplug_add } diff --git a/net/nut/files/nut_server b/net/nut/files/nut_server index 6449203a4..cda92497d 100644 --- a/net/nut/files/nut_server +++ b/net/nut/files/nut_server @@ -4,6 +4,7 @@ #config driver 'upsname' # option driver usbhid-ups # option port auto +# option enable_usb_serial 0 #config user # option username upsuser diff --git a/net/nut/files/nutshutdown b/net/nut/files/nutshutdown index ad1cda2d3..8400c9a6e 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,29 +11,39 @@ stop_instance() { shutdown_instance() { local cfg="$1" config_get driver "$cfg" driver "usbhid-ups" + # Only FSD if killpower was indicated if [ -f /var/run/killpower ]; then - /lib/nut/${driver} -a "$cfg" -k + /lib/nut/"${driver}" -a "$cfg" -k fi } -if [ -f /var/run/killpower ]; then - if [ -f /etc/config/nut_server ]; then - 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 / / + + . ${IPKG_INSTOOT}/lib/functions.sh - # 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 - poweroff - # And just in case - sleep 120 - # Uh-oh failed to poweroff UPS - reboot -f + 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 fi -else - poweroff -fi +}