Debian Linux on the My Cloud PR4100 / PR2100

The {0:d} is just to format the first argument as a digit, see below.

_CORETEMP_FILENAME_BASE = "/sys/class/hwmon/hwmon0/temp{0:d}_{1}"
_CORETEMP_CORE_OFFSET = 2
...
 file_name = _CORETEMP_FILENAME_BASE.format(_CORETEMP_CORE_OFFSET + cpu_index,
                                               value_type)

Indeed, you need to use hwmon1. I see I had disabled CPU temperature monitoring in my setup and just relied on the other sensors. Sorry about that.

I’m now running the non-root systemd config and this diff

root@ptr-eiwxtdwig27a15tzjnm:/usr/local/lib/wdhwd# git diff
diff --git a/wdhwlib/fancontroller.py b/wdhwlib/fancontroller.py
index 896c3e5..7e27aef 100644
--- a/wdhwlib/fancontroller.py
+++ b/wdhwlib/fancontroller.py
@@ -615,6 +615,7 @@ class FanController(FanControllerCallback):
                         level = monitor.level
                         if level is not None:
                             if global_level < level:
+                                _logger.info("ZZZ %s got temp %s lvl %s", monitor._log_name, monitor.temperature, level)
                                 global_level = level
                     
                     fan_speed_change = False
diff --git a/wdhwlib/temperature.py b/wdhwlib/temperature.py
index 9a5d49f..a81b2aa 100644
--- a/wdhwlib/temperature.py
+++ b/wdhwlib/temperature.py
@@ -35,7 +35,7 @@ _logger = logging.getLogger(__name__)
 _CPUINFO_FILENAME = "/proc/cpuinfo"
 _CPUINFO_REGEX_CORES = re.compile(r"^cpu\s+cores.*:\s*([0-9]+)\s*$")
 
-_CORETEMP_FILENAME_BASE = "/sys/class/hwmon/hwmon0/temp{0:d}_{1}"
+_CORETEMP_FILENAME_BASE = "/sys/class/hwmon/hwmon1/temp{0:d}_{1}"
 _CORETEMP_CORE_OFFSET = 2
 _CORETEMP_TYPE_JUNCTION_VALUE = "input"
 _CORETEMP_TYPE_JUNCTION_REGULAR_MAX = "max"
@@ -56,7 +56,7 @@ _SMBUS_MEMORY_SPD_TEMP_ADDRESS = 0x18
 _SMBUS_MEMORY_SPD_TEMP_REG_TEMPERATURE = 5
 
 _HDSMART_COMMAND_BASE = ["/usr/bin/sudo", "-n", "/usr/sbin/hddtemp", "-n", "-u", "C"]
-HDSMART_DISKS = ["/dev/sda", "/dev/sdb"]
+HDSMART_DISKS = ["/dev/sda", "/dev/sdb", "/dev/sdc", "/dev/sdd"]
 _HDSMART_REGEX_TEMPERATURE = re.compile(r"^([0-9]+)[^0-9]*$")

To run the daemon manually, go to the /usr/local/lib/wdhwd directory (or wherever you installed the repo) first.

/usr/local/lib/wdhwd# ls
LICENSE  messagequeue  README.md  scripts  threadedserial  threadedsockets  tlv	tools  wdhwdaemon  wdhwlib
/usr/local/lib/wdhwd# sudo python3 -m wdhwdaemon.daemon

In a separate window check the logs

tailf /var/log/wdhwd/daemon.log

Ok, i changed the stuff back, set the hwmon to 1 and started the deamon by hand with the result:

christian@unassigned-hostname:/usr/local/lib/wdhwd$ sudo python3 -m wdhwdaemon.daemon
2018-07-30 13:39:51,747 - __main__ - ERROR - WdHwDaemon: Daemon failed with PMCCommandRejectedException: ; exiting
Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/local/lib/wdhwd/wdhwdaemon/daemon.py", line 915, in <module>
    ret = d.main(sys.argv)
  File "/usr/local/lib/wdhwd/wdhwdaemon/daemon.py", line 802, in main
    pmc_version = pmc.getVersion()
  File "/usr/local/lib/wdhwd/wdhwlib/wdpmcprotocol.py", line 428, in getVersion
    return self.__processor.transceiveCommand(_PMC_COMMAND_VERSION)
  File "/usr/local/lib/wdhwd/wdhwlib/wdpmcprotocol.py", line 351, in transceiveCommand
    raise PMCCommandRejectedException()
wdhwlib.wdpmcprotocol.PMCCommandRejectedException

And i didnt understood this. i just cloned the files from github, copied to an usb drive and copied to my debian home folder on the nas. the last change/fix was von july 14th - this is what i can see in github.

The daemon starts with a sanity check on the PMC.
It seems like the uart communication is not working yet.
Are you able to run this?

sudo python3
import serial
s = serial.Serial('/dev/ttyS2')
s.write(b'STA\r')     # edit: used to be r'STA\r' ... but it should be bytes, not a regex
s.readline()

And what do you get for this?

