In part 1 Debian Buster was installed via debootstrap. Part 2 discussed how a suitable kernel can be compiled.
Getting the LED to work
Having looked at the wrong places, I finally got the LED control to work. The DTB configures all internal devices and exposes them at /proc/devices/platform.
Aparrently there ar four PWM devices, of which only #3 is enabled. By adjusting the duty cycle one can actually control the LED:
echo 0 > /sys/devices/platform/980070d0.pwm/dutyRate3 # LED off echo 100 > /sys/devices/platform/980070d0.pwm/dutyRate3 # LED 100% brightness
Digging deeper I found a kernel document describing how to add PWM controlled LEDs to the generic LED interface of the kernel. From there it was straight forward adding the required lines to the DTB (part of my kernel patches).
// linux-kernel/arch/arm64/boot/dts/realtek/wd-monarch-1GB.SATA.dts pwmleds { compatible = "pwm-leds"; pwm3{ label = "led"; pwms = <&pwm 3 37878>; max-brightness = <255>; }; };
Now the LED can be controlled via
echo 0 > /sys/class/leds/led/brightness # LED off echo 255 > /sys/class/leds/led/brightness # LED 100% brightness
The updated pre-compiled DTB matching my kernel can be found here. Have a look at part 2 on how to apply that in case you are wondering...
Below is a modified version of the monitorio script I use from my old MyBook Live. It's been modified to match the disks of the MCH. Additional required packages are hdparm and smartmontools.
The LED will now be turned off when the disk enters standby, and return to 100% brightness when the disk is active.
#!/bin/bash # # (c) 2011 Western Digital Technologies, Inc. All rights reserved. # # monitorio - Monitor disk activity, and put system into standby. ## PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin . /lib/lsb/init-functions MIN_SINCE_DISK_ACCESS=/tmp/minutes_since_disk_access dataVolumeDevice=/dev/sataa24 currentRootDevice=/dev/sataa20 declare -i sleepcount declare -i rootdisk_thresh declare -i enterStandbyTime=0 rm -f /tmp/standby source /usr/local/etc/standby.conf resetSleepCount() { sleepcount=0 source /usr/local/etc/standby.conf rootdisk_thresh=$((standby_time-1)) } rootDisk=`basename ${currentRootDevice}` dataVolumeDisk=`basename ${dataVolumeDevice}` drivelist=(${dataVolumeDevice}) echo "0" > ${MIN_SINCE_DISK_ACCESS} echo 255 > /sys/class/leds/led/brightness if [ "$1" == "debug" ]; then echo "1" > /proc/sys/vm/block_dump dmesg -c > /dev/null fi while :; do for i in ${drivelist[@]}; do smartctl -i -n standby /dev/sataa | grep -q "STANDBY" standby_test=$? [ "$standby_test" -eq "1" ] && break done if [ "$standby_test" -eq "0" ]; then sleep 5 continue else if [ -f /tmp/standby ]; then standby_since=`stat --format %z /tmp/standby` rm -f /tmp/standby # Turn on LED echo 255 > /sys/class/leds/led/brightness currentTime=`date +%s` timeInStandby=`expr $currentTime - $enterStandbyTime` echo "exit standby after $timeInStandby (since $standby_since)" logger "exit standby after $timeInStandby (since $standby_since)" if [ "$1" == "debug" ]; then dmesg -c fi fi resetSleepCount echo $sleepcount > ${MIN_SINCE_DISK_ACCESS} ior_root=`awk -v disk="${rootDisk}" '{if ($3==disk) print $6}' /proc/diskstats` iow_root=`awk -v disk="${rootDisk}" '{if ($3==disk) print $10}' /proc/diskstats` ior_datavol=`awk -v disk="${dataVolumeDisk}" '{if ($3==disk) print $6}' /proc/diskstats` iow_datavol=`awk -v disk="${dataVolumeDisk}" '{if ($3==disk) print $10}' /proc/diskstats` if [ "$1" == "debug" ]; then echo "Init ior_datavol=$ior_datavol ior_datavol2=$ior_datavol2" echo " iow_datavol=$iow_datavol iow_datavol2=$iow_datavol2" echo " ior_root=$ior_root ior_root2=$ior_root2" echo " iow_root=$iow_root iow_root2=$iow_root2" dmesg -c fi while :; do # Wait for 60 seconds sleep 60 ior_root2=`awk -v disk="${rootDisk}" '{if ($3==disk) print $6}' /proc/diskstats` iow_root2=`awk -v disk="${rootDisk}" '{if ($3==disk) print $10}' /proc/diskstats` ior_datavol2=`awk -v disk="${dataVolumeDisk}" '{if ($3==disk) print $6}' /proc/diskstats` iow_datavol2=`awk -v disk="${dataVolumeDisk}" '{if ($3==disk) print $10}' /proc/diskstats` # use data volume writes until near sleep threshold, then check all disk writes old_sleepcount=sleepcount if [ $((sleepcount)) -eq $((rootdisk_thresh)) ] && [ "$ior_root" -eq "$ior_root2" ] && [ "$iow_root" -eq "$iow_root2" ]; then sleepcount=$((sleepcount+1)) elif [ $((sleepcount)) -lt $((rootdisk_thresh)) ] && [ "$ior_datavol" -eq "$ior_datavol2" ] && [ "$iow_datavol" -eq "$iow_datavol2" ]; then sleepcount=$((sleepcount+1)) else resetSleepCount fi echo $sleepcount > ${MIN_SINCE_DISK_ACCESS} if [ "$1" == "debug" ]; then [ "$sleepcount" != "0" ] && echo "sleepcount: $sleepcount" [ "$sleepcount" == "0" ] && echo "Disk activity:" echo "... ior_datavol=$ior_datavol ior_datavol2=$ior_datavol2" echo "... iow_datavol=$iow_datavol iow_datavol2=$iow_datavol2" echo "... ior_root=$ior_root ior_root2=$ior_root2" echo "... iow_root=$iow_root iow_root2=$iow_root2" # dmesg -c fi ior_datavol=$ior_datavol2 iow_datavol=$iow_datavol2 ior_root=$ior_root2 iow_root=$iow_root2 if [ "$standby_enable" == "enabled" ] && [ "$sleepcount" -eq "$standby_time" ] ; then touch /tmp/standby enterStandbyTime=`date +%s` echo "Enter standby" if [ "$1" == "debug" ]; then echo "`date`: Enter standby " dmesg -c > /dev/null fi for i in ${drivelist[@]}; do hdparm -y $i >/dev/null done # Turn off LED echo 0 > /sys/class/leds/led/brightness sleep 5 break fi done fi done
The script requires an additional config file:
# /usr/local/etc/standby.conf standby_enable=enabled standby_time=17
Of course putting the disk to sleep only makes sense if regular write operations don't go to disk but to RAM. After having used a custom RamLog script before, folder2ram
is the preferred solution I now use. My folder2ram.conf looks like this:
#<type> <mount point> <options>
tmpfs /var/log
tmpfs /var/tmp
tmpfs /var/spool
tmpfs /var/cache/samba
tmpfs /var/lib/smartmontools
tmpfs /var/lib/systemd
tmpfs /var/lib/samba
tmpfs /var/lib/dhcp
For Debian Bullseye make sure to remove the /var/log/journal folder!
Cool. What do you use it for?
AntwortenLöschenAs I understand, you can set the brightness to XX%
Does that mean it will permanently emit light at XX%?
Or can it be made to show what is going on in the system. Like when the HD is busy? Or flash when errors occur?
Could it be made flashing when someone tries to log in via SSH?
There is some LED trigger drivers:
Löschen* heartbeat
* transient
* oneshot
* timer
Neither the network driver nor the SATA driver support trigger actions. That means you'll have to write your own userspace program to manage the LED.
All I wanted to do is turn it off in order to save some power :D
I updated the post to demonstrate how the LED can be turned on/off by the monitorio script.
LöschenHello :)
AntwortenLöschenIt seems that i dont have the "/sys/class/leds/led/brightness" mine stops at "/sys/class/leds/" where did i go wrong ?
ty in advance
This is actually what the DTB change is supposed to do. Did you install the modified one from above?
LöschenSee "Installing the Kernel" here https://blog.loetzimmer.de/2021/01/debian-on-wd-my-cloud-home-single-bay.html
how to make the script run on boot ?
AntwortenLöschenIf you don't want to create a SystemD unit file for it
Löschen#/etc/systemd/system/monitorio.service
[Unit]
Description=Disk Sleep Daemon
After=local-fs.target
[Service]
ExecStart=/usr/local/sbin/monitorio.sh
ExecStop=/usr/bin/killall monitorio.sh
[Install]
WantedBy=multi-user.target
you could put it in /etc/rc.local