RAID-Z Expansionがマージされてた&ファイル名の最大長拡張PRが出来てた
もはや旧聞に属する話だが、2023年11月9日のRAID-Z Expansionのプルリクがついにmasterにマージされていた。コンセプトが発表されてから足掛け7年、実に長かった。なかなかインパクトのある機能だし仕方ないか。関係者の皆様お疲れ様でございました。
とはいったものの、実際にリリースされて使えるようになるのは、まだ先と思われる。リリース時期に関する最新情報は見つけられなかったのだけど、2021年時点のロードマップではOpenZFS 3.0で対応予定となっている。どんなに早くても2.3かなー?と思いつつ、どちらのバージョンのブランチもまだ存在しないのが現状。
加えてFreeBSDで使うには、ベースシステムに取り込まれるのを待たなきゃならんわけで、1年以上先なんじゃね?という気がしなくもない(まぁportsから入れればいいんだけども)。首を長くして待ちましょー
ついでにプルリク一覧を眺めていたら、ファイル名/ディレクトリ名の最大長を1023バイトに拡張する新しい機能フラグの実装があった⇒Longname: files/directories name upto 1023 bytes by tuxoko · Pull Request #15921 · openzfs/zfs
ZFSのファイル名/ディレクトリ名の最大長は255バイトとされているが、これはNAME_MAXだかPATH_MAX定数由来の制約らしい。これはUNIX系のファイルシステムにおける典型的な最大長で、通常はほとんど困らないサイズである。
ところが、ファイル名の文字コードとしてUTF-8を使うと話が変わってくる。UTF-8では1文字あたりのバイト数が1~4バイトと可変なので、ワーストケースで63文字しか格納できない。日本語の文字種はおおむね3バイトになるため、85文字で打ち止めとなる。
これでもFreeBSD、Linux単体で使う分にはさほど問題にならないと思うが、Windowsとファイル共有するとだいぶ困ったことになる。 というのもWindows (NTFS)の最大長はUTF-16で255文字1)なので、ZFSの255バイトでは全然足りんのです。 まぁ、日常的に85文字を超えるファイル名を使うことは、少なくとも自分は無いけれど、それでも1年に2~3回くらいは困る場面があるんだよね…
上記PRとは別に(?)最大長拡張の議論もなされており、開発のコアメンバーも認識はしている模様。互換性はどうなるんだとか、最大255文字で決め打ちしてるアプリで扱おうとした時にどうなるんだとか、色々気になる点はあるが、是非とも実現されてほしいところ。
参考サイト
Windowsのローカルユーザーのパスワードをネットワーク越しに変更する
Ctrl+Del+Altからのパスワード変更画面で、ユーザー名をリモートコンピュータ名\ユーザー名とすると、ローカルPCアカウントと同じ要領でリモートPCのローカルアカウント(ややこしい)のパスワードを変えられるそうなんだけど、最近のWindowsでは以下のおまじないが必要だそう。
- コマンドプロンプトで以下のコマンドを実行(レジストリ追加)
REG ADD HKLM\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters /v NullSessionPipes /t REG_MULTI_SZ /d SAMR /fREG ADD HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v RestrictRemoteSamAuditOnlyMode /t REG_DWORD /d 1 /f
- Windowsファイアウォールで「Netlogonサービス」を許可
ファイヤウォールの穴あけまで言及してるサイトが殆どなくて結構ハマった。
参考サイト
C#の0がenum値に暗黙キャストされてinvokeStaticで例外出て超ハマった
僕はついさっき知ったばかりなんですけど、C#の数値0ってあらゆるenum値に暗黙的キャストされるんですってね。要するに、0だけはキャスト不要で列挙型の値として変数に代入できちゃったりするということ。コードで示すと以下のようなかんじ。
using System; public class Program { enum Hoge { A, B } enum Piyo { C, D } public static void Main() { Hoge h1 = 0, h2 = 0.0f; Piyo p1 = 0x0, p2 = 0.0m; Console.WriteLine($"{h1}, {h2}"); Console.WriteLine($"{p1}, {p2}"); } }
このコードは何の警告もなくビルドが通り、以下の実行結果が得られる。
A, A C, C
浮動小数点数やDecimalのゼロも同様の扱いっていうのが、なかなかのキモいポイント。C#のenumってC/C++のそれと違ってそれなりに厳密なので、自分的には結構衝撃的な仕様だった。まぁ、分かってしまえばどうってことはない。
で、ここからが本題。
そんな0のenumへの暗黙的型変換のおかげで、意図せぬメソッドのオーバーロード解決が行われ、小一時間ハマった。
以下のような処理メソッドAddと、それに対する単体テストAddTestを考える。対象メソッドはプライベートな静的メソッドなので、テスト呼び出しにはPrivateType.InvokeStaticメソッドを使っているが、至ってシンプルなコードである。
何の疑いもなく動くと思いきや、ケース3のテストでのみMissingMethodException例外が発生し、Addメソッドの呼び出しに失敗するのだ!
// 加算 private static decimal? Add(decimal? v1, decimal? v2) { return v1 + v2; } // Addメソッドの単体テスト void AddTest() { var privateType = new PrivateType(typeof(AddClass)); // ケース1 var value = (decimal?)privateType.InvokeStatic("Add", 1.0m, 1.0m); // OK Assert.AreEqual(2, value); // ケース2 value = (decimal?)privateType.InvokeStatic("Add", 1.0m, 0.0m); // OK Assert.AreEqual(1, value); // ケース3 value = (decimal?)privateType.InvokeStatic("Add", 0.0m, 1.0m); // MissingMethodException例外が発生! Assert.AreEqual(1, value); }
MissingMethodExceptionは読んで字のごとく、メソッドが見つからなかった場合に投げられる例外だ。
ケース1~2は通っているのに見つからないとは一体…!?という感じなのだが、これまでの説明からお気づきであろう、ケース1~2と3では呼び出されるInvokeStaticのシグネチャが違うのだ。同メソッドは引数違いで10個ほどのオーバーロードが定義されており、それぞれ以下のシグネチャのものが呼び出される。
- ケース1~2
- InvokeStatic(String, params Object[])
- ケース3
- InvokeStatic(string, System.Reflection.BindingFlags, params Object[])
ケース3では、第二引数の0.0mがBindingFlagsに暗黙キャストされた結果、引数を1つ持つAddメソッドを呼び出そうとして例外を吐くというわけ。なんじゃそりゃー!分かるわけネェーッ!!意図通り動かすにはprivateType.InvokeStatic(“Add”, (decimal?)0.0m, 1.0m)のように、明示的にキャストし正しいオーバーロード解決を導いてあげればよい。
この暗黙型変換を禁止ないし警告出してくれるコンパイルオプションとかないのかしら…ハマった時に死ぬほどわかりづらいんですけど……
PowerEdge T330/PERC H330環境でPVE 8がEFI stubうんちゃらで起動できない件
PowerEdge T330とITファームを書き込んでHBA化したPERC H330環境で、H330に接続したストレージにインストールしたProxmox VE 8.0-2を起動しようとすると、EFI stub: Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device pathと出て止まってしまう。マザボから生えてる内蔵SATAの方だと問題ない。
PVEのフォーラムでも同様の現象が報告されている。
ZFSがらみの何かっぽくext4なら大丈夫らしい。根本的な解決策は見当たらないが、PVE 7をインストールしアップデートでPVE 8にした場合は起動するそうで、試しにやってみたら確かに問題なくPVE 8が立ち上がった。すんごい気持ち悪いんですけど。
BIOSとiDRACあたりとの相性かと思い数時間かけて頑張って更新したが、完全な無駄足になってしまった…。更新後はJava版の仮想コンソールが何故か起動に失敗すること多いし、PVEで仮想コンソールのキー入力が全く効かないわ、ACPIシャットダウンが機能しないわでマジで意味がわからん。ただの無駄足であってくれた方がなんと良かったことか……
一応PVEの動作に問題はなさそうだけど、どうしたものか。
5年半使ったIntel DC S3500 240GBの状態とベンチマーク
ファイルサーバで使ってたInte SSD DC S3500 240GB (SSDSC2BB240G4)がお役御免となった。購入記録を採ってるわけじゃないけど、たぶんこの時のSSD⇒Intel SSDSC2BB240G4 (DC S3500 240GB) のベンチマーク。のちに同じSSDを中古購入し、2台でRAID組んでWindows Serverのシステム領域兼記憶域階層のSSD層として使っていた。先に買った方、つまり当時のベンチマークがある方の使用時間は5年半ほどになる。
経年でどの程度パフォーマンスが変わったのか比較してみた。
ランダムリード・ライトが若干遅くなっているように見えなくもないが、4KiB 32QT1は速くなって良くわからん。240GBのSSDに対して93TB書き込んでるけど、問題になるような性能低下はなさそう。損耗率から計算すると残り280TBほど書き込めるようだ。
かたわれのSSDは結構深刻な状態で、ランダムライト速度が半分以下になってしまっている。
------------------------------------------------------------------------------
CrystalDiskMark 8.0.4 x64 (C) 2007-2021 hiyohiyo
Crystal Dew World: https://crystalmark.info/
------------------------------------------------------------------------------
* MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]
* KB = 1000 bytes, KiB = 1024 bytes
[Read]
SEQ 1MiB (Q= 8, T= 1): 496.475 MB/s [ 473.5 IOPS] < 16845.23 us>
SEQ 1MiB (Q= 1, T= 1): 399.525 MB/s [ 381.0 IOPS] < 2621.80 us>
RND 4KiB (Q= 32, T= 1): 312.067 MB/s [ 76188.2 IOPS] < 418.81 us>
RND 4KiB (Q= 1, T= 1): 30.675 MB/s [ 7489.0 IOPS] < 133.11 us>
[Write]
SEQ 1MiB (Q= 8, T= 1): 285.882 MB/s [ 272.6 IOPS] < 29174.83 us>
SEQ 1MiB (Q= 1, T= 1): 285.205 MB/s [ 272.0 IOPS] < 3673.12 us>
RND 4KiB (Q= 32, T= 1): 92.268 MB/s [ 22526.4 IOPS] < 1419.45 us>
RND 4KiB (Q= 1, T= 1): 43.706 MB/s [ 10670.4 IOPS] < 93.19 us>
Profile: Default
Test: 2 GiB (x3) [D: 0% (0/224GiB)]
Mode: [Admin]
Time: Measure 5 sec / Interval 5 sec
Date: 2023/10/10 22:06:50
OS: Windows 10 Professional [10.0 Build 19045] (x64)
Comment: Intel DC S3500 240GB (SSDSC2BB240G4)
セキュアイレースしても目立った改善は見られなかった。
S.M.A.R.T.はメディア消耗指標は問題なさそうだが、電源断保護失敗で異常が検出されており、そのためか電源投入回数が跳ね上がっている。
電源断保護失敗でパフォーマンス低下ってのも良くわからんけど、内蔵の電源回路が不調→コントローラリセット→すぐ回復→辛うじて書き込みは継続、って感じなのかなー?
若干の不安はありつつも、別サーバでZFSのRAID-1構成で引き続き頑張ってもらう予定。








