256バイト以上のファイル名を持つZFSをFreeBSDにインポートしてみる
以前、FreeBSDではlongnameフィーチャーは使えないという話をした。
FreeBSDで255バイト超のファイル名でファイルは作れないとして、Linuxで作った256バイト以上のファイル名を持つZFSをFreeBSDにインポートした場合、どうなるのだろうか。インポートできなかったり、クラッシュしたり、データセットが壊れるなんてことは流石にないと思うが、分からんってのが正直なところ。サクッと試してみよう。
まずはLinux側でlongnameフィーチャーが有効なデータセットと、長いファイル名を持つファイルを作る。
環境はこんな感じ。Linuxと言いつつProxmox VEです。
# pveversion
pve-manager/9.1.4/5ac30304265fbd8e (running kernel: 6.17.4-2-pve)
# zpool version
zfs-2.3.4-pve1
zfs-kmod-2.3.4-pve1
# zpool status zlongname
pool: zlongname
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
zlongname ONLINE 0 0 0
zvol/zvm/vm-100-disk-0 ONLINE 0 0 0
errors: No known data errors
データセットの文字コードはUTF-8にした。
# zfs create -o utf8only=on zlongname/longname
UTF-8の場合、日本語1文字はおおむね3~4バイトでエンコードされるので、255バイト=全角85文字となる。255バイトと256バイトのファイル名でファイルを作ってみる。
# touch '123456789~1~123456789~2~1234 56789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345' # touch '123456789~1~123456789~2~1234 56789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345a' touch: cannot touch '123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345a': File name too long
256バイトの方はファイル名長すぎィと怒られた。longnameフィーチャーを有効にして再度試してみる。
# zfs set longname=on zlongname/longname # touch '123456789~1~123456789~2~1234 56789~3~123456789~4~123456789~5~123456789~6~123456 789~7~123456789~8~12345a' # ls 123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345 123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345a
今度は当然ながら問題なく作成できた。このプールをFreeBSDに持っていく。
FreeBSD側は以下のような感じ。ashiftの警告が出てるけど本質じゃないのでスルーで。
$ freebsd-version -uk
14.3-RELEASE-p2
14.3-RELEASE-p2
$ zpool status zlongname
pool: zlongname
state: ONLINE
status: One or more devices are configured to use a non-native block size.
Expect reduced performance.
action: Replace affected devices with devices that support the
configured block size, or migrate data to a properly configured
pool.
config:
NAME STATE READ WRITE CKSUM
zlongname ONLINE 0 0 0
gptid/737d89da-f0e3-6c4d-a86d-426d41479aa8 ONLINE 0 0 0 block size: 512B configured, 4096B native
lsでは普通に255バイト超のファイル名も表示された。ちょっと意外。
$ ls /zlongname/longname/ 123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345 123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345a
開こうとするとファイル名長すぎィと怒られた。
$ cat '/zlongname/longname/123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345a' cat: /zlongname/longname/123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345a: File name too long
256バイトのファイル名でファイルを作ろうとしても、やっぱり長すぎィと怒られた。
$ touch '/zlongname/longname/123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345b' touch: /zlongname/longname/123456789~1~123456789~2~123456789~3~123456789~4~123456789~5~123456789~6~123456789~7~123456789~8~12345b: File name too long
というわけで、ZFSのlongnameフィーチャーを有効にし256バイト以上のファイル名があるデータセットをFreeBSDに持っていくと、ファイルの存在は確認できるが、ファイル操作は不可というのが現状のようだ。
Linux 5.7でintel_pstateのHWPの挙動が変わっていた
自鯖のProxmox VEを6から7に上げたら、アイドル時の消費電力が上がったような気がする。ハードウェア構成が少し変わってたりもするので何とも言えないところだが、IPMIで見る限り増えているのは確か。
あれこれ試してみたところCPUのスケーリングガバナーの挙動が変わっていた。そして、そもそもCPUドライバとしてintel_pstateではなくintel_cpufreqが使われていた。
# cpupower frequency-info
analyzing CPU 0:
driver: intel_cpufreq ★これ
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: 20.0 us
hardware limits: 1.20 GHz - 3.30 GHz
available cpufreq governors: conservative ondemand userspace powersave performance schedutil
current policy: frequency should be within 1.20 GHz and 3.30 GHz.
The governor "powersave" may decide which speed to use
within this range.
current CPU frequency: Unable to call hardware
current CPU frequency: 1.20 GHz (asserted by call to kernel)
boost state support:
Supported: yes
Active: yes
同じ環境でPVE 6の時はintel_pstateが使われていたハズなんだけどなぁ。dmesgを見ると、intel_pstateが採用されている雰囲気だが、“HWP not enabled”の一文も気になるところ。
# dmesg | grep intel_pstate [ 2.020574] intel_pstate: HWP not enabled [ 2.020580] intel_pstate: Intel P-state driver initializing
答えはArchiWikiとintel_pstateのドキュメントに書いてあった。HWP (Hardware P-States)が使えないCPUではintel_pstateはPassive Modeとして動作し、ドライバとしてintel_cpufreqが使われるとのこと。お前かー!!
Linuxカーネルバージョン5.81)でのintel_pstateの改修により、この挙動に変わったらしい。実際、v5.7とv5.8のソースを見比べると、確かにそのような変更が加えられている。
話はこれで終わらずv5.9において、EPP (Energy Performance Preference)を持たないCPUをHWP制御から除外するコードがわざわざ追加されている。HWPはSkylakeからの実装とされているが、実際はBroadwell-EPで初期実装が行われているらしく、現に前述のv5.7コードではHWPを使うようになっている。
自鯖のCPUはまさにBroadwell-EPなXeonなので、見事に該当しているというワケだった。
強制的にアクティブモードにすることもできそうだが、どっちがいいんだろうねぇ?更にHWPM (Hardware Power Management)を使って、完全にハードウェア任せにするという選択肢もあるし悩ましいところ。
(2022-02-21 追記)
うちのマシンの場合アイドル時の消費電力は、やはりアクティブモードの方が気持ち低いようだ。
アクティブモードとパッシブモードの切り替えは/sys/devices/system/cpu/intel_pstate/statusに、それぞれactiveとpassiveを書き込むことで可能。切り替えた場合、スケーリングガバナーの変更もお忘れなく。
# cpupower frequency-info
analyzing CPU 0:
driver: intel_cpufreq
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: 20.0 us
hardware limits: 1.20 GHz - 3.30 GHz
available cpufreq governors: conservative ondemand userspace powersave performance schedutil
current policy: frequency should be within 1.20 GHz and 3.30 GHz.
The governor "ondemand" may decide which speed to use
within this range.
current CPU frequency: Unable to call hardware
current CPU frequency: 1.30 GHz (asserted by call to kernel)
boost state support:
Supported: yes
Active: yes
# echo active > /sys/devices/system/cpu/intel_pstate/status
# cpupower frequency-info
analyzing CPU 0:
driver: intel_pstate
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: Cannot determine or is not supported.
hardware limits: 1.20 GHz - 3.30 GHz
available cpufreq governors: performance powersave
current policy: frequency should be within 1.20 GHz and 3.30 GHz.
The governor "performance" may decide which speed to use
within this range.
current CPU frequency: Unable to call hardware
current CPU frequency: 1.20 GHz (asserted by call to kernel)
boost state support:
Supported: yes
Active: yes
参考サイト
デグレったZFSプールは他マシンでのインポートが制限されるっぽい?
色々と事情があって、FreeBSDで作ったHDD×4台からなるRAIDZプールを、HDD×3でデグらせた状態でZoL環境でインポートした。
すると自動scrubが走るわけだが、処理途中で一旦エクスポートし、FreeBSDの方でHDD×4の状態でインポートしようとしたら出来なかった。
# zpool import zdata cannot import 'zdata': no such pool available
こんなエラーが出るわけ。プールをFreeBSDとLinuxの間で、あまつさえデグレった状態で行き来させたせいで壊れた!?と超焦るわけ。
ZoL環境だと正常にインポートできたのでプールの無事は確認でき、HDD×4に戻してRAID修復が終わるのを待ったところ、FreeBSDの方でも何事もなくインポートできるようになった。
ここから分かることは、どうやらデグレった状態のプールを一度でもインポートすると、プールの健全性が回復するまで別のシステムでのインポートができなくなるらしい?これがZFSの正常な挙動なのか、FreeBSD (Legacy ZFS)とZoLを行き来したが為の特殊挙動なのかは分からない。
もし正式挙動だとしたら、プール修復中にマシンが壊れるとプールが死ぬわけだから、正式挙動ではないとは思うんだけど、実際に起こった事象として記録しておく。
LinuxがGPTを1MB確保するのはWindowsとの互換性のため
LinuxでGPTを作ると、First usable LBAの値が512バイトセクタドライブで2048、4kセクタドライブで256となる。すなわち、LinuxはGPTとして1MiBを確保する。
GPTの情報を格納するのに必要なサイズは16.5KiBなので、本来は33セクタ@512Bまたは5セクタ@4KiBで事足りる。FreeBSDの39セクタ@512Bに慣れた身からすると、無駄とも思えるサイズである。
この理由を調べてみると、どうもWindowsとの互換性のためっぽい。
WindowsではVistaとWindows Server 2008から、パーティションを1MiBアライメントで揃えるようになったそうだ。Linuxはこれに倣ったとのこと。1MiBアライメントなら、512バイトと4kBの倍数なので所謂AFTアライメント問題が解消でき、将来、より大きなセクタサイズが登場した時に対応できる可能性も高まる、というのが狙いらしい。
言われてみれば納得の理由で、逆にFreeBSDが20KiBしか確保しないことが不安になってくる…。パーティション追加時にgpart create -a 1Mとすればパーティションを1MiB境界で揃えることはできる。一方で、First usable LBAを弄るものではないので、パーティション一覧を出したときにGPTと第1パーティションの間に“未使用領域”が計上されてしまうのが、ちょっとカッコ悪い。
どうでもいいけど調査の過程で、今更ながらCHSやらセクター63やらシリンダ境界規定やらを調べてしまった。
(2021-01-16 追記)
Linuxのfdiskで切ったパーティションをFreeBSDで見てみた。
> gpart show
=> 6 234423115 nvd0 GPT (894G)
6 131072 1 efi (512M)
131078 26214400 2 freebsd-zfs (100G)
26345478 208077643 - free - (794G)
=> 256 468843345 nvd1 GPT (1.7T)
256 131072 1 efi (512M)
131328 26214400 2 freebsd-zfs (100G)
26345728 375914496 3 !6a898cc3-1dd2-11b2-99a6-080020736631 (1.4T)
402260224 13107200 4 !6a898cc3-1dd2-11b2-99a6-080020736631 (50G)
415367424 53476177 - free - (204G)
nvd0がFreeBSDのgpart、nvd1がLinuxのfdiskで作成したもので、どちらも4kセクタである。
FreeBSDのgpartもFirst usable LBAをちゃんと見ているようで、nvd1のESPの開始セクタ256セクタ=1MiB地点を正しく認識している。
将来のことを考えると、GPTを作るところまではLinuxまたはWindowsでやった方がいいかもしれないなぁ。
参考サイト
いつのまにかZoLとOpenZFSが統合されてた&永続的L2ARCが来るっぽい
2020年12月1日、ZoLベースとなるOpenZFS 2.0が無事にリリースされた
ZFSのLinux向け実装であり今やZFS開発のメインストリームであるZFS on Linux (ZoL)が、いつの間にかOpenZFSと統合されていた。実際のところ、統合というよりはOpenZFSがZoLベースで仕切り直され、ZoLがOpenZFSに名前を変えたという感じのようだ。
経緯はともかく、既にZoLのGitHubはOpenZFSのリポジトリへとリダイレクトされるようになっている。で、2020年、すなわち今年にはZoL 0.8をベースとしたOpenZFS 2.0がLinuxとFreeBSD向けにリリース見込みとなっている。この辺のロードマップはOpenZFS Developer Summitでの発表資料(PDF)に詳しい。
また、そう遠くない未来に永続的L2ARC (Persistent L2ARC。界隈ではpL2ARCと表記されている)が取り込まれるようだ。
ZFSerにはご存じのとおり、L2ARCはSSDなどの高速ストレージを使ったZFSの読み込みキャッシュの仕組みである。必要な時に後から有効化できたり、不要になったらいつでも無効化できたりと、簡単便利な仕組みだが、システムの再起動でキャッシュ内容が失われてしまう欠点がある。正確には、キャッシュデータはストレージ上に残っているものの、メインメモリのキャッシュ管理データが消えてしまうため、現状のL2ARCは事実上の揮発性キャッシュとなっている。
pL2ARCでは、その名前のとおりシステムを再起動しても以前のキャッシュが維持されるようになる。ちなみに、L2ARCの管理データは無視するには大きすぎるサイズとなる。あまり巨大なL2ARCを作ると管理データがメモリを圧迫し、L2じゃない方のARCが減るという本末転倒な事態に陥るので注意が必要。
pL2ARCの構想自体は旧OpenZFSのロードマップにも存在していた。2015年にillumos向け実装の移植が試みられていたようだが、結局実現はしなかった。ところが最近になって、これまたZoLパワーでもって急速に開発が進められている。現時点でOpenZFS 2.0リリース予定には組み込まれていないものの、既にプルリクが作られており近々masterに取り込まれそうな勢いである。Linuxパワーしゅごい……。