2014/04/26

OpenZFS on OS X (8) では、いじってみる。

もはやZFSの話しかしていないこのブログ・・・VAIO Duo以降さしたるガジェットも買ってないし。と思ったらそういえばiPad mini retinaを買っていた。UMPCが本当にジャンルごと死んでしまったので、Ultrathin Keyboard Folio for iPad mini買ってUMPC風に使ってます。便利すぎてPC好きとしては逆に辛かったり。

で、結局OpenZFS on OS X(O3X)の話題です。ある程度ZEVOをリプレースする目処が立ったので、メインマシンの環境をZEVOから移行してMavericksにアップグレードしました。
しかし、現状ではEAやACL周りの挙動が怪しい、zvolがかなり遅い、ARCが小さいので全体的に遅い、などかなり未完成な印象なので、検証用以外のストレージに導入するのはまだオススメできません。
自分はZEVOの時点でメインのストレージ(3TBx2)をZFSにしちゃったんでもう後には引けないですがw 今更AppleRAIDにも戻りたくない。

今回は特にまとまってないZFS on MacあるいはO3X固有の話題についてつらつら書いていこうかと。


まずO3X独自プロパティについて。
O3Xは、上流のZFS on Linuxで実装されているもの以外に、2つのZFSプロパティを持っています。
zfs getで見てみると以下のような感じ。
# zfs get all r1pool
NAME    PROPERTY               VALUE                  SOURCE
r1pool  type                   filesystem             -
(略)
r1pool  com.apple.browse       on                     default
r1pool  com.apple.ignoreowner  off                    default
1つはcom.apple.browseで、これはデスクトップにZFSデータセットが外部ディスクとして表示されるかどうかを制御します。
offにするとデスクトップに表示されなくなる(フォルダを開いていけばFinderからも普通に見える=フォルダと同じ)ので、データセットを大量に作っている人にとっては便利です。
実際、ZEVOの頃は作ったデータセットが全部デスクトップに出て邪魔で、Finder環境設定から外部ディスク表示を切った上で必要なボリュームだけエイリアス作って置いたりしていたので、そういった対策が不要になるので非常に便利なプロパティです。

もう1つはcom.apple.ignoreownerで、名前で予想がつくかもしれませんが「このボリューム上の所有権を無視」を有効にするプロパティです。外部とやり取りするUSBメモリ上のプールではonにしておくとパーミッションを意識する必要が無くなり便利だと思います。まあZFSでそういう使い方をするケースは稀な気がしますが・・・

どちらも、データセット上のデータ様式ではなくMac OS X側の挙動を変えるプロパティなので、これらのプロパティが操作されたプールを他のOSでimportとしても特に問題は無いかと思います。


次にVMware FusionでのZFS活用について。
仮想マシンの置き場としてZFSを使うのは非常に効果的です。VMwareの機能に頼らないsnapshot、圧縮、クローンによる複製などZFSの機能が良く活かせるシチュエーションだと思います。

仮想マシン用にZFSを使う場合、使い方としては
・仮想マシン用にデータセットを用意する
・仮想マシンごとにzvolを作成して接続する
の2つが考えられると思います。後者の方が、ファイルを介さないことによるパフォーマンス面やホスト側からマウントできる点で有利な気がしますが、結論から言うと現状後者は実用になりません。

理由としてはパフォーマンスに尽きます。というのも、O3X1.2.0時点でzvolが遅いということに加え、VMwareのrawdisk接続機能が512Bブロックのデバイスしかサポートしていないため、
# zfs create -V 100G -b 512 pool/vol1
$ ./vmware-rawdiskcreator create /dev/diskX fullDevice vmdkFile sata
のようにしてzvolを作成するしかなく、更にパフォーマンスが落ちます(内部的に4K単位でアクセスしているため4K未満のvolblocksizeはメリットが無いらしい)。
手元の環境では、Windows 8.1インストーラーのインストール開始から完了までの時間が、ZFS上のvmdkファイルでは2分だったところ、zvolでは1時間かかった挙げ句遅すぎて起動できないという有様でとても実用にはなりませんでした。

ということで、前者の方法を採ることにします。
ここで重要なのが、仮想マシン1台につき1つのデータセットを用意するという点です。1つのデータセット内に複数の仮想マシンを置いてしまうと、snapshotのロールバックやクローンが一蓮托生となってしまうため、ZFSの恩恵を受けることが難しくなります。

しかし、仮想マシン置き場としてのZFSデータセットが林立し、各データセット内に仮想マシンファイルが1つ置かれているだけというディレクトリ構造も気持ちが悪いので、対策することとします。
以下の手順は既存の仮想マシンの移行を想定していますが、新規仮想マシンを作る場合も、Fusion上から仮想マシン作成→インストーラーを立ち上げず終了してOS未インストールの仮想マシンファイルを作る、という手順を踏めば同様のことが可能です。

まず、既存の仮想マシン置き場として
/Volumes/HDD/Virtual Machines/
が存在しているとします(このフォルダがどのファイルシステム上かは問わない)。
このフォルダのディレクトリ構造は以下のようになっています。
$ ls /Volumes/HDD/Virtual Machines/
Mac OS X 10.9.vmwarevm
Ubuntu 12.04 x64.vmwarevm
Windows 8.1 x64.vmwarevm
拡張子.vmwarevmのファイルが仮想マシンファイルです。が、ファイルと書きましたが実体はディレクトリで、右クリックから中身を開くことができます。
つまり、「仮想マシン名.vmwarevm」という名前のデータセットをこのフォルダにマウントしてしまえばZFSデータセットがあたかも仮想マシンファイルとして存在しているかのように扱うことができます。

