diff --git a/lib/distributions.sh b/lib/distributions.sh index 63ae159bba..bb33c9c27e 100644 --- a/lib/distributions.sh +++ b/lib/distributions.sh @@ -429,6 +429,7 @@ FAMILY_TWEAKS chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable armbian-ramlog.service >/dev/null 2>&1" chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable armbian-resize-filesystem.service >/dev/null 2>&1" chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable armbian-hardware-monitor.service >/dev/null 2>&1" + chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable armbian-led-state.service >/dev/null 2>&1" # copy "first run automated config, optional user configured" cp "${SRC}"/packages/bsp/armbian_first_run.txt.template "${SDCARD}"/boot/armbian_first_run.txt.template diff --git a/lib/makeboarddeb.sh b/lib/makeboarddeb.sh index 56ad8b71ba..9445dc2fc0 100644 --- a/lib/makeboarddeb.sh +++ b/lib/makeboarddeb.sh @@ -255,7 +255,7 @@ fi fi # Reload services - systemctl --no-reload enable armbian-hardware-monitor.service armbian-hardware-optimize.service armbian-zram-config.service >/dev/null 2>&1 + systemctl --no-reload enable armbian-hardware-monitor.service armbian-hardware-optimize.service armbian-zram-config.service armbian-led-state.service >/dev/null 2>&1 exit 0 EOF diff --git a/packages/bsp/common/lib/systemd/system/armbian-led-state.service b/packages/bsp/common/lib/systemd/system/armbian-led-state.service new file mode 100644 index 0000000000..77d2946c87 --- /dev/null +++ b/packages/bsp/common/lib/systemd/system/armbian-led-state.service @@ -0,0 +1,21 @@ +# Armbian led state save and restore +# Stores the current led state at shutdown and restores +# it during bootstrap + +[Unit] +Description=Armbian leds state +Before=sysinit.target +After=local-fs.target +Conflicts=shutdown.target +DefaultDependencies=no + +[Service] +Type=oneshot +RemainAfterExit=true +ReadWritePaths=/sys/class/leds +ExecStart=/usr/lib/armbian/armbian-led-state-restore.sh +ExecStop=/usr/lib/armbian/armbian-led-state-save.sh + +[Install] +WantedBy=basic.target + diff --git a/packages/bsp/common/usr/lib/armbian/armbian-led-state-restore.sh b/packages/bsp/common/usr/lib/armbian/armbian-led-state-restore.sh new file mode 100755 index 0000000000..2aa3da1e89 --- /dev/null +++ b/packages/bsp/common/usr/lib/armbian/armbian-led-state-restore.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# +# Copyright (c) Authors: https://www.armbian.com/authors +# +# This file is licensed under the terms of the GNU General Public +# License version 2. This program is licensed "as is" without any +# warranty of any kind, whether express or implied. + +STATE_PATH="$1" +[[ -z "$1" ]] && STATE_PATH="/etc/armbian-leds.conf" + +REGEX_BLANK_LINE=$'^\s*$' +REGEX_COMMENT_LINE=$'^#.*$' +REGEX_EXTRACT=$'\[(.*)\]' +REGEX_PARSE=$'(.*)=(.*)' + +LED="" + +if [[ ! -f $STATE_PATH ]]; then + echo "File $STATE_PATH not found, nothing to do" + exit 0 +fi + +while read LINE; do + + # Blank lines and lines starting with "#" are ignored + [[ "$LINE" =~ $REGEX_BLANK_LINE ]] && continue + [[ "$LINE" =~ $REGEX_COMMENT_LINE ]] && continue + + # When line matches the [...] style, assign the content as led base path + if [[ "$LINE" =~ $REGEX_EXTRACT ]]; then + LED=${BASH_REMATCH[1]} + continue + fi + + if [[ -z "$LED" ]]; then + echo "Invalid state file, no led path stanza found" + exit 1 + fi + + [[ "$LINE" =~ $REGEX_PARSE ]] + + PARAM=${BASH_REMATCH[1]} + VALUE=${BASH_REMATCH[2]} + + if [[ -z $PARAM || -z $VALUE ]]; then + echo "Invalid state file, syntax error in configuration file " + exit 1 + fi + + # Ignore brightness=0 param, this will reset trigger to none + [[ $PARAM == "brightness" && $VALUE -eq 0 ]] && continue + + # Verify the led parameter exists and is writable, otherwise skip to next param + if [[ ! -w "$LED/$PARAM" ]]; then + echo "warning: $LED/$PARAM could not be restored" + continue + fi + + # Workaround for trigger=none: led does not clear if trigger is already none. + # Set it to default-on, then will be reset immediately to none to turn it off + [[ "$PARAM" == "trigger" && "$VALUE" == "none" ]] && echo "default-on" > "$LED/$PARAM" + + echo "$VALUE" > "$LED/$PARAM" + +done < $STATE_PATH + +exit 0 diff --git a/packages/bsp/common/usr/lib/armbian/armbian-led-state-save.sh b/packages/bsp/common/usr/lib/armbian/armbian-led-state-save.sh new file mode 100755 index 0000000000..9721742d8f --- /dev/null +++ b/packages/bsp/common/usr/lib/armbian/armbian-led-state-save.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Copyright (c) Authors: https://www.armbian.com/authors +# +# This file is licensed under the terms of the GNU General Public +# License version 2. This program is licensed "as is" without any +# warranty of any kind, whether express or implied. + +STATE_PATH="$1" +[[ -z "$1" ]] && STATE_PATH="/etc/armbian-leds.conf" + +# Regular expression to extract the trigger from the led trigger file +REGEX=$'\[(.*)\]' + +CMD_FIND=$(which find) + +# Retrieve the trigger for a specific led and stores the entry in a destination state file +# Also retrieve all the writable parameters for a led and stores them in a destination state file +# $1 = base led path +# $2 = path of destination state file +function store_led() { + + PATH="$1" + TRIGGER_PATH="$1/trigger" + DESTINATION="$2" + + TRIGGER_CONTENT=$(<$TRIGGER_PATH) + + [[ "$TRIGGER_CONTENT" =~ $REGEX ]] + + TRIGGER_VALUE=${BASH_REMATCH[1]} + + echo "[$LED]" >> $STATE_PATH + echo "trigger=$TRIGGER_VALUE" >> $DESTINATION + + # In case the trigger is any of the kbd-*, don't store any other parameter + # This avoids num/scroll/capslock from being restored at startup + [[ "$TRIGGER_VALUE" =~ kbd-* ]] && return + + COMMAND_PARAMS="$CMD_FIND $PATH/ -maxdepth 1 -type f ! -iname uevent ! -iname trigger -perm /u+w -printf %f\\n" + PARAMS=$($COMMAND_PARAMS) + + for PARAM in $PARAMS; do + + PARAM_PATH="$PATH/$PARAM" + VALUE=$(<$PARAM_PATH) + + echo "$PARAM=$VALUE" >> $DESTINATION + + done + +} + +# zeroing current state file if existing +[[ -f $STATE_PATH ]] && echo -n > $STATE_PATH + +for LED in /sys/class/leds/*; do + + store_led $LED $STATE_PATH + echo >> $STATE_PATH + +done