DeskPi ProのSATA SSDでTrimを設定する

DeskPi ProのSATAはUSB接続となっていてSSDを接続しても、Trimを実行することができない。これはLinux側の問題で、USB接続のSSDでのTrimをサポートしていないかららしい。設定を変えることで、USB接続でもTrimができるのでそれを実行する。

forums.raspberrypi.com

SSDがTrimに対応しているかコマンドで確認

ubuntu@ubuntu:~$ sudo hdparm -I /dev/sda | grep TRIM
       *    Data Set Management TRIM supported (limit 8 blocks)

ラズパイにつないでいるSSDは、CSSD-S6B480CG3VXというものでTrimには対応している。 USB接続だとTrimできるSSDでも、zpool status -t やfstrimでTrimできないと表示される。

ubuntu@ubuntu:~$ zpool status -t
  pool: pool01
 state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    pool01      ONLINE       0     0     0
      sda4      ONLINE       0     0     0  (trim unsupported)

errors: No known data errors
ubuntu@ubuntu:~$ sudo fstrim -v /
fstrim: /: the discard operation is not supported

ベンダーIDとプロダクトIDを確認

ubuntu@ubuntu:~$ lsusb -tv
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        ID 1a40:0101 Terminus Technology Inc. Hub
        |__ Port 4: Dev 3, If 0, Class=Vendor Specific Class, Driver=ch341, 12M
            ID 1a86:7523 QinHeng Electronics CH340 serial converter
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=uas, 5000M
        ID 174c:55aa ASMedia Technology Inc. ASM1051E SATA 6Gb/s bridge, ASM1053E SATA 6Gb/s bridge, ASM1153 SATA 3Gb/s bridge, ASM1153E SATA 6Gb/s bridge
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        ID 2109:3431 VIA Labs, Inc. Hub

Bus02 Port1 Dev2のASMediaがUSB⇔SATA変換のチップ ID 1a86:7523の左がベンダーIDで右がプロダクトID

/etc/udev/rules.d/にルールファイルを追加する

ubuntu@ubuntu:~$ sudo vi /etc/udev/rules.d/99-usbssd-trim.rules
ACTION=="add|change", ATTRS{idVendor}=="1a86, ATTRS{idProduct}=="7523", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"

再起動してTrimを実行する

再起動してもTrimが有効にならない

設定前とコマンドの結果が変わらない

ubuntu@ubuntu:~$ zpool status -t
  pool: pool01
 state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    pool01      ONLINE       0     0     0
      sda4      ONLINE       0     0     0  (trim unsupported)

errors: No known data errors
ubuntu@ubuntu:~$ sudo fstrim -v /
fstrim: /: the discard operation is not supported

原因と対処

/sys/block/sda/device/scsi_disk/0:0:0:0/provisioning_modeの値がunmapになっていない

ubuntu@ubuntu:~$ cat /sys/block/sda/device/scsi_disk/0:0:0:0/provisioning_mode
full

/etc/rc.localに以下を追記して、起動時にunmapに変更するようにする

ubuntu@ubuntu:~$ sudo vi /etc/rc.local
#!/bin/sh
echo -n unmap > /sys/block/sda/device/scsi_disk/0:0:0:0/provisioning_mode

ubuntu@ubuntu:~$ sudo chmod 755 /etc/rc.local 

再確認

これでfstrimはできるようになったが、zpool trimはできない

ubuntu@ubuntu:~$ sudo fstrim -v /
/: 27.4 GiB (29468852224 bytes) trimmed

ubuntu@ubuntu:~$ zpool status -t
  pool: pool01
 state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    pool01      ONLINE       0     0     0
      sda4      ONLINE       0     0     0  (trim unsupported)

errors: No known data errors

原因と対処

udev ruleより先にzfsのモジュールがロードされることが原因 www.reddit.com

リンクにあるスクリプトを/usr/share/initramfs-tools/hooks/において権限をつける

Detect and enable trim for usb-connected sata/nvme drives in initramfs/initrd, ideally before zfs modules load. · GitHub

ubuntu@ubuntu:~$ sudo chmod 755 /usr/share/initramfs-tools/hooks/usbtrim 

スクリプトを配置したらinitramfsを更新する オプションはuckを選択

root@ubuntu:~# update-initramfs --help

Usage: update-initramfs {-c|-d|-u} [-k version] [-v] [-b directory]

Options:
 -k version Specify kernel version or 'all'
 -c     Create a new initramfs
 -u     Update an existing initramfs
 -d     Remove an existing initramfs
 -b directory   Set alternate boot directory
 -v     Be verbose

See update-initramfs(8) for further details.

root@ubuntu:~# update-initramfs -u -c -k `uname -r`

終わったら再起動

 再確認

Trimできるようになっている

ubuntu@ubuntu:~$ zpool status -t
  pool: pool01
 state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    pool01      ONLINE       0     0     0
      sda4      ONLINE       0     0     0  (untrimmed)

errors: No known data errors

実際にTrimしてみる

ubuntu@ubuntu:~$ sudo fstrim -v /
/: 27.4 GiB (29443108864 bytes) trimmed
ubuntu@ubuntu:/pool01$ sudo zpool trim pool01 sda4
ubuntu@ubuntu:/pool01$ zpool status -t
  pool: pool01
 state: ONLINE
config:

    NAME        STATE     READ WRITE CKSUM
    pool01      ONLINE       0     0     0
      sda4      ONLINE       0     0     0  (100% trimmed, completed at Sat Apr  2 00:19:37 2022)

errors: No known data errors