というわけで、まずZFSデータセットを作っていきます。
# zfs create -o atime=off -o mountpoint=none -o compression=lz4 -o com.apple.browse=off pool/vm
# zfs create pool/vm/osx10.9
# zfs create pool/vm/ubuntu12.04x64
# zfs create pool/vm/win8.1x64
個々の仮想マシンに割り当てるデータセットの上に1つデータセット(pool/vm)を作って、各種プロパティを割り当てておくことをおすすめします。特に、仮想マシンは圧縮が効くのでcompression=lz4がおすすめです(lz4はオーバーヘッドも少ない)。次に、既存の仮想マシンをリネームしてZFSデータセットと置き換えます。
$ cd "/Volumes/HDD/Virtual Machines/"
$ mv "Mac OS X 10.9.vmwarevm" "Mac OS X 10.9_old.vmwarevm"
$ mv "Ubuntu 12.04 x64.vmwarevm" "Ubuntu 12.04 x64_old.vmwarevm"
$ mv "Windows 8.1 x64.vmwarevm" "Windows 8.1 x64_old.vmwarevm"

# zfs set mountpoint="/Volumes/HDD/Virtual Machines/Mac OS X 10.9.vmwarevm" pool/vm/osx10.9
# zfs set mountpoint="/Volumes/HDD/Virtual Machines/Ubuntu 12.04 x64.vmwarevm" pool/vm/ubuntu12.04x64
# zfs set mountpoint="/Volumes/HDD/Virtual Machines/Windows 8.1 x64.vmwarevm" pool/vm/win8.1x64
# zfs mount -a

# chown b00t:staff "./Mac OS X 10.9.vmwarevm"
# chown b00t:staff "./Ubuntu 12.04 x64.vmwarevm"
# chown b00t:staff "./Windows 8.1 x64.vmwarevm"
リネームはFinderからでも問題はありません。最後にコピーします。
$ cp -r "./Mac OS X 10.9_old.vmwarevm/*" "./Mac OS X 10.9.vmwarevm/"
$ cp -r "./Ubuntu 12.04 x64_old.vmwarevm/*" "./Ubuntu 12.04 x64.vmwarevm/"
$ cp -r "./Windows 8.1 x64_old.vmwarevm/*" "./Windows 8.1 x64.vmwarevm/"
コピーもFinderからでOKです(不可視ファイル等は特になし)。これで、VMware FusionからZFSデータセット上の仮想マシンの起動が可能になります。また、マウントしたデータセットをVMware Fusionのライブラリにドラッグ&ドロップして登録することも可能です。


さて、仮想マシンの次はOS X全体のZFSへの置換を目指したいところです。
と言っても、カーネルがZFSを読めない以上ZFSデータセット上に置いたシステムからの起動は無理です。HFS+が前提となっているOSでもあるので、システムボリューム全体をZFSに置換するのは無理そうです。
ということで、ホームディレクトリのZFS化を目指していきたいと思います。

単純にZFSデータセットをホームディレクトリにすること自体はそんなに難しくはありません。
/Volumes/Users/hogeにマウントしてホームディレクトリの位置を変えても、/Users/hogeに直接マウントして使ってもちゃんと機能します。

ただ、現状の問題点として自動ログインができないという問題があります。これは、ZFSの仕様上自動ログインに対応しないということではなく、
自動ログインだとZFSデータセットのマウントが起動に間に合わない
→ホームディレクトリが空だとしてログインされる
→新規ユーザの設定が始まってしまう
→ホームディレクトリに初期設定ファイル・フォルダが作成される
→ZFSデータセットがマウントできず新規ユーザとしてログインさせられる
ということが発生してしまうためです。
自動ログインを切っていれば、ログインウィンドウ起動とパスワード入力の間にマウントが完了するのでこのような問題は起こりません。
auto-import用のlaunchdスクリプトやspl/zfs.kextの置き場を/Libraryから/System/Libraryに移したりもしましたが特に効果はありませんでした。

個人的には、起動時に色々ごちゃごちゃ立ち上がる自宅PCは自動ログインを維持したいのでどうしよう、というところです。
ログインプロセスの立ち上がり前に何らかの形でディレイを入れられればいいんですが。
元々自動ログインを使っていない環境であれば普通に起動可能です。
ただ、何らかのトラブル時に起動できないといった事態を避けるため、普通のホームディレクトリを持つメンテナンス用アカウントを1つ作っておく必要はあるでしょう。


もう1つは移行の問題。同じHDD/SSD上に移行するのであればZFS用の領域を切り出すための空き容量が必要です。
大容量HDDがシステムならともかく、SSDだったりすると結構大変です。
自分の構成ではシステムが256GBのSSD上にあり、大体
・全体の使用量:103GB
・ホームディレクトリの使用量:64GB
・その他の領域の使用量:39GB
・空き容量:153GB
といった感じです。
ホームディレクトリを丸々コピーするだけなら空き容量は足りていますが、実際にZFSデータセットを作るとなるとパーティション設定の問題が発生してくるので、HFS+80GB、ZFS残り、みたいな切り方をするには使用量がオーバーしています。

まあ、実のところホームディレクトリは移行のためにかなりダイエットしていて、64GBの多くを占めているのが47GBのWin7仮想マシン(これだけSSDに置いている)なので、一時的にこれをHDD上に退避すれば特に問題は無かったりします。

もし空き容量が足りない状態で移行するなら
メンテ用アカウントでログイン
→ホームディレクトリを外付けHDD等に退避
→必要サイズまでHFS+パーティション縮小して残りを(適当にフォーマットした後)zpool create
→作成したZFSデータセットに退避したホームディレクトリをコピー
→一般的なホームディレクトリ移行関係の諸々の設定をした後再起動
みたいな手順が必要かと思います。

このあたりは怖いのでVMで色々検証しよう・・・

0 件のコメント:

コメントを投稿