mirror of
https://github.com/miskcoo/ugreen_dx4600_leds_controller.git
synced 2025-07-23 12:23:09 +02:00
add ATA disk mapping, zpool check, netdev check, and a config file (#15)
1. Add the config file /etc/ugreen-leds.conf for environment variables used in ugreen-diskiomon (see scripts/ugreen-leds.conf) 2. Make the blinking of netdev activities, colors of different disk states / NIC link speeds configurable 3. Add the check of zpool health 4. Add the check of gateway connectivity and the link speed of network device 5. Split the systemd service to ugreen-diskiomon.service and ugreen-netdevmon@<device name>.service 6. HCTL mapping will fail in some cases (hctl mapping for SATA drives only #14), UGOS uses ATA number to map disks to slots. I changed the default mapping to ATA, which can be shown by the following scripts:
This commit is contained in:
19
README.md
19
README.md
@@ -149,6 +149,8 @@ To blink the `disk` LED when a block device is active, you can use the `ledtrig-
|
||||
|
||||
#### Start at Boot (for Debian 12)
|
||||
|
||||
The configure file of `ugreen-diskiomon` and `ugreen-netdevmon` is `/etc/ugreen-led.conf`. Please see `scripts/ugreen-leds.conf` for an example.
|
||||
|
||||
- Edit `/etc/modules-load.d/ugreen-led.conf` and add the following lines:
|
||||
```
|
||||
i2c-dev
|
||||
@@ -163,27 +165,36 @@ ledtrig-netdev
|
||||
|
||||
- Copy files in the `scripts` directory:
|
||||
```bash
|
||||
# copy the scripts
|
||||
scripts=(ugreen-diskiomon ugreen-netdevmon ugreen-probe-leds)
|
||||
for f in ${scripts[@]}; do
|
||||
chmod +x "scripts/$f"
|
||||
cp "scripts/$f" /usr/bin
|
||||
done
|
||||
|
||||
# copy the configuration file, you can change it if needed
|
||||
cp scripts/ugreen-leds.conf /etc/ugreen-leds.conf
|
||||
|
||||
# copy the systemd services
|
||||
cp scripts/*.service /etc/systemd/system/
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
# change enp2s0 to the network device you want to monitor
|
||||
systemctl start ugreen-ledmon@enp2s0
|
||||
systemctl start ugreen-netdevmon@enp2s0
|
||||
systemctl start ugreen-diskiomon
|
||||
|
||||
# if you confirm that everything works well,
|
||||
# run the command below to make the service start at boot
|
||||
systemctl enable ugreen-ledmon@enp2s0
|
||||
systemctl enable ugreen-netdevmon@enp2s0
|
||||
systemctl enable ugreen-diskiomon
|
||||
```
|
||||
|
||||
## Disk Mapping
|
||||
|
||||
To make the disk LEDs useful, we should map the disk LEDs to correct disk slots. First of all, we should highlight that using `/dev/sdX` is never a smart idea, as it may change at every boot. In the script `ugreen-diskiomon` we provide two mapping methods: **by HCTL** and **by serial**.
|
||||
To make the disk LEDs useful, we should map the disk LEDs to correct disk slots. First of all, we should highlight that using `/dev/sdX` is never a smart idea, as it may change at every boot. In the script `ugreen-diskiomon` we provide three mapping methods: **by ATA**, **by HCTL** and **by serial**.
|
||||
|
||||
The best mapping method is using serial numbers, but it needs to record them manually and fill the `DISK_SERIAL` array in `/etc/ugreen-leds.conf`. We use ATA mapping by default, and find that UGOS also uses a similar mapping method (see [#15](https://github.com/miskcoo/ugreen_dx4600_leds_controller/pull/15)). See the comments in `scripts/ugreen-leds.conf` for more details.
|
||||
|
||||
The HCTL mapping depends on how the SATA controllers are connected to the PCIe bus and the disk slots. To check the HCTL order, you can run the following command, and check the serial of your disks:
|
||||
|
||||
@@ -200,7 +211,7 @@ sdg 6:0:0:0 XXKH3SXX
|
||||
sdh 7:0:0:0 XXJDB1XX
|
||||
```
|
||||
|
||||
As far as we know, the mapping between HCTL and the disk serial are stable at each boot (see [#4](https://github.com/miskcoo/ugreen_dx4600_leds_controller/pull/4) and [#9](https://github.com/miskcoo/ugreen_dx4600_leds_controller/issues/9)). However, it has been reported that the exact order is model-dependent (see [#9](https://github.com/miskcoo/ugreen_dx4600_leds_controller/issues/9)). In DX4600 Pro and DXP8800 Plus, the mapping is `X:0:0:0 -> diskX`, but In the DXP6800 Pro, `0:0:0:0` and `1:0:0:0` are mapped to `disk5` and `disk6`, and `2:0:0:0` to `6:0:0:0` are mapped to `disk1` to `disk4`, so you should change the array `hctl_map` in `ugreen-diskiomon` accordingly.
|
||||
As far as we know, the mapping between HCTL and the disk serial are stable at each boot (see [#4](https://github.com/miskcoo/ugreen_dx4600_leds_controller/pull/4) and [#9](https://github.com/miskcoo/ugreen_dx4600_leds_controller/issues/9)). However, it has been reported that the exact order is model-dependent (see [#9](https://github.com/miskcoo/ugreen_dx4600_leds_controller/issues/9)). In DX4600 Pro and DXP8800 Plus, the mapping is `X:0:0:0 -> diskX`, but in DXP6800 Pro, `0:0:0:0` and `1:0:0:0` are mapped to `disk5` and `disk6`, and `2:0:0:0` to `6:0:0:0` are mapped to `disk1` to `disk4`. The script will use `dmidecode` to detect the device model, but I suggest to check the mapping outputed by the script manually.
|
||||
|
||||
## Communication Protocols
|
||||
|
||||
|
@@ -6,6 +6,8 @@ exit-ugreen-diskiomon() {
|
||||
rm "/var/run/ugreen-diskiomon.lock"
|
||||
fi
|
||||
kill $smart_check_pid 2>/dev/null
|
||||
kill $zpool_check_pid 2>/dev/null
|
||||
kill $disk_online_check_pid 2>/dev/null
|
||||
}
|
||||
|
||||
# trap exit and remove lockfile
|
||||
@@ -23,42 +25,55 @@ if [[ -f /boot/config/plugins/ugreenleds-driver/settings.cfg ]]; then
|
||||
source /boot/config/plugins/ugreenleds-driver/settings.cfg
|
||||
fi
|
||||
|
||||
# load environment variables
|
||||
if [[ -f /etc/ugreen-leds.conf ]]; then
|
||||
source /etc/ugreen-leds.conf
|
||||
fi
|
||||
|
||||
# led-disk mapping (see https://github.com/miskcoo/ugreen_dx4600_leds_controller/pull/4)
|
||||
MAPPING_METHOD=${MAPPING_METHOD:=hctl} # hctl, serial
|
||||
MAPPING_METHOD=${MAPPING_METHOD:=ata} # ata, hctl, serial
|
||||
led_map=(disk1 disk2 disk3 disk4 disk5 disk6 disk7 disk8)
|
||||
|
||||
# hctl, $> lsblk -S -x hctl -o hctl,serial,name
|
||||
# NOTE: It is reported that the order below should be adjusted for each model.
|
||||
# Please check the disk mapping section in https://github.com/miskcoo/ugreen_dx4600_leds_controller/blob/master/README.md.
|
||||
hctl_map=("0:0:0:0" "1:0:0:0" "2:0:0:0" "3:0:0:0" "4:0:0:0" "5:0:0:0" "6:0:0:0" "7:0:0:0")
|
||||
if which dmidecode; then
|
||||
# serial number, $> lsblk -S -x hctl -o hctl,serial,name
|
||||
serial_map=(${DISK_SERIAL})
|
||||
# ata number, $> ls /sys/block | egrep ata\d
|
||||
ata_map=("ata1" "ata2" "ata3" "ata4" "ata5" "ata6" "ata7" "ata8")
|
||||
|
||||
if which dmidecode > /dev/null; then
|
||||
product_name=$(dmidecode --string system-product-name)
|
||||
case "${product_name}" in
|
||||
"DXP6800 Pro")
|
||||
echo "Found UGREEN DXP6800 Pro"
|
||||
hctl_map=("2:0:0:0" "3:0:0:0" "4:0:0:0" "5:0:0:0" "0:0:0:0" "1:0:0:0")
|
||||
;;
|
||||
"DX4600 Pro")
|
||||
echo "Found UGREEN DX4600 Pro"
|
||||
# using the default mapping
|
||||
;;
|
||||
"DXP8800 Plus")
|
||||
echo "Found UGREEN DXP8800 Plus"
|
||||
# using the default mapping
|
||||
;;
|
||||
DXP6800*) # tested on DXP6800 Pro
|
||||
echo "Found UGREEN DXP6800 series"
|
||||
hctl_map=("2:0:0:0" "3:0:0:0" "4:0:0:0" "5:0:0:0" "0:0:0:0" "1:0:0:0")
|
||||
ata_map=("ata3" "ata4" "ata5" "ata6" "ata1" "ata2")
|
||||
;;
|
||||
DX4600*) # tested on DX4600 Pro
|
||||
echo "Found UGREEN DX4600 series"
|
||||
;;
|
||||
DXP4800*)
|
||||
echo "Found UGREEN DXP4800 series"
|
||||
;;
|
||||
DXP8800*) # tested on DXP8800 Plus
|
||||
echo "Found UGREEN DXP8800 series"
|
||||
# using the default mapping
|
||||
;;
|
||||
*)
|
||||
if [[ "${MAPPING_METHOD}" = "hctl" ]]; then
|
||||
echo "Using the default HCTL order. Please check it maps to your disk slots correctly."
|
||||
echo "If you confirm that the HCTL order is correct, or find it is different, you can submit an issue to let us know, so we can update the script."
|
||||
echo "(Read the disk mapping section in https://github.com/miskcoo/ugreen_dx4600_leds_controller/blob/master/README.md for more details)"
|
||||
fi
|
||||
;;
|
||||
if [[ "${MAPPING_METHOD}" == "hctl" || "${MAPPING_METHOD}" == "ata" ]]; then
|
||||
echo -e "\033[0;31mUsing the default HCTL order. Please check it maps to your disk slots correctly."
|
||||
echo -e "If you confirm that the HCTL order is correct, or find it is different, you can "
|
||||
echo -e "submit an issue to let us know, so we can update the script."
|
||||
echo -e "Please read the disk mapping section in the link below for more details. "
|
||||
echo -e " https://github.com/miskcoo/ugreen_dx4600_leds_controller/blob/master/README.md\033[0m"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
elif [[ "${MAPPING_METHOD}" = "hctl" ]]; then
|
||||
echo "installing the tool `dmidecode` is suggested; otherwise the script cannot detect your device and adjust the hctl_map"
|
||||
elif [[ "${MAPPING_METHOD}" == "hctl" || "${MAPPING_METHOD}" == "ata" ]]; then
|
||||
echo -e "\033[0;31minstalling the tool `dmidecode` is suggested; otherwise the script cannot detect your device and adjust the hctl/ata_map\033[0m"
|
||||
fi
|
||||
# serial number, $> lsblk -S -x hctl -o hctl,serial,name
|
||||
serial_map=("placeholder0" "placeholder1" "placeholder2" "placeholder3" "placeholder4" "placeholder5" "placeholder6" "placeholder7")
|
||||
declare -A devices
|
||||
|
||||
# set monitor SMART information to true by default if not running unRAID
|
||||
@@ -72,31 +87,55 @@ CHECK_SMART_INTERVAL=${CHECK_SMART_INTERVAL:=360}
|
||||
# refresh interval from disk leds
|
||||
LED_REFRESH_INTERVAL=${LED_REFRESH_INTERVAL:=0.1}
|
||||
|
||||
# whether to check zpool health
|
||||
CHECK_ZPOOL=${CHECK_ZPOOL:=false}
|
||||
# polling rate for checking zpool health. 5 seconds by default
|
||||
CHECK_ZPOOL_INTERVAL=${CHECK_ZPOOL_INTERVAL:=5}
|
||||
|
||||
# polling rate for checking disk online. 5 seconds by default
|
||||
CHECK_DISK_ONLINE_INTERVAL=${CHECK_DISK_ONLINE_INTERVAL:=5}
|
||||
|
||||
COLOR_DISK_HEALTH=${COLOR_DISK_HEALTH:="255 255 255"}
|
||||
COLOR_DISK_UNAVAIL=${COLOR_DISK_UNAVAIL:="255 0 0"}
|
||||
COLOR_ZPOOL_FAIL=${COLOR_ZPOOL_FAIL:="255 0 0"}
|
||||
COLOR_SMART_FAIL=${COLOR_SMART_FAIL:="255 0 0"}
|
||||
BRIGHTNESS_DISK_LEDS=${BRIGHTNESS_DISK_LEDS:="255"}
|
||||
|
||||
|
||||
{ lsmod | grep ledtrig_oneshot ; } || modprobe -v ledtrig_oneshot
|
||||
{ lsmod | grep ledtrig_oneshot > /dev/null; } || { modprobe -v ledtrig_oneshot && sleep 2; }
|
||||
|
||||
sleep 2
|
||||
function disk_enumerating_string() {
|
||||
if [[ $MAPPING_METHOD == ata ]]; then
|
||||
ls -ahl /sys/block | sed 's/\/$//' | awk '{
|
||||
if (match($0, /ata[0-9]+/)) {
|
||||
ata = substr($0, RSTART, RLENGTH);
|
||||
if (match($0, /[^\/]+$/)) {
|
||||
basename = substr($0, RSTART, RLENGTH);
|
||||
print basename, ata;
|
||||
}
|
||||
}
|
||||
}'
|
||||
elif [[ $MAPPING_METHOD == hctl || $MAPPING_METHOD == serial ]]; then
|
||||
lsblk -S -o name,${MAPPING_METHOD},tran | grep sata
|
||||
else
|
||||
echo Unsupported mapping method: ${MAPPING_METHOD}
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo Enumerating disks based on $MAPPING_METHOD...
|
||||
declare -A dev_map
|
||||
while read line
|
||||
do
|
||||
blk_line=($line)
|
||||
if [[ $MAPPING_METHOD = hctl ]]; then
|
||||
key=${blk_line[1]}
|
||||
val=${blk_line[0]}
|
||||
elif [[ $MAPPING_METHOD = serial ]]; then
|
||||
key=${blk_line[1]}
|
||||
val=${blk_line[0]}
|
||||
else
|
||||
echo Unsupported mapping method: ${MAPPING_METHOD}
|
||||
exit 1
|
||||
fi
|
||||
key=${blk_line[1]}
|
||||
val=${blk_line[0]}
|
||||
dev_map[${key}]=${val}
|
||||
echo $MAPPING_METHOD ${key} ">>" ${dev_map[${key}]}
|
||||
done <<< "$(lsblk -S -o name,${MAPPING_METHOD} | tail -n +2)"
|
||||
done <<< "$(disk_enumerating_string)"
|
||||
|
||||
# initialize LEDs
|
||||
declare -A dev_to_led_map
|
||||
for i in "${!led_map[@]}"; do
|
||||
led=${led_map[i]}
|
||||
if [[ -d /sys/class/leds/$led ]]; then
|
||||
@@ -104,35 +143,116 @@ for i in "${!led_map[@]}"; do
|
||||
echo 1 > /sys/class/leds/$led/invert
|
||||
echo 100 > /sys/class/leds/$led/delay_on
|
||||
echo 100 > /sys/class/leds/$led/delay_off
|
||||
echo "255 255 255" > /sys/class/leds/$led/color
|
||||
echo "$COLOR_DISK_HEALTH" > /sys/class/leds/$led/color
|
||||
echo "$BRIGHTNESS_DISK_LEDS" > /sys/class/leds/$led/brightness
|
||||
|
||||
# find corresponding device
|
||||
_tmp_str=${MAPPING_METHOD}_map[@]
|
||||
_tmp_arr=(${!_tmp_str})
|
||||
dev=${dev_map[${_tmp_arr[i]}]}
|
||||
if [[ -f /sys/class/block/${dev}/stat ]]; then
|
||||
devices[$led]=${dev}
|
||||
else
|
||||
# turn off the led if no disk installed on this slot
|
||||
echo 0 > /sys/class/leds/$led/brightness
|
||||
echo none > /sys/class/leds/$led/trigger
|
||||
|
||||
if [[ -v "dev_map[${_tmp_arr[i]}]" ]]; then
|
||||
dev=${dev_map[${_tmp_arr[i]}]}
|
||||
|
||||
if [[ -f /sys/class/block/${dev}/stat ]]; then
|
||||
devices[$led]=${dev}
|
||||
dev_to_led_map[$dev]=$led
|
||||
else
|
||||
# turn off the led if no disk installed on this slot
|
||||
echo 0 > /sys/class/leds/$led/brightness
|
||||
echo none > /sys/class/leds/$led/trigger
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# construct zpool device mapping
|
||||
declare -A zpool_ledmap
|
||||
if [ "$CHECK_ZPOOL" = true ]; then
|
||||
echo Enumerating zpool devices...
|
||||
while read line
|
||||
do
|
||||
zpool_dev_line=($line)
|
||||
zpool_dev_name=${zpool_dev_line[0]}
|
||||
zpool_scsi_dev_name="unknown"
|
||||
# zpool_dev_state=${zpool_dev_line[1]}
|
||||
case "$zpool_dev_name" in
|
||||
sd*)
|
||||
# remove the trailing partition number
|
||||
zpool_scsi_dev_name=$(echo $zpool_dev_name | sed 's/[0-9]*$//')
|
||||
;;
|
||||
dm*)
|
||||
# find the underlying block device of the encrypted device
|
||||
dm_slaves=($(ls /sys/block/${zpool_dev_name}/slaves))
|
||||
zpool_scsi_dev_name=${dm_slaves[0]}
|
||||
;;
|
||||
*)
|
||||
echo Unsupported zpool device type ${zpool_dev_name}.
|
||||
;;
|
||||
esac
|
||||
|
||||
# if the detected scsi device can be found in the mapping array
|
||||
#echo zpool $zpool_dev_name ">>" $zpool_scsi_dev_name ">>" ${dev_to_led_map[${zpool_scsi_dev_name}]}
|
||||
if [[ -v "dev_to_led_map[${zpool_scsi_dev_name}]" ]]; then
|
||||
zpool_ledmap[$zpool_dev_name]=${dev_to_led_map[${zpool_scsi_dev_name}]}
|
||||
echo "zpool device" $zpool_dev_name ">>" $zpool_scsi_dev_name ">> LED:"${zpool_ledmap[$zpool_dev_name]}
|
||||
fi
|
||||
done <<< "$(zpool status -L | egrep ^\\s*\(sd\|dm\))"
|
||||
|
||||
function zpool_check_loop() {
|
||||
while true; do
|
||||
while read line
|
||||
do
|
||||
zpool_dev_line=($line)
|
||||
zpool_dev_name=${zpool_dev_line[0]}
|
||||
zpool_dev_state=${zpool_dev_line[1]}
|
||||
|
||||
# TODO: do something if the pool is unhealthy?
|
||||
|
||||
if [[ -v "zpool_ledmap[${zpool_dev_name}]" ]]; then
|
||||
led=${zpool_ledmap[$zpool_dev_name]}
|
||||
|
||||
if [[ "$(cat /sys/class/leds/$led/color)" != "$COLOR_DISK_HEALTH" ]]; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
if [[ "${zpool_dev_state}" != "ONLINE" ]]; then
|
||||
echo "$COLOR_ZPOOL_FAIL" > /sys/class/leds/$led/color
|
||||
echo Disk failure detected on /dev/$dev at $(date +%Y-%m-%d' '%H:%M:%S)
|
||||
fi
|
||||
|
||||
# ==== To recover from an error, you should restart the script ====
|
||||
## case "${zpool_dev_state}" in
|
||||
## ONLINE)
|
||||
## # echo "$COLOR_DISK_HEALTH" > /sys/class/leds/$led/color
|
||||
## ;;
|
||||
## *)
|
||||
## echo "255 0 0" > /sys/class/leds/$led/color
|
||||
## ;;
|
||||
## esac
|
||||
fi
|
||||
done <<< "$(zpool status -L | egrep ^\\s*\(sd\|dm\))"
|
||||
|
||||
sleep ${CHECK_ZPOOL_INTERVAL}s
|
||||
done
|
||||
}
|
||||
|
||||
zpool_check_loop &
|
||||
zpool_check_pid=$!
|
||||
fi
|
||||
|
||||
# check disk health if enabled
|
||||
if [ "$CHECK_SMART" = true ]; then
|
||||
(
|
||||
while true; do
|
||||
for led in "${!devices[@]}"; do
|
||||
if [[ "$(cat /sys/class/leds/$led/color)" = "255 0 0" ]]; then
|
||||
if [[ "$(cat /sys/class/leds/$led/color)" != "$COLOR_DISK_HEALTH" ]]; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
dev=${devices[$led]}
|
||||
|
||||
if [[ -z $(smartctl -H /dev/${dev} | grep PASSED) ]]; then
|
||||
echo "255 0 0" > /sys/class/leds/$led/color
|
||||
echo "$COLOR_SMART_FAIL" > /sys/class/leds/$led/color
|
||||
echo Disk failure detected on /dev/$dev at $(date +%Y-%m-%d' '%H:%M:%S)
|
||||
continue
|
||||
fi
|
||||
@@ -143,40 +263,42 @@ if [ "$CHECK_SMART" = true ]; then
|
||||
smart_check_pid=$!
|
||||
fi
|
||||
|
||||
# check for zpool-leds.sh and set variable
|
||||
if [[ -f /usr/bin/zpool-leds.sh ]]; then
|
||||
ZPOOL_LEDS="bash /usr/bin/zpool-leds.sh"
|
||||
else
|
||||
ZPOOL_LEDS=""
|
||||
fi
|
||||
# check disk online status
|
||||
(
|
||||
while true; do
|
||||
for led in "${!devices[@]}"; do
|
||||
dev=${devices[$led]}
|
||||
|
||||
if [[ "$(cat /sys/class/leds/$led/color)" != "$COLOR_DISK_HEALTH" ]]; then
|
||||
continue;
|
||||
fi
|
||||
|
||||
if [[ ! -f /sys/class/block/${dev}/stat ]]; then
|
||||
echo "$COLOR_DISK_UNAVAIL" > /sys/class/leds/$led/color 2>/dev/null
|
||||
echo Disk /dev/$dev went offline at $(date +%Y-%m-%d' '%H:%M:%S)
|
||||
continue
|
||||
fi
|
||||
done
|
||||
sleep ${CHECK_DISK_ONLINE_INTERVAL}s
|
||||
done
|
||||
) &
|
||||
disk_online_check_pid=$!
|
||||
|
||||
# monitor disk activities
|
||||
declare -A diskio_data_rw
|
||||
while true; do
|
||||
for led in "${!devices[@]}"; do
|
||||
dev=${devices[$led]}
|
||||
diskio_old_rw="${diskio_data_rw[$led]}"
|
||||
|
||||
if [[ "$(cat /sys/class/leds/$led/color)" = "255 0 0" ]]; then
|
||||
continue;
|
||||
fi
|
||||
# if $dev does not exist, diskio_new_rw="", which will be safe
|
||||
diskio_new_rw="$(cat /sys/block/${devices[$led]}/stat 2>/dev/null)"
|
||||
|
||||
if [[ ! -f /sys/class/block/${dev}/stat ]]; then
|
||||
echo "255 0 0" > /sys/class/leds/$led/color 2>/dev/null
|
||||
echo Disk /dev/$dev went offline at $(date +%Y-%m-%d' '%H:%M:%S)
|
||||
continue
|
||||
fi
|
||||
|
||||
diskio_new_rw="$(cat /sys/block/${dev}/stat)"
|
||||
|
||||
if [ "${diskio_old_rw}" != "${diskio_new_rw}" ]; then
|
||||
if [ "${diskio_data_rw[$led]}" != "${diskio_new_rw}" ]; then
|
||||
echo 1 > /sys/class/leds/$led/shot
|
||||
fi
|
||||
|
||||
diskio_data_rw[$led]=$diskio_new_rw
|
||||
done
|
||||
|
||||
${ZPOOL_LEDS}
|
||||
|
||||
sleep ${LED_REFRESH_INTERVAL}s
|
||||
|
||||
done
|
||||
|
@@ -1,12 +0,0 @@
|
||||
[Unit]
|
||||
Description=UGREEN LEDs daemon for monitoring diskio / netio (of %i) and blinking corresponding LEDs
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/bin/ugreen-probe-leds
|
||||
ExecStartPre=/usr/bin/ugreen-netdevmon %i
|
||||
ExecStart=/usr/bin/ugreen-diskiomon
|
||||
StandardOutput=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
99
scripts/ugreen-leds.conf
Normal file
99
scripts/ugreen-leds.conf
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
# configuration file for ugreen-diskiomon and ugreen-netdevmon
|
||||
# it should be put in /etc/ugreen-leds.conf
|
||||
|
||||
# =========== parameters of disk activities monitoring ===========
|
||||
|
||||
# The method of mapping disks to LEDs: ata, hctl, serial
|
||||
# ata: default, also used in UGOS
|
||||
# $> ls -ahl /sys/block | grep ata[0-9] --color
|
||||
# * you should check whether it will change after reboot
|
||||
#
|
||||
# hctl: mapping by HCTL,
|
||||
# $> lsblk -S -x hctl -o hctl,serial,name
|
||||
# it will fail in some devices if you have USB disks inserted, but works well otherwise
|
||||
# * you should check whether it will change after reboot
|
||||
# ** see https://github.com/miskcoo/ugreen_dx4600_leds_controller/issues/14
|
||||
#
|
||||
# serial: suggested, mapping by serial
|
||||
# this method requires the user to check the disks' serial numbers
|
||||
# and fill the DISK_SERIAL array below (see the comments therein).
|
||||
MAPPING_METHOD=ata
|
||||
|
||||
# The serial numbers of disks (used only when MAPPING_METHOD=serial)
|
||||
# You need to record them before inserting to your NAS, and the corresponding disk slots.
|
||||
# If you have 4 disks, with serial numbers: SN1 SN2 SN3 SN4,
|
||||
# then the config below leads to the following mapping:
|
||||
# SN1 -- disk1
|
||||
# SN2 -- disk2
|
||||
# SN3 -- disk3
|
||||
# SN4 -- disk4
|
||||
DISK_SERIAL="SN1 SN2 SN3 SN4"
|
||||
|
||||
# The sleep time between two disk activities checks (default: 0.1 seconds)
|
||||
LED_REFRESH_INTERVAL=0.1
|
||||
|
||||
# brightness of disk LEDs, taking value from 1 to 255 (default: 255)
|
||||
BRIGHTNESS_DISK_LEDS="255"
|
||||
|
||||
# color of a healthy disk (default: 255 255 255)
|
||||
COLOR_DISK_HEALTH="255 255 255"
|
||||
|
||||
# color of an unavailable disk (default: 255 0 0)
|
||||
COLOR_DISK_UNAVAIL="255 0 0"
|
||||
|
||||
# color of a failed zpool device (default: 255 0 0)
|
||||
COLOR_ZPOOL_FAIL="255 0 0"
|
||||
|
||||
# color of a device with unhealthy smart info (default: 255 0 0)
|
||||
COLOR_SMART_FAIL="255 0 0"
|
||||
|
||||
# Check the disk health by smartctl (default: true)
|
||||
CHECK_SMART=true
|
||||
|
||||
# The sleep time between two smart checks (default: 360 seconds)
|
||||
CHECK_SMART_INTERVAL=360
|
||||
|
||||
# Check the zpool health (default: false)
|
||||
CHECK_ZPOOL=false
|
||||
|
||||
# The sleep time between two zpool checks (default: 5 seconds)
|
||||
CHECK_ZPOOL_INTERVAL=5
|
||||
|
||||
# The sleep time between two disk online checks (default: 5 seconds) CHECK_DISK_ONLINE_INTERVAL=5
|
||||
|
||||
|
||||
# =========== parameters of network activities monitoring ===========
|
||||
|
||||
# Blink the netdev light when sending data (default: 1)
|
||||
NETDEV_BLINK_TX=1
|
||||
|
||||
# Blink the netdev light when receiving data (default: 1)
|
||||
NETDEV_BLINK_RX=1
|
||||
|
||||
# A cycle of netdev blinking (default: 200 milliseconds)
|
||||
NETDEV_BLINK_INTERVAL=200
|
||||
|
||||
# color of the netdev under the normal state (for CHECK_LINK_SPEED=false)
|
||||
COLOR_NETDEV_NORMAL="255 255 255"
|
||||
|
||||
# The sleep time between two netdev connectivity / link speed monitoring (default: 60 seconds)
|
||||
CHECK_NETDEV_INTERVAL=60
|
||||
|
||||
# Monitor the gateway connectivity (default: false)
|
||||
CHECK_GATEWAY_CONNECTIVITY=false
|
||||
|
||||
# Monitor the link speed (default: false)
|
||||
CHECK_LINK_SPEED=false
|
||||
|
||||
# brightness of the netdev LED, taking value from 1 to 255 (default: 255)
|
||||
BRIGHTNESS_NETDEV_LED="255"
|
||||
|
||||
# color of the netdev under different link speeds (for CHECK_LINK_SPEED=true)
|
||||
COLOR_NETDEV_LINK_100="255 255 255"
|
||||
COLOR_NETDEV_LINK_1000="255 255 255"
|
||||
COLOR_NETDEV_LINK_2500="255 255 255"
|
||||
COLOR_NETDEV_LINK_10000="255 255 255"
|
||||
|
||||
# color of the netdev when unable to ping the gateway
|
||||
COLOR_NETDEV_GATEWAY_UNREACHABLE="255 0 0"
|
@@ -1,13 +1,91 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
{ lsmod | grep ledtrig_netdev ; } || modprobe -v ledtrig_netdev
|
||||
# function for removing lockfile
|
||||
exit-ugreen-netdevmon() {
|
||||
if [[ -f "/var/run/ugreen-netdevmon.lock" ]]; then
|
||||
rm "/var/run/ugreen-netdevmon.lock"
|
||||
fi
|
||||
kill $smart_check_pid 2>/dev/null
|
||||
kill $zpool_check_pid 2>/dev/null
|
||||
kill $disk_online_check_pid 2>/dev/null
|
||||
}
|
||||
|
||||
sleep 2
|
||||
# trap exit and remove lockfile
|
||||
trap 'exit-ugreen-netdevmon' EXIT
|
||||
|
||||
# check if script is already running
|
||||
if [[ -f "/var/run/ugreen-netdevmon.lock" ]]; then
|
||||
echo "ugreen-netdevmon already running!"
|
||||
exit 1
|
||||
fi
|
||||
touch /var/run/ugreen-netdevmon.lock
|
||||
|
||||
{ lsmod | grep ledtrig_netdev > /dev/null; } || { modprobe -v ledtrig_netdev && sleep 2; }
|
||||
|
||||
# load environment variables
|
||||
if [[ -f /etc/ugreen-leds.conf ]]; then
|
||||
source /etc/ugreen-leds.conf
|
||||
fi
|
||||
|
||||
COLOR_NETDEV_NORMAL=${COLOR_NETDEV_NORMAL:="255 255 255"}
|
||||
COLOR_NETDEV_GATEWAY_UNREACHABLE=${COLOR_NETDEV_GATEWAY_UNREACHABLE:="255 0 0"}
|
||||
|
||||
BRIGHTNESS_NETDEV_LED=${BRIGHTNESS_NETDEV_LED:="255"}
|
||||
|
||||
CHECK_NETDEV_INTERVAL=${CHECK_NETDEV_INTERVAL:=60}
|
||||
CHECK_GATEWAY_CONNECTIVITY=${CHECK_GATEWAY_CONNECTIVITY:=false}
|
||||
CHECK_LINK_SPEED=${CHECK_LINK_SPEED:=false}
|
||||
|
||||
led="netdev"
|
||||
netdev_name=$1
|
||||
echo netdev > /sys/class/leds/$led/trigger
|
||||
echo $1 > /sys/class/leds/$led/device_name
|
||||
echo $netdev_name > /sys/class/leds/$led/device_name
|
||||
echo 1 > /sys/class/leds/$led/link
|
||||
echo 1 > /sys/class/leds/$led/tx
|
||||
echo 1 > /sys/class/leds/$led/rx
|
||||
echo 200 > /sys/class/leds/$led/interval
|
||||
echo ${NETDEV_BLINK_TX:=1} > /sys/class/leds/$led/tx
|
||||
echo ${NETDEV_BLINK_RX:=1} > /sys/class/leds/$led/rx
|
||||
echo ${NETDEV_BLINK_INTERVAL:=200} > /sys/class/leds/$led/interval
|
||||
echo $COLOR_NETDEV_NORMAL > /sys/class/leds/$led/color
|
||||
echo $BRIGHTNESS_NETDEV_LED > /sys/class/leds/$led/brightness
|
||||
|
||||
function set_netdev_normal_color() {
|
||||
color=$COLOR_NETDEV_NORMAL
|
||||
|
||||
if [[ $CHECK_LINK_SPEED == true ]]; then
|
||||
case $(cat /sys/class/net/$netdev_name/speed) in
|
||||
100) color=${COLOR_NETDEV_LINK_100:=$COLOR_NETDEV_NORMAL};;
|
||||
1000) color=${COLOR_NETDEV_LINK_1000:=$COLOR_NETDEV_NORMAL};;
|
||||
2500) color=${COLOR_NETDEV_LINK_2500:=$COLOR_NETDEV_NORMAL};;
|
||||
10000) color=${COLOR_NETDEV_LINK_10000:=$COLOR_NETDEV_NORMAL};;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo $color > /sys/class/leds/$led/color
|
||||
}
|
||||
|
||||
if [[ $CHECK_GATEWAY_CONNECTIVITY == false && $CHECK_LINK_SPEED == false ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
gw_conn=1
|
||||
|
||||
while true; do
|
||||
|
||||
if [[ $CHECK_GATEWAY_CONNECTIVITY == true ]]; then
|
||||
gw=$(ip route | awk '/default/ { print $3 }')
|
||||
if ping -q -c 1 -W 1 $gw >/dev/null; then
|
||||
gw_conn=1
|
||||
else
|
||||
gw_conn=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $gw_conn == 1 ]]; then
|
||||
set_netdev_normal_color
|
||||
else
|
||||
echo $COLOR_NETDEV_GATEWAY_UNREACHABLE > /sys/class/leds/$led/color
|
||||
fi
|
||||
|
||||
|
||||
sleep ${CHECK_NETDEV_INTERVAL}s
|
||||
|
||||
done
|
||||
|
11
scripts/ugreen-netdevmon@.service
Normal file
11
scripts/ugreen-netdevmon@.service
Normal file
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=UGREEN LEDs daemon for monitoring netio (of %i) and blinking corresponding LEDs
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/bin/ugreen-probe-leds
|
||||
ExecStart=/usr/bin/ugreen-netdevmon %i
|
||||
StandardOutput=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
Reference in New Issue
Block a user