sudo stty -g -F /dev/ttyS2                                                                              :(
0:0:cbd:0:3:1c:7f:15:4:0:0:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

Regarding git, the version from july is fine.

here the result

>>> s.write(r'STA\r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 518, in write
    d = to_bytes(data)
  File "/usr/lib/python3/dist-packages/serial/serialutil.py", line 63, in to_bytes
    raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
TypeError: unicode strings are not supported, please encode to bytes: 'STA\\r'
>>> s.readline()

s.readline() is not responding.
after ctrl+D

>>> s.readline()
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 472, in read
    ready, _, _ = select.select([self.fd, self.pipe_abort_read_r], [], [], timeout.time_left())
KeyboardInterrupt
>>> 

for

sudo stty -g -F /dev/ttyS2   

the output is the same

0:0:cbd:0:3:1c:7f:15:4:0:0:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

EDIT:
if i put .encode() to the command

>>> s.write(r'STA\r'.encode())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 's' is not defined

oh sorry. I meant b'STA\r'
Oneliner

sudo python3 -c 'import serial; s=serial.Serial("/dev/ttyS2"); s.write(b"STA\r\r"); print(s.readline())'

ok, interesting.
after running the command (even with r instead of b) with the .encode() the daemon is now starting probably.
till now the two shutdown calls are disabled.
i will activate the systemd service again, restart, see if its working and afterwards uncomment the two shutdown calls

EDIT:

result:

christian@unassigned-hostname:~$ sudo python3 -c 'import serial; s=serial.Serial("/dev/ttyS2"); s.write(b"STA\r\r"); print(s.readline())'
b'STA=6c\n'

That looks good. The daemon should work now. You can also query the version (VER) instead of the status (STA). Sometimes the serial connection gets a bit messed up during the debugging and querying the status usually helps. Just make sure you clear the buffer (readline). On a healthy normal boot, everything should be fine, but sending an empty '\r' can always help.

ExecStartPre=/bin/echo -ne 'LN1=Look hot\r' > /dev/ttyS2
ExecStartPre=/bin/echo -ne 'LN2=Stay cool\r' > /dev/ttyS2

i took this two lines from your wdhwd.service file right after you posted your files into my file (and everything else as well)

after two painfull days it is really working now.

thank you so much for your help !!

No problem. Enjoy the box now that it’s fully powered!
I’ll try to update the holes in my guide the coming days with the info we gathered.

My setup is now the PR2100 with 2x 3TB WD RED inside, on sda 32GB for Debian, 10GB swap, and a ~6TB software RAID0 made with mdadm.

using the UART Port is very very helpful

If you’ve got WD reds, you can’t use hdparm to manage disk spindown.
This blog post explains how to setup hd-idle

Thanks a lot!

Thank you so much for sharing this! I bought a PR4100 because of your post.

I’m super impressed at how you figured all of this out. I’ve been trying to replicate your results with Ubuntu for the last few hours and failing.

Has anyone done this with Ubuntu? It’s not a big deal but I have a slight preference for it over Debian because it comes with ZFS binaries.

BTW I installed a SSD in the first bay for boot using this 2.5" drive adapter: Amazon.com

You didn’t say where it fails… what have you done so far?
Preseed config should be the same, so what is the output of

lspci -k -s 00:1e
ls -l /sys/class/tty/*/device/driver
sudo dmesg | grep tty

I’m using zfs on debian with the kernel headers as above and then

apt-get install zfs-dkms zfsutils-linux

I tried using http://archive.ubuntu.com/ubuntu/dists/bionic-updates/main/installer-amd64/current/images/netboot/mini.iso in place of …/debian-cd/current/amd64/iso-cd/debian-9.2.1-amd64-netinst.iso. SSH never came up and I don’t have a UART port cable to diagnose why.

I did install Debian successfully with ZFS, thank you. I found this guide to be helpful: apt - Install zfs on debian 9 stretch - Unix & Linux Stack Exchange

From https://help.ubuntu.com/community/Installation/MinimalCD

mini system in UEFI mode
While the minimal iso image is handy, it isn’t useful for installing on UEFI-based systems that you want to run in UEFI mode. The mini iso lacks the proper files for booting the computer in UEFI mode. Thus, the computer will boot in BIOS compatibility mode, and the installation will be in BIOS mode.

I’d use the ubuntu server iso.

Thanks for your hints. Encouraged, I gave it another go with Ubuntu. I tried testing it first on another Linux machine I just acquired so I could see what I was doing.

Big mistake. I wasted hours and regret it. Ubuntu has TWO server installers. The default is http://releases.ubuntu.com/18.04.1/ubuntu-18.04.1-live-server-amd64.iso which doesn’t appear to work with preseeding but there’s no good documentation explaining that or why.

The other, http://cdimage.ubuntu.com/ubuntu/releases/18.04/release/ubuntu-18.04.1-server-amd64.iso, supposedly does but fails with the error “Your installation CD-ROM couldn’t be mounted.” This is a bug that’s been known for years and requires manual intervention to pass.

Both images are available via HTTP only, no SSL! This is 2018! Shame on you, Ubuntu!

Conclusion: Ubuntu installers are a giant mess and I’m sticking with Debian.

@dswv42 You may want to remove the nomodeset kernel parameter from the GRUB config.
This prevents the i915 intel video driver getting loaded, required for vaapi HW video transcoding.
Thanks reference

I removed it from /etc/default/grub default params and then did

# sudo update-grub
# sudo reboot
...
# ls -l /dev/dri/renderD128
# vainfo      
error: XDG_RUNTIME_DIR not set in the environment.
error: can't connect to X server!
libva info: VA-API version 0.39.4
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.39 (libva 1.7.3)
vainfo: Driver version: Intel i965 driver for Intel(R) CherryView - 1.7.3
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            :	VAEntrypointVLD
      VAProfileMPEG2Simple            :	VAEntrypointEncSlice
      VAProfileMPEG2Main              :	VAEntrypointVLD
      VAProfileMPEG2Main              :	VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline:	VAEntrypointVLD
      VAProfileH264ConstrainedBaseline:	VAEntrypointEncSlice
      VAProfileH264Main               :	VAEntrypointVLD
      VAProfileH264Main               :	VAEntrypointEncSlice
      VAProfileH264High               :	VAEntrypointVLD
      VAProfileH264High               :	VAEntrypointEncSlice
      VAProfileH264MultiviewHigh      :	VAEntrypointVLD
      VAProfileH264MultiviewHigh      :	VAEntrypointEncSlice
      VAProfileH264StereoHigh         :	VAEntrypointVLD
      VAProfileH264StereoHigh         :	VAEntrypointEncSlice
      VAProfileVC1Simple              :	VAEntrypointVLD
      VAProfileVC1Main                :	VAEntrypointVLD
      VAProfileVC1Advanced            :	VAEntrypointVLD
      VAProfileNone                   :	VAEntrypointVideoProc
      VAProfileJPEGBaseline           :	VAEntrypointVLD
      VAProfileJPEGBaseline           :	VAEntrypointEncPicture
      VAProfileVP8Version0_3          :	VAEntrypointVLD
      VAProfileVP8Version0_3          :	VAEntrypointEncSlice
      VAProfileHEVCMain               :	VAEntrypointVLD

E.g. Emby media server can now use it

ps fax | grep vaapi
 2706 ?        Sl     0:15  \_ /opt/emby-server/bin/ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 -i file:/MM/Trailers/SomeMovie.mkv -threads 0 -map 0:0 -map 0:1 -map -0:s -codec:v:0 h264_vaapi -vf format=nv12|vaapi,hwupload,scale_vaapi=w=1280:h=692 -b:v 3680000 -maxrate 3680000 -bufsize 7360000 -profile:v 578 -level 41 -force_key_frames expr:if(isnan(prev_forced_t),eq(t,t),gte(t,prev_forced_t+3)) -copyts -vsync -1 -codec:a:0 libmp3lame -ac 2 -ab 320000 -f segment -max_delay 5000000 -avoid_negative_ts disabled -map_metadata -1 -map_chapters -1 -start_at_zero -segment_time 3 -individual_header_trailer 0 -segment_format mpegts -segment_list_type m3u8 -segment_start_number 0 -segment_list /var/lib/emby/transcoding-temp/74f5332ba1271fcece2c3cba79a6d129.m3u8 -y /var/lib/emby/transcoding-temp/74f5332ba1271fcece2c3cba79a6d129%d.ts
1 Like

Here’s how to get hardware control with much less effort / time by building an in-tree kernel module.

Install the 4.9 kernel, headers and source. At the moment this is a meta package for linux-image-4.9.0-8, or the 4.9.110-3 kernel. This may bump in the future

sudo apt install linux-image-amd64 linux-headers-$(uname -r) linux-source \
  gcc make libc6-dev binutils-dev bc

Verify that the current kernel is 4.9.0-8-amd64 with uname -r
If it isn’t, update the grub bootloader to select the correct menuentry by setting the grub default.

Prepare kernel build directory and extract the source

mkdir ~/kbuild && cd ~/kbuild
tar xf /usr/src/linux-source-4.9.tar.xz
cd linux-source-4.9

Get the module symvers from the headers. This file is generated when you build the full kernel, so we save a few hours by skipping this.

cp /usr/src/linux-headers-$(uname -r)/Module.symvers .

Get the corresponding kernel config

cp /boot/config-$(uname -r) .config

Verify if the kernel source version matches the current version.

uname -r
make kernelversion

If these previous commands did not match, edit the first lines of the Makefile like this. (thanks @neversaydie)

SUBLEVEL = 0
EXTRAVERSION = -8-amd64

Enable the Intel LPSS UART driver in the kernel config.

Directly with an editor

Enable these 2 parameters in the .config in your favorite editor

CONFIG_SERIAL_8250_LPSS=m
CONFIG_DW_DMAC_PCI=m

Note that these parameters may change in future kernels.

or select it in the menu
sudo apt install libncurses5-dev
make nconfig

Enable support as a module.

   -> Device Drivers
     -> Character devices
       -> Serial drivers
        -> <M> Support for serial ports on Intel LPSS platforms. 

Save and exit.

Now compile the module

make prepare
make modules_prepare
make M=scripts/mod
make M=drivers/tty/serial

And install it

sudo make M=drivers/tty/serial modules_install
sudo depmod
sudo modprobe 8250_lpss

Verify it’s active

lsmod | grep 8250_lpss

This lighter module is easier to keep in sync with the mainline kernel.
All that’s left is to put all this in a post-install script.

1 Like

I’d suggest a 4GB image file with OMV already installed and just inflate the partitions on first boot.
Then the user only needs to update OMV to the latest version and change the password.
The image can be installed on a disk but I’d recommend to run it from a USB drive.