Open velocithrills21 opened 4 months ago
Not surprised that the RPM doesn't work. I haven't updated it (or the docs) for quite a while. I'll try to provide an overview of what you'll need to do.
First you'll need an updated version of freecusd
, directly from the repo.
$ git clone https://github.com/ipilcher/n5550
Cloning into 'n5550'...
remote: Enumerating objects: 828, done.
remote: Counting objects: 100% (239/239), done.
remote: Compressing objects: 100% (150/150), done.
remote: Total 828 (delta 151), reused 170 (delta 88), pack-reused 589
Receiving objects: 100% (828/828), 229.89 KiB | 1.96 MiB/s, done.
Resolving deltas: 100% (561/561), done.
$ cd n5550/freecusd
$ gcc -Os -Wall -Wextra -pthread -o freecusd *.c -lcip
Then build the S.M.A.R.T. helper.
$ gcc -Os -Wall -Wextra -pthread -o freecusd-smart-helper smart/helper.c -latasmart
Install the freecusd
binary in /usr/local/bin
; install freecusd-smart-helper
in /usr/local/libexec
.
Create /etc/freecusd.conf
, based on the freecusd/freecusd.conf
template in the repo.
Then you'll need a systemd
unit file for the service (in /etc/systemd/system/freecusd.service
).
[Unit]
Description=Thecus N5550 NAS monitoring daemon
[Service]
Type=simple
ExecStart=/usr/local/bin/freecusd -s -d
[Install]
WantedBy=multi-user.target
That gets you the monitoring service, but you'll still need to get the kernel modules built (and rebuilt for every kernel update) and loaded & configured on every boot.
You'll need 2 kernel modules.
n5550_board
- Latest source and makefile are at https://github.com/ipilcher/n5550-v2/tree/main/n5550_board.ledtrig-blkdev
- Latest source is at https://github.com/ipilcher/ledtrig-blkdev/blob/v6.9%2B/drivers/leds/trigger/ledtrig-blkdev.c. You'll need to select the correct branch for your kernel version; Fedora 39 is currently on kernel 6.8, so you'll want the trigger module from the v6.8+
branch. Makefile is at https://github.com/ipilcher/n5550-v2/blob/main/ledtrig-blkdev/Makefile.Put the ledtrig-blkdev
and n5550_board
module source files and makefiles in /usr/src/n5550/ledtrig-blkdev
and /usr/src/n5550/n5550_board
respectively.
I use a dracut
module to automatically rebuild the modules every time a new kernel is installed. Create /usr/local/lib/dracut/modules.d/99n5550/module-setup.sh
with the following contents.
#!/bin/bash
n5550_do_module() {
local MODULE=$1
[ -e $srcmods/n5550/$MODULE.ko ] && return
pushd $(mktemp --directory)
cp /usr/src/n5550/$MODULE/{$MODULE.c,Makefile} .
make KERNEL=$kernel || return 1
strip --strip-debug $MODULE.ko
mkdir -p $srcmods/n5550
cp $MODULE.ko $srcmods/n5550/
popd
}
check() {
n5550_do_module ledtrig-blkdev || return 1
n5550_do_module n5550_board || return 1
depmod -A $kernel
return 0
}
installkernel() {
hostonly='' instmods n5550_board ledtrig-blkdev
}
Create a symbolic link, so that dracut
can find the module.
# ln -s /usr/local/lib/dracut/modules.d/99n5550 /usr/lib/dracut/modules.d/99n5550
You'll need some udev
rules and a helper script to "link" the LEDs to the correct disks and create create stable paths for the hardware sensors (coretemp
and it87
) and the PCA9532 GPIO chip.
/etc/udev/rules.d/99-n5550.rules
:
# Create a stable path (/run/n5550/coretemp) to the coretemp module's monitoring attributes
ACTION=="add", SUBSYSTEM=="hwmon", ATTR{name}=="coretemp", RUN{program}+="/bin/sh -c 'mkdir -p /run/n5550 && ln -s /sys$devpath /run/n5550/coretemp'"
# Do the same for the it87 module (/run/n5550/it87) and also set the system fan speed - rule for newer kernels
ACTION=="add", SUBSYSTEM=="hwmon", ATTR{name}=="it8728", ATTR{pwm3_enable}="1", ATTR{pwm3}="255", RUN{program}+="/bin/sh -c 'mkdir -p /run/n5550 && ln -s /sys$devpath /run/n5550/it87'"
# Older kernels put the it87 module's attributes under the platform device, not the hwmon device
ACTION=="add", SUBSYSTEM=="platform", DRIVER=="it87", ATTR{name}=="it8728", ATTR{pwm3_enable}="1", ATTR{pwm3}="255", RUN{program}+="/bin/sh -c 'mkdir -p /run/n5550 && ln -s /sys$devpath /run/n5550/it87'"
# Link the data disks to the LED triggers (if necessary)
ACTION=="add", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", DRIVERS=="ahci", DEVPATH=="/devices/pci0000:00/0000:00:1f.2/ata*/host[1-5]/*", RUN{program}+="/usr/libexec/n5550-link-ledtrig $devpath $devnode"
# Stable path for the PCA9532 GPIO "chip"
ACTION=="add", SUBSYSTEM=="gpio", ATTRS{name}=="pca9532", SYMLINK+="gpio-pca9532"
/usr/libexec/n5550-link-ledtrig
:
#!/bin/sh
DEVPATH=$1
DEVNODE=$2
# Extract the AHCI controller port from the device path
PORT=${DEVPATH#/devices/pci0000:00/0000:00:1f.2/ata*/}
PORT=${PORT%%/*}
PORT=${PORT#host}
# Link the disk to the LED trigger, if present (host0 is the DOM, so subtract 1)
LED=/sys/class/leds/n5550:green:disk-act-$((PORT-1))
[ -e $LED/link_dev_by_path ] && echo $DEVNODE > $LED/link_dev_by_path
Make the helper script executable.
# chmod 0755 /usr/libexec/n5550-link-ledtrig
Create a dracut
configuration file to include some additional kernel modules and other files in the initial ramdisk and run the n5550
module that you created above.
/etc/dracut.conf.d/n5550.conf
:
install_items+=" /etc/udev/rules.d/99-n5550.rules /usr/libexec/n5550-link-ledtrig "
add_drivers+=" i2c_i801 leds_pca9532 leds_gpio gpio_ich lpc_ich libahci "
add_dracutmodules+=" n5550 "
Create a modprobe
configuration file.
/etc/modprobe.d/n5550.conf
:
options it87 fix_pwm_polarity=1
softdep n5550_board pre: lpc_ich i2c_i801 ledtrig-blkdev n5550_ahci_leds gpio_ich leds_pca9532 leds_gpio
Create a configuration for systemd-modules-load.service
.
/etc/modules-load.d/n5550.conf
:
it87
n5550_board
You should now be able to rebuild your initial ramdisk (usually just dracut -f
), whith will build the modules for your kernel and include all of the required kernel modules and other files. You can examine the contents of your initial ramdisk with the lsinitrd
command. If everything works, it should look something like this.
# lsinitrd | grep n5550
n5550
-rw-r--r-- 1 root root 138 Sep 3 2022 etc/modprobe.d/n5550.conf
-rw-r--r-- 1 root root 17 Sep 3 2022 etc/modules-load.d/n5550.conf
-rw-r--r-- 1 root root 1226 Dec 1 21:36 etc/udev/rules.d/99-n5550.rules
-rwxr-xr-x 1 root root 386 Aug 24 2022 usr/libexec/n5550-link-ledtrig
drwxr-xr-x 2 root root 0 Mar 19 19:00 usr/lib/modules/6.9.0-0.rc5.20240424git9d1ddab261f3.46.fc40.x86_64/n5550
-rw-r--r-- 1 root root 40480 Mar 19 19:00 usr/lib/modules/6.9.0-0.rc5.20240424git9d1ddab261f3.46.fc40.x86_64/n5550/ledtrig-blkdev.ko
-rw-r--r-- 1 root root 31744 Mar 19 19:00 usr/lib/modules/6.9.0-0.rc5.20240424git9d1ddab261f3.46.fc40.x86_64/n5550/n5550_board.ko
(The kernel version will be different.)
When you reboot, your green disk activity LEDs should work, and freecusd
should be able to start and display the NAS status on the built-in LCD.
That said, I've almost certainly forgotten something. Please give it a shot let me know if you run into any problems.
Sorry in advance if I'm missing something really simple here, but it looks like compile errors for both.
For the freecusd compile I get the following errors:
root@saruman:~/blinkylights/n5550/freecusd# gcc -Os -Wall -Wextra -pthread -o freecusd *.c -lcip
err.c: In function ‘fcd_err_txt’:
err.c:203:35: error: ‘sys_nerr’ undeclared (first use in this function)
203 | if (errno >= 0 && errno < sys_nerr)
| ^~~~
err.c:203:35: note: each undeclared identifier is reported only once for each function it appears in
err.c:204:36: error: ‘sys_errlist’ undeclared (first use in this function)
204 | return fcd_err_str(sys_errlist[errno]);
| ^~~
pic.c:20:10: fatal error: gpiod.h: No such file or directory
20 | #include ~~~~
compilation terminated.
For the kernel modules I followed all the steps provided but it looks like build is failing (I get the same error if I run "make" by hand on these):
root@saruman:/usr/local/lib/dracut/modules.d/99n5550# dracut -fv
dracut: Executing: /usr/bin/dracut -fv
dracut: dracut module 'systemd-networkd' will not be installed, because command 'networkctl' could not be found!
dracut: dracut module 'systemd-networkd' will not be installed, because command '/usr/lib/systemd/systemd-networkd' could not be found!
dracut: dracut module 'systemd-networkd' will not be installed, because command '/usr/lib/systemd/systemd-networkd-wait-online' could not be found!
dracut: dracut module 'busybox' will not be installed, because command 'busybox' could not be found!
dracut: dracut module 'dbus-daemon' will not be installed, because command 'dbus-daemon' could not be found!
dracut: dracut module 'rngd' will not be installed, because command 'rngd' could not be found!
dracut: dracut module 'connman' will not be installed, because command 'connmand' could not be found!
dracut: dracut module 'connman' will not be installed, because command 'connmanctl' could not be found!
dracut: dracut module 'connman' will not be installed, because command 'connmand-wait-online' could not be found!
dracut: dracut module 'network-wicked' will not be installed, because command 'wicked' could not be found!
dracut: dracut module 'dmraid' will not be installed, because command 'dmraid' could not be found!
dracut: dracut module 'nvmf' will not be installed, because command 'nvme' could not be found!
dracut: dracut module 'biosdevname' will not be installed, because command 'biosdevname' could not be found!
dracut: dracut module 'memstrack' will not be installed, because command 'memstrack' could not be found!
dracut: memstrack is not available
dracut: If you need to use rd.memdebug>=4, please install memstrack and procps-ng
/tmp/tmp.sS4KKggqA1 /usr/local/lib/dracut/modules.d/99n5550
make -C /lib/modules/6.8.7-200.fc39.x86_64/build M=/tmp/tmp.sS4KKggqA1 modules
make[1]: Entering directory '/usr/src/kernels/6.8.7-200.fc39.x86_64'
CC [M] /tmp/tmp.sS4KKggqA1/ledtrig-blkdev.o
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c: In function 'blkdev_trig_get_bdev_file':
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c:539:21: error: implicit declaration of function 'bdev_file_open_by_path'; did you mean 'bdev_open_by_path'? [-Werror=implicit-function-declaration]
539 | bdev_file = bdev_file_open_by_path(strim(buf), BLK_OPEN_READ,
| ^~~~~~
| bdev_open_by_path
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c:539:19: warning: assignment to 'struct file ' from 'int' makes pointer from integer without a cast [-Wint-conversion]
539 | bdev_file = bdev_file_open_by_path(strim(buf), BLK_OPEN_READ,
| ^
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c: In function 'blkdev_trig_get_btb':
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c:570:16: error: implicit declaration of function 'file_bdev' [-Werror=implicit-function-declaration]
570 | bdev = file_bdev(bdev_file);
| ^~~~~
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c:570:14: warning: assignment to 'struct block_device ' from 'int' makes pointer from integer without a cast [-Wint-conversion]
570 | bdev = file_bdev(bdev_file);
| ^
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c:607:9: error: implicit declaration of function 'fput'; did you mean 'iput'? [-Werror=implicit-function-declaration]
607 | fput(bdev_file);
| ^~~~
| iput
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c: In function 'unlink_dev_by_path_store':
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c:770:14: warning: assignment to 'struct block_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
770 | bdev = file_bdev(bdev_file);
| ^
cc1: some warnings being treated as errors
make[3]: [scripts/Makefile.build:243: /tmp/tmp.sS4KKggqA1/ledtrig-blkdev.o] Error 1
make[2]: [/usr/src/kernels/6.8.7-200.fc39.x86_64/Makefile:1939: /tmp/tmp.sS4KKggqA1] Error 2
make[1]: [Makefile:252: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/kernels/6.8.7-200.fc39.x86_64'
make: [Makefile:6: all] Error 2
dracut: dracut module 'n5550' cannot be found or installed.
Sorry for the delay in responding. Work travel has been crazy.
root@saruman:~/blinkylights/n5550/freecusd# gcc -Os -Wall -Wextra -pthread -o freecusd *.c -lcip
err.c: In function ‘fcd_err_txt’:
err.c:203:35: error: ‘sys_nerr’ undeclared (first use in this function)
203 | if (errno >= 0 && errno < sys_nerr)
| ^~~~~~~~
err.c:203:35: note: each undeclared identifier is reported only once for each function it appears in
err.c:204:36: error: ‘sys_errlist’ undeclared (first use in this function)
204 | return fcd_err_str(sys_errlist[errno]);
| ^~~~~~~~~~~
pic.c:20:10: fatal error: gpiod.h: No such file or directory
20 | #include <gpiod.h>
| ^~~~~~~~~
compilation terminated.
My bad. You need to add a definition to the gcc
command to tell it not to use those old symbols (sys_nerr
and sys_errlist
). So your command should be:
gcc -DFCD_NEW_OS -Os -Wall -Wextra -pthread -o freecusd *.c -lcip
As for the modules ...
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c: In function 'blkdev_trig_get_bdev_file':
/tmp/tmp.sS4KKggqA1/ledtrig-blkdev.c:539:21: error: implicit declaration of function 'bdev_file_open_by_path'; did you mean 'bdev_open_by_path'? [-Werror=implicit-function-declaration]
539 | bdev_file = bdev_file_open_by_path(strim(buf), BLK_OPEN_READ,
| ^~~~~~~~~~~~~~~~~~~~~~
| bdev_open_by_path
This (and the other errors) indicate that you're using the wrong version of the module for your kernel. It looks like you're using kernel 6.8.7, so you need the version of ledtrig-blkdev.c
from the v6.8+
branch of https://github.com/ipilcher/ledtrig-blkdev. Direct link here.
Hopefully this will get you going. Let me know how it goes!
Sorry for the long delay on my end. It appears this still results in errors:
gcc -DFCD_NEW_OS -Os -Wall -Wextra -pthread -o freecusd *.c -lcip
pic.c: In function ‘fcd_pic_reset’:
pic.c:101:29: error: variable ‘rc’ has initializer but incomplete type
101 | static const struct gpiod_line_request_config rc = {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
pic.c:102:18: error: ‘const struct gpiod_line_request_config’ has no member named ‘consumer’
102 | .consumer = "freecusd",
| ^~~~~~~~
pic.c:102:35: warning: excess elements in struct initializer
102 | .consumer = "freecusd",
| ^~~~~~~~~~
pic.c:102:35: note: (near initialization for ‘rc’)
pic.c:103:18: error: ‘const struct gpiod_line_request_config’ has no member named ‘request_type’
103 | .request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT
| ^~~~~~~~~~~~
pic.c:103:35: error: ‘GPIOD_LINE_REQUEST_DIRECTION_OUTPUT’ undeclared (first use in this function); did you mean ‘GPIOD_LINE_DIRECTION_OUTPUT’?
103 | .request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| GPIOD_LINE_DIRECTION_OUTPUT
pic.c:103:35: note: each undeclared identifier is reported only once for each function it appears in
pic.c:103:35: warning: excess elements in struct initializer
pic.c:103:35: note: (near initialization for ‘rc’)
pic.c:101:55: error: storage size of ‘rc’ isn’t known
101 | static const struct gpiod_line_request_config rc = {
| ^~
pic.c:111:21: error: implicit declaration of function ‘gpiod_chip_open_by_label’; did you mean ‘gpiod_chip_info_get_label’? [-Wimplicit-function-declaration]
111 | if ((chip = gpiod_chip_open_by_label("gpio-pca9532")) == NULL)
| ^~~~~~~~~~~~~~~~~~~~~~~~
| gpiod_chip_info_get_label
pic.c:111:19: error: assignment to ‘struct gpiod_chip *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
111 | if ((chip = gpiod_chip_open_by_label("gpio-pca9532")) == NULL)
| ^
pic.c:114:21: error: implicit declaration of function ‘gpiod_chip_get_line’; did you mean ‘gpiod_chip_get_info’? [-Wimplicit-function-declaration]
114 | if ((line = gpiod_chip_get_line(chip, 15)) == NULL)
| ^~~~~~~~~~~~~~~~~~~
| gpiod_chip_get_info
pic.c:114:19: error: assignment to ‘struct gpiod_line *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
114 | if ((line = gpiod_chip_get_line(chip, 15)) == NULL)
| ^
pic.c:117:13: error: implicit declaration of function ‘gpiod_line_request’; did you mean ‘gpiod_line_request_get_fd’? [-Wimplicit-function-declaration]
117 | if (gpiod_line_request(line, &rc, 0) != 0)
| ^~~~~~~~~~~~~~~~~~
| gpiod_line_request_get_fd
pic.c:120:13: error: implicit declaration of function ‘gpiod_line_set_value’; did you mean ‘gpiod_line_request_set_value’? [-Wimplicit-function-declaration]
120 | if (gpiod_line_set_value(line, 1) != 0)
| ^~~~~~~~~~~~~~~~~~~~
| gpiod_line_request_set_value
pic.c:146:9: error: implicit declaration of function ‘gpiod_line_release’; did you mean ‘gpiod_line_request_release’? [-Wimplicit-function-declaration]
146 | gpiod_line_release(line);
| ^~~~~~~~~~~~~~~~~~
| gpiod_line_request_release
pic.c:101:55: warning: unused variable ‘rc’ [-Wunused-variable]
101 | static const struct gpiod_line_request_config rc = {
|
I pulled in the latest version of ledtrig-blkdev.c but get this when attempting to compile the kernel modules:
# dracut -f
/tmp/tmp.q77rwUyajG /usr/local/lib/dracut/modules.d/99n5550
make -C /lib/modules/6.8.11-300.fc40.x86_64/build M=/tmp/tmp.q77rwUyajG modules
make[1]: Entering directory '/usr/src/kernels/6.8.11-300.fc40.x86_64'
CC [M] /tmp/tmp.q77rwUyajG/ledtrig-blkdev.o
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c: In function 'blkdev_trig_get_bdev_file':
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c:539:21: error: implicit declaration of function 'bdev_file_open_by_path'; did you mean 'bdev_open_by_path'? [-Wimplicit-function-declaration]
539 | bdev_file = bdev_file_open_by_path(strim(buf), BLK_OPEN_READ,
| ^~~~~~~~~~~~~~~~~~~~~~
| bdev_open_by_path
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c:539:19: error: assignment to 'struct file *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
539 | bdev_file = bdev_file_open_by_path(strim(buf), BLK_OPEN_READ,
| ^
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c: In function 'blkdev_trig_get_btb':
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c:570:16: error: implicit declaration of function 'file_bdev' [-Wimplicit-function-declaration]
570 | bdev = file_bdev(bdev_file);
| ^~~~~~~~~
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c:570:14: error: assignment to 'struct block_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
570 | bdev = file_bdev(bdev_file);
| ^
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c:607:9: error: implicit declaration of function 'fput'; did you mean 'iput'? [-Wimplicit-function-declaration]
607 | fput(bdev_file);
| ^~~~
| iput
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c: In function 'unlink_dev_by_path_store':
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c:770:14: error: assignment to 'struct block_device *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
770 | bdev = file_bdev(bdev_file);
| ^
make[3]: *** [scripts/Makefile.build:243: /tmp/tmp.q77rwUyajG/ledtrig-blkdev.o] Error 1
make[2]: *** [/usr/src/kernels/6.8.11-300.fc40.x86_64/Makefile:1939: /tmp/tmp.q77rwUyajG] Error 2
make[1]: *** [Makefile:252: __sub-make] Error 2
make[1]: Leaving directory '/usr/src/kernels/6.8.11-300.fc40.x86_64'
make: *** [Makefile:6: all] Error 2
dracut[E]: Module 'n5550' cannot be installed.
If this is proving to be too much of a rabbit hole I can probably cut my losses here. Especially if future Fedora releases and kernel versions are likely to break it.
No need to apologize for the delay. I'm equally guilty.
gcc -DFCD_NEW_OS -Os -Wall -Wextra -pthread -o freecusd *.c -lcip
pic.c: In function ‘fcd_pic_reset’:
pic.c:101:29: error: variable ‘rc’ has initializer but incomplete type
101 | static const struct gpiod_line_request_config rc = {
| ^~~~~~~~~~~~~~~~~~~~~~~~~
Looks like you might need to add another macro to your command line. Try gcc -DFCD_NEW_OS -DFCD_NEW_GPIOD -Os -Wall -Wextra -pthread -o freecusd *.c -lcip
.
/tmp/tmp.q77rwUyajG/ledtrig-blkdev.c:539:21: error: implicit declaration of function 'bdev_file_open_by_path'; did you mean 'bdev_open_by_path'? [-Wimplicit-function-declaration]
539 | bdev_file = bdev_file_open_by_path(strim(buf), BLK_OPEN_READ,
| ^~~~~~~~~~~~~~~~~~~~~~
| bdev_open_by_path
You're using the module source from the v6.9+ branch on a 6.8 kernel. You need the source from the v6.8+ branch (or you need to use a 6.9 kernel).
Let me know how it goes.
So I know that nowhere in the doc is it indicated this is meant to work on Fedora, but I figured I'd give it a shot. I was thrilled to find this and figured it was a longshot it would work, so if it's a relatively easy fix due to a new version of glibc or something (found similar errors posted online where others indicated this might be the case) I'd greatly appreciate any help you're willing to provide.
Thanks in advance
I worked my way through most of the steps in the quickstart guide, successfully compiled and installed libcip-devel version 0.1.1.6, but the n5500-0.6 rpmbuild fails on compilation of freecusd. Specifically it fails with an error when trying to manually fire the compile commands from the spec file:
Running rpmbuild command: