特に、ZEVOから利用しているデータセットをO3Xに移行する際の問題についてそれなりに詳細に記しています。
基本的にZEVOについて書いた昔の記事の流れを汲んだものです。
まず、netatalkについて。
O3XではコードベースがZFS on Linux(ZoL)となったので、最新のOpenZFSで作成されたプールもインポートできます。そのため、ZoL環境でnetatalkを動かしているサーバーにトラブルが起こっても、O3Xからインポートして一時的なサルベージができる可能性があります。
netatalkでの拡張属性についてですが、拡張属性に対応したファイルシステムであれば拡張属性に格納し、そうでない場合はAppleDouble(._から始まるファイル)となるようです。しかし、com.apple.ResourceForkだけは格納できないらしくAppleDouble方式になります。本来のZFS(=SolarisのZFS)ではResourceForkも拡張属性に入るようですが、ZoLではそうなっていません(ZoLの制限・Linuxの制限・netatalkの制限・netatalkがSolaris以外のZFSを考慮していないだけ、のどれかは不明)。
ともかく、Linux+ZoL+netatalkのボリュームをMacからマウントすると以下のようになります。
$ ls -la@ total 1024 drwx------@ 1 b00t staff 264 3 24 21:16 . org.netatalk.has-Extended-Attributes 4 drwxrwxrwt@ 8 root admin 272 3 24 21:14 .. com.apple.FinderInfo 32 drwxr-xr-x@ 1 b00t staff 264 3 24 21:15 folderIcon com.apple.FinderInfo 32 drwxr-xr-x@ 1 b00t staff 264 3 24 21:15 folderLabel com.apple.FinderInfo 32 drwxr-xr-x 1 b00t staff 264 3 24 21:14 folderNone -rw-r--r--@ 1 b00t staff 0 3 24 21:16 textCreater.txt com.apple.ResourceFork 1338 -rw-r--r--@ 1 b00t staff 0 3 24 21:15 textIcon.txt com.apple.FinderInfo 32 com.apple.ResourceFork 325188 -rw-r--r--@ 1 b00t staff 0 3 24 21:15 textLabel.txt com.apple.FinderInfo 32 com.apple.metadata:kMDLabel_qygkxhrfarhtxanqhi264amkku 50 -rw-r--r-- 1 b00t staff 0 3 24 21:15 textNone.txtちゃんと拡張属性が保存されています。しかし、このボリュームをサーバー上で見ると以下のようになっています。
# xattr * folderIcon: user.org.netatalk.Metadata folderLabel: user.org.netatalk.Metadata folderNone: user.org.netatalk.Metadata textCreater.txt: user.org.netatalk.Metadata textIcon.txt: user.org.netatalk.Metadata textLabel.txt: user.org.netatalk.Metadata textLabel.txt: user.com.apple.metadata:kMDLabel_qygkxhrfarhtxanqhi264amkku textNone.txt: user.org.netatalk.Metadataどういうことかというと、Mac OS Xでの各種拡張属性がuser.org.netatalkから始まる独自の拡張属性として格納されています。これをnetatalkがMac向けの拡張属性であるように見せているため、O3Xから直接マウントすると当然netatalk独自の拡張属性を理解できないためラベルやアイコンは見えなくなります。
まあ、実際のところサーバーのZFSデータセットをO3Xで読むのはサルベージなどの緊急時くらいだと思うので、netatalk経由で書いた拡張属性が読めないのはさほど問題にならないと思います。
というわけでこの話は蛇足です。
肝心なのがZEVO→O3X移行に際して拡張属性が保存されるかどうかという問題です。
結論から言うと保存されません。が、手動でおおむね何とかできます。
ディスク上のデータに変更が無い上に、netatalkと違いどちらもMacから読み書きする以上、何か問題が出るとは正直考えてもいなかったのですが、出ました。
まず、今回はZEVOがインストールされているMac上から「zevo.txt」というファイルを作成し、カスタムアイコン・ラベルを持たせました。これを作成元のMacから見ると以下のようになります。
$ ls -l@ total 0 -rwxrwxrwx@ 1 b00t wheel 0 3 30 19:57 zevo.txt com.apple.FinderInfo 32 com.apple.ResourceFork 222790 com.apple.metadata:kMDLabel_26x2uentpjgt7lka65qdcazuya 50しかし、このファイルが含まれるプールをO3XがインストールされているMac上から見ると、アイコンもラベルも表示されません。
ターミナルでの表示が以下のようになっています。
$ ls -l@ total 4 -rwxrwxrwx@ 1 b00t wheel 0 3 30 19:57 zevo.txt com.apple.ResourceFork 222790 com.apple.metadata:kMDLabel_26x2uentpjgt7lka65qdcazuya 50なんと、com.apple.FinderInfoが消滅しています。ZEVOで再インポートすると問題なく見えるので、正確には見失っています。一方、O3Xから同様に作ったo3x.txtをZEVO側から見ると以下のようになります。
$ ls -l@ total 0 -rwxrwxrwx@ 1 b00t staff 0 3 30 19:45 o3x.txt com.apple.ResourceFork 241097 com.apple.metadata:kMDLabel_kqde5prblvaibjifrcn4saxjwi 50 com.apple.FinderInfo -1今度は、com.apple.FinderInfo -1とサイズが正しく計算できていません(そしてアイコンもラベルも表示されない)。なんにせよ、ZEVOかO3Xで拡張属性、少なくともcom.apple.FinderInfoの扱いに差異がある(もしかするとどちらかが間違えている)ようです。
個人的には、このあたりの挙動を考えるとZEVOがバグってるんじゃ?と思ってしまいます。
そして、このcom.apple.FinderInfoが読めないのが色々とトラブルを引き起こしています。
まず、ラベルについてですが、ラベル付きファイルは各色ごとにcom.apple.metadata:kMDLabelから始まる拡張属性を保持しているのですが、実はFinderでの表示に関係しているのcom.apple.FinderInfo内のラベル情報の方で、こちらの拡張属性の存在意義は謎です(消してもラベルは見えたまま)。謎というのは世間一般的に謎というか個人的に知らないというだけですが・・・
ともかく、com.apple.metadata:kMDLabelが残っていようとcom.apple.FinderInfoが読めない時点でNGです。
また、カスタムアイコンについてはアイコンデータはcom.apple.ResourceForkに格納されているものの、「カスタムアイコンがResourceForkに入っている」という情報自体はcom.apple.FinderInfoに入っているので同様に問題が起こります。
つまり、このcom.apple.FinderInfoをなんとかしないとZEVOからO3X移行時に拡張属性の多くが見かけ上消えてしまうわけです。
というわけで、なんとかしましょう。
とは言っても、32バイトからなるcom.apple.FinderInfoの各バイトがどの情報に対応しているかはわからない(というか調べる気が起きない)ので、O3Xでインポート後に見えるその他の拡張情報から正しいcom.apple.FinderInfoを作って書き込むことは難しいと思います。少なくとも自分には無理です。
なので、方針としてはZEVOで稼働している時点で各ファイルのcom.apple.FinderInfoを全部書き出しておき、O3Xでインポート後に書き戻すという手順になります。
方針としては
ステップ1:xattr -r /Volumes/pool | grep FinderInfo でcom.apple.FinderInfoを持つファイルリストを作る
ステップ2:xattr -x -p com.apple.FinderInfo /Volumes/pool/path/to/file でファイルリスト上のファイルからcom.apple.FinderInfoの16進値を取得・保存
ステップ3:O3Xに移行後、保存した16進値をxattr -x -w com.apple.FinderInfo (hex) /Volumes/pool/path/to/file で書き戻す
という感じです。
そしてできたものが以下のとても汚いスクリプト(xattr.rb)
#!/usr/bin/env ruby # coding: UTF-8 if `id -un`.strip != "root" puts "please use this option with root privilege." exit end dir = File.expand_path(File.dirname(__FILE__)) + "/work" `mkdir -p #{dir}` case ARGV[0] when "1st" if ARGV[1] != nil `xattr -r #{ARGV[1]} | grep FinderInfo > #{dir}/finderInfo.txt` else puts "usage: sudo ./xattr.rb 1st|2nd|3rd [fullPathFor1st]" exit end when "2nd" files = Array.new filesTxt = open("#{dir}/files.txt", "w") open("#{dir}/finderInfo.txt").each_line do |line| filesTxt.puts "\"#{line.split(": ")[0]}\"" end filesTxt.close hexHash = Hash.new { |h, k| h[k] = Array.new } path = "" hex = "" `cat #{dir}/files.txt | xargs xattr -x -p com.apple.FinderInfo`.each_line do |line| if line.include?("/") hexHash[hex] << path if hex != "" path = line[0..-4] hex = "" else hex << line.gsub(/\s/, "") end end hexHash[hex] << path `rm #{dir}/files.txt` num = 0 xattrScript = open("#{dir}/xattr.sh", "w") hexHash.each do |hex, files| tempTxt = open("#{dir}/temp#{num}.txt", "w") files.each do |path| tempTxt.puts "\"#{path}\"" end tempTxt.close xattrScript.puts "cat #{dir}/temp#{num}.txt | xargs xattr -x -w com.apple.FinderInfo #{hex}" num += 1 end xattrScript.close `chmod +x #{dir}/xattr.sh` when "3rd" `#{dir}/xattr.sh` else puts "usage: sudo ./xattr.rb 1st|2nd|3rd [fullPathFor1st]" endsudo ./xattr.rb 1st|2nd|3rd という使い方で、上記ステップに対応した各引数を与えながら都合3回実行することになります。ステップ1では対象データセットのフルパスも渡します。
つまり、ZEVOが動いている状態で
$ sudo ./xattr.rb 1st /Volumes/path/to/pool $ sudo ./xattr.rb 2ndと実行し、O3X移行後に
$ sudo ./xattr.rb 3rdと実行することになります。3段階実行のためにworkディレクトリを作ったりworkの中にcom.apple.FinderInfoの16進値ごとにファイルを生成したりする相当汚いスクリプトになってますが、とりあえず自分の環境では動いたし、無いよりはマシかと・・・
正直かなり適当なスクリプトな上にruby必須なので気まずいのですが、上の情報を見てイチからなんとかするよりはまだ楽かなと。
ZEVOが動いてる=Mountain Lion以下=標準のrubyが1.8=多分1.9入れないと動かない、というあたりも残念ですが。
まあ、それ以前にこのスクリプトを使うにしろ使わないにしろ、拡張属性の読み書きをする時点で多分xattrコマンドをbrewなりで入れるのが必須になると思います。
上の情報を読んでもっとスマートな解決方法があるぞ!と思った方は教えていただけると幸いです。
netatalk側だったらapple_dumpコマンドでFinderInfoの中身もdumpしますよ。
返信削除おお、これだとFinderInfoの各バイトが示してる内容もわかりそうですね。
返信削除