ahci-hd と zvol で運用すれば fstrim が効くことが分かった。 (ありがとう!)

以下は既に virtio-blk で動かしている centos7 を ahci-hd に変換する手順。

vm-centos7 # vim 下の二行を有効にする
add_drivers+="ahci" 
hstonly="no"

vm-centos7 # dracut -f

vm-centos7 # shutdown -P now

bhyve-host # ls -al zroot/vm/centos7_guest/disk0.img
-rw-------  1 root  wheel  32212254720  7月 17 16:56 /vm/centos7_guest/disk0.img (約30G)

bhyve-host # zfs create -sV 32212254720 zroot/vm/centos7_guest/disk0 (スパースにする場合 -s)

bhyve-host # time ddrescue --force /vm/centos7_guest/disk0.img /dev/zvol/zroot/vm/centos7_guest/disk0 (ddでもよいけど)
GNU ddrescue 1.24
Press Ctrl-C to interrupt
    ipos:   32212 MB, non-trimmed:        0 B,  current rate:    533 MB/s
    opos:   32212 MB, non-scraped:        0 B,  average rate:    657 MB/s
non-tried:        0 B,  bad-sector:        0 B,    error rate:       0 B/s
  rescued:   32212 MB,   bad areas:        0,        run time:         48s
pct rescued:  100.00%, read errors:        0,  remaining time:         n/a
                              time since last successful read:         n/a
Finished
ddrescue --force /vm/centos7_guest/disk0.img /dev/zvol/zroot/vm/centos7_guest/disk0  1.06s user 39.09s system 83% cpu 48.275 total

bhyve-host # vm configure centos7_guest (上の2行を下の3行に)
#disk0_type="virtio-blk"
#disk0_name="disk0.img"
disk0_type="ahci-hd"
disk0_dev="sparse-zvol"
disk0_name="disk0"

bhyve-host # vm start -f centos7_guest

disk0_dev="zvol" と disk0_dev="sparse-zvol" の違いは
zfs create 時に -V サイズ とするか -sV サイズ とするかの違いらしい。(/usr/local/lib/vm-bhyve/vm-zfs によれば)

それぞれの簡単な違い。

# zfs create -V 1G zroot/test_V1G
# zfs create -sV 1G zroot/test_sV1G
# zfs get volsize,refreservation,reservation zroot/test_V1G zroot/test_sV1G
NAME              PROPERTY        VALUE      SOURCE
zroot/test_V1G    volsize         1G         local
zroot/test_V1G    refreservation  1.03G      local
zroot/test_V1G    reservation     none       default
zroot/test_sV1G   volsize         1G         local
zroot/test_sV1G   refreservation  none       default
zroot/test_sV1G   reservation     none       default
# zfs get -o property,value,source all zroot/test_V1G > test_V1G
# zfs get -o property,value,source all zroot/test_sV1G > test_sV1G
# diff -u test_V1G test_sV1G
--- test_V1G    2020-07-17 17:28:19.427149000 +0900
+++ test_sV1G   2020-07-17 17:28:23.357872000 +0900
@@ -1,8 +1,8 @@
 PROPERTY              VALUE                    SOURCE
 type                  volume                   -
 creation              金  7月 17 14:51 2020  -
-used                  1.03G                    -
-available             823G                     -
+used                  12K                      -
+available             822G                     -
 referenced            12K                      -
 compressratio         1.00x                    -
 reservation           none                     default
@@ -11,16 +11,16 @@
 checksum              on                       default
 compression           lz4                      inherited from zroot
 readonly              off                      default
-createtxg             1016554                  -
+createtxg             1016548                  -
 copies                1                        default
-refreservation        1.03G                    local
-guid                  15560263540813307977     -
+refreservation        none                     default
+guid                  6406179365608872919      -
 primarycache          all                      default
 secondarycache        all                      default
 usedbysnapshots       0                        -
 usedbydataset         12K                      -
 usedbychildren        0                        -
-usedbyrefreservation  1.03G                    -
+usedbyrefreservation  0                        -
 logbias               latency                  default
 dedup                 off                      default
 mlslabel                                       -

ボリュームサイズ+メタデータ と refreservation を比べたときに、未満であれば sparse と言い、以上であれば not sparse らしい。
sparse の別名 thin provisioned, sparse volume, スパースボリューム
not sparse の別名 thick provisioned

zfs set refreservation=auto とした場合は、zfs create -V した場合と同じく、サイズ一杯まで (volsize+metadata) となるようだ。

# zfs get volsize,refreservation,reservation zroot/test_V1G
NAME             PROPERTY        VALUE      SOURCE
zroot/test_V1G   volsize         1G         local
zroot/test_V1G   refreservation  1.03G      local
zroot/test_V1G   reservation     none       default
# zfs set refreservation=none zroot/test_V1G
# zfs get volsize,refreservation,reservation zroot/test_V1G
NAME             PROPERTY        VALUE      SOURCE
zroot/test_V1G   volsize         1G         local
zroot/test_V1G   refreservation  none       local
zroot/test_V1G   reservation     none       default
# zfs set refreservation=auto zroot/test_V1G
# zfs get volsize,refreservation,reservation zroot/test_V1G
NAME             PROPERTY        VALUE      SOURCE
zroot/test_V1G   volsize         1G         local
zroot/test_V1G   refreservation  1.03G      local
zroot/test_V1G   reservation     none       default
perl adv
perl adv