Add an optional compiled disk activities monitor to reduce the CPU usage (#38)
Some checks are pending
Build kernel module for TrueNAS / build-and-run (push) Waiting to run

This commit is contained in:
Yuhao Zhou
2024-10-31 18:24:48 +08:00
committed by GitHub
parent af8680ce95
commit b49da0d890
4 changed files with 113 additions and 14 deletions

View File

@@ -211,6 +211,15 @@ Please see `scripts/ugreen-leds.conf` for an example.
systemctl enable ugreen-diskiomon systemctl enable ugreen-diskiomon
``` ```
- (_Optional_) To reduce the CPU usage of blinking LEDs when disks are active, you can enter the `scripts` directory and do the following things:
```bash
# compile the disk activities monitor
g++ -std=c++17 -O2 blink-disk.cpp -o ugreen-blink-disk
# copy the binary file (the path can be changed, see BLINK_MON_PATH in ugreen-leds.conf)
cp ugreen-blink-disk /usr/bin
```
## Disk Mapping ## 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. 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.

73
scripts/blink-disk.cpp Normal file
View File

@@ -0,0 +1,73 @@
#include <fstream>
#include <thread>
#include <vector>
#include <iostream>
#include <string>
#include <chrono>
int main(int argc, char *argv[]) {
if (argc < 4 || argc % 2 != 0) {
std::cerr << "Usage: " << argv[0] << " <sleep time (in second)>"
<< " <block device 1> <led device 1> <block device 2> <led device 2>...\n";
return 1;
}
int num_devices = (argc - 2) / 2;
int sleep_time_ms = int(std::stod(argv[1]) * 1000);
std::vector<std::string> block_device_stat_paths;
std::vector<std::string> led_device_shot_paths;
for (int i = 0; i < num_devices; i++) {
std::string block_device = argv[2 + 2 * i];
std::string led_device = argv[3 + 2 * i];
block_device_stat_paths.push_back(
"/sys/block/" + block_device + "/stat");
led_device_shot_paths.push_back(
"/sys/class/leds/" + led_device + "/shot");
}
std::vector<bool> device_status(num_devices, true);
std::vector<std::string> old_lines(num_devices);
while (true) {
for (int i = 0; i < num_devices; i++) {
if (!device_status[i]) {
continue;
}
std::ifstream stat_file(block_device_stat_paths[i]);
if (!stat_file.is_open()) {
std::cerr << "Failed to open " << block_device_stat_paths[i] << "\n";
device_status[i] = false;
continue;
}
std::string line;
std::getline(stat_file, line);
stat_file.close();
if (line != old_lines[i]) {
std::ofstream led_file(led_device_shot_paths[i]);
if (!led_file.is_open()) {
std::cerr << "Failed to open " << led_device_shot_paths[i] << "\n";
device_status[i] = false;
continue;
}
led_file << "1";
led_file.close();
old_lines[i] = std::move(line);
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time_ms));
}
return 0;
}

View File

@@ -228,7 +228,7 @@ if [ "$CHECK_ZPOOL" = true ]; then
if [[ "${zpool_dev_state}" != "ONLINE" ]]; then if [[ "${zpool_dev_state}" != "ONLINE" ]]; then
echo "$COLOR_ZPOOL_FAIL" > /sys/class/leds/$led/color echo "$COLOR_ZPOOL_FAIL" > /sys/class/leds/$led/color
echo Disk failure detected on /dev/$dev at $(date +%Y-%m-%d' '%H:%M:%S) echo Disk failure detected on /dev/$zpool_dev_name at $(date +%Y-%m-%d' '%H:%M:%S)
fi fi
# ==== To recover from an error, you should restart the script ==== # ==== To recover from an error, you should restart the script ====
@@ -316,6 +316,19 @@ fi
disk_online_check_pid=$! disk_online_check_pid=$!
# monitor disk activities # monitor disk activities
BLINK_MON_PATH=${BLINK_MON_PATH:=/usr/bin/ugreen-blink-disk}
if [ -f "${BLINK_MON_PATH}" ]; then
diskiomon_parameters() {
echo ${LED_REFRESH_INTERVAL}
for led in "${!devices[@]}"; do
echo ${devices[$led]} $led
done
}
${BLINK_MON_PATH} $(diskiomon_parameters)
else
declare -A diskio_data_rw declare -A diskio_data_rw
while true; do while true; do
for led in "${!devices[@]}"; do for led in "${!devices[@]}"; do
@@ -333,3 +346,4 @@ while true; do
sleep ${LED_REFRESH_INTERVAL}s sleep ${LED_REFRESH_INTERVAL}s
done done
fi

View File

@@ -20,6 +20,9 @@
# and fill the DISK_SERIAL array below (see the comments therein). # and fill the DISK_SERIAL array below (see the comments therein).
MAPPING_METHOD=ata MAPPING_METHOD=ata
# The path of the compiled diskio monitor (OPTIONAL)
BLINK_MON_PATH=/usr/bin/ugreen-blink-disk
# The serial numbers of disks (used only when MAPPING_METHOD=serial) # 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. # 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, # If you have 4 disks, with serial numbers: SN1 SN2 SN3 SN4,