2012/12/13

GPO でレジストリをいじる

事の発端は IE9。気がついたらなにやら調子が悪くなり、調べたらどうやら GPUを使ったハードウェアレンダリングが有効になっていた。

VMware の仮想マシンは 3Dサポート機能を有効にすることで OpenGL, DirectX といったGPUを有効活用するAPIが利用可能になるのだが、私の Windows7 ではこれを無効にしていたため、存在しないGPU相手になにやらやっていて、タイムアウトが起こるまで不調が続いたという感じだ。

対処については以下の通り。インターネットオプションの詳細より無効化できる。
http://support.microsoft.com/kb/2618121/ja

が、問題はこの設定は GPO で簡単には配布できないということだ。

http://technet.microsoft.com/ja-jp/library/gg699401.aspx より
Internet Explorer 9 には、ハードウェア アクセラレーション (GPU レンダリング) を無効にするポリシーは用意されていません。必要な場合、グループ ポリシーの基本設定を使用してハードウェア アクセラレーションを無効にできます。HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main キーでレジストリ値 UseSWRender を設定します。グループ ポリシーの基本設定の詳細については、「グループ ポリシー ツールによるブラウザー設定の管理」を参照してください。
「グループポリシーの基本設定」でできるとあるが、こちらで動いてる ActiceDirectory のドメインコントローラが Windows Server 2003 のためか、「Internet Explorer のメンテナンス」などのメニューにそれを見つけることができなかった。

あまり時間もなかったのと、ユーザへ個別に .reg を配ったり .bat ファイルを実行させるのも気が引けたので、adm テンプレートを作って強制的に適用するようにした。

; IE9 HW Accesll
CLASS USER
CATEGORY !!IE9SWRender
KEYNAME "Software\Microsoft\Internet Explorer\Main"
POLICY !!IE9SWRenderConfig
    EXPLAIN !!IE9SWRenderExplain
    VALUENAME "UseSWRender"
    VALUEON NUMERIC 1
    VALUEOFF NUMERIC 0
END POLICY
END CATEGORY
[Strings]
IE9SWRender="IE9 SW Rendering Configuration"
IE9SWRenderConfig="IE9 SW Rendering Configuration"
IE9SWRenderExplain="Use SW Render insted GPU"


作ったのは上記の通り。adm ファイルの書式については解説は不要だろう。

要するに「HKCU\Software\Microsoft\Internet Explorer\Main」の「UseSWRender」の値を DWORDで1か0かを設定するというシンプルなものだ。

ただし、実はこれではうまくいかない。というか表示されない。

諸々試したが、Software\Policies 以下でないパスへの操作については、GPOエディタでデフォルトでは表示されないようだ。

この通り定義したはずの POLICY項目が表示されない

これについては、右クリックして「表示」から「フィルタ...」を選択、


「完全に管理されているポリシー設定のみを表示します」のチェックを外すと見える。


ただし、表示されるようにこのポリシーは適切に管理されるとは限らない。
たとえば「無効」にも「未設定」にもせずにこの adm を削除したりすると、レジストリの中に設定がそのままごみとして残ってしまう恐れがある。


分かって使う分には問題ないが、あまりお勧めはできないこと、わざと表示していないことを察するべきだろう。






2012/10/30

VMware Fusion 5 Professional を買うと VMware Player が商利用サポートされる

VMware Fusion はバージョン5になってから通常版の「VMware Fusion5」とプロフェッショナル版の「VMware Fusion 5 Professional」に分かれた。

それぞれの機能比較は VMware 社のページにあるので見て頂ければと思う。

個々で興味深いのは「VMware Fusion 5 Professional は、実績のある VMware Player が含まれている」という記述だろう。VMware Fusion 5 Professional のライセンスキーは VMware Player にも投入でき、どちらをアクティベーションすることもできる。

無償の VMware Player をアクティベーションして何の意味がある?と思われるかも知れないが、これは VMware Fusion Professional の正規の機能であり、保守によるサポート範疇に含まれる、というのがミソだ。

通常の VMware Player は個人利用のみ無償であり、雑誌掲載や商利用などについてはこれまでも申請が必要だった。が、この申請がややこしいのもあり、VMware Workstation を購入するというのが現実的には行われていた。単に仮想マシンを実行できれば良く、Workstation のもつ様々な機能を使う必要がなくても、だ。

そこで、VMware Fusion 5 Professional を購入し、そのライセンスを Mac ではなく WindowsPC に割り当て、VMware Player をインストール、利用する、という形態をとることで VMware Player をより簡単に、より安価に商利用で使えるようになった訳だ。

VMware Fusion 5 Professional はライセンスキーのみでの購入ができ、ボリュームディスカウントも存在する。通常のインシデントベースのサポートだけではなく、平日8-20時でのサポートとサブスクリプションも用意されている。これは Mac むけもさることながら、商用版 VMware Player としての使われ方も想定してのことだろう。


2013/9/14追記:

VMware Fusion6, Workstation10, の公開にともない、VMware Player もバージョンアップし VMware Player6 になった。 この Player6 では個人用途で無償でダウンロードできる通常版に加え、商利用がサポートされた PlayerPlus というライセンスが新たに用意された。

ただし、VMware PlayerPlus は現時点では VMware社のオンラインストアでしか購入することができない。中小企業でごく小規模に使う場合はオンラインストアで購入も悪くはないが、ある程度の規模で導入しようとするとボリュームライセンスでの購入が避けられなくなる。

この場合は、やはり VMware Fusion Professional を購入し、Windows/Linux PC に割り当て、VMware PlayerPlus として使うという形態になる。


2012/10/28

XP から Windows8 にアップグレードするとNICが認識されなくなるのとその対処

Windows8 の発売の翌朝だが、セミナーの講師をしていたところ、お客様より「今回のセミナーとは関係ないのですが...」と問い合わせを受けた。

どうもこのお客様のお客様、つまりはエンドユーザの方が VMware Fusion 上で、Windows XP を実行している仮想マシンに Windows8 をアップグレードインストールした、そうだ。すると、アップグレードは成功したもののNICを認識しないので何とかしてほしいと相談を受けたとのこと。

まあそんなチャレンジャーなアップグレード良くやるなぁと思ったが、とりあえずNICが AMD PCnet だからではないかと推測、いくつかの方法を話をした。

この土日、折角なので個人的に調べてみた。

● 再現試験

実際に Windows XP Professional から Windows 8 Pro にアップグレードインストールしたところ、それ自体は成功した。が、確かにNICを認識していないのが分かった。

手持ちの Windows XP はIDE接続の仮想ディスクにインストールされており、やはりNICは AMD PCnet (vlance というかフレキシブル) であった。

アップデート前に確認、NICは AMD PCnet エミュレーションだった
アップグレードしたところ、NICに×印がついている
クリックしたところ、認識しているネットワーク接続がないことが記載される
あとキャプチャを忘れたが、「ネットワーク接続」のデバイス一覧に何のネットワーク接続も表示されていなかった。


● 手っ取り早い対処法

手っ取り早く何とかしたい場合は、以下の手順を行えばいい。
なお、vmx ファイルを操作するという危険なことを行うので、バックアップは必ずとっておいてほしい
  1. 仮想マシンをシャットダウンし、VMware Fusion を終了させる
  2. 「仮想マシン名.vmwarevm」を右クリック、パッケージの内容を表示し、拡張子 .vmx ファイルを確認する
  3. 確認した vmx ファイルをテキストエディットなどで開き、一番下で良いので以下の行を追加する
    ethernet0.virtualDev = "e1000e"
  4. ファイルを保存する
  5. VMware Fusion を起動し、仮想マシンを起動する
要するにデフォルトのNICが AMD PCnet 互換から Intel EtherExpress 1000e 互換に行っている訳だ。

Fusion で作成したWindowsXP仮想マシンの場合、NICに対する virtualDev は指定されていない。指定されていない場合は AMD PCnet 扱いする。一方、Fusion で Windows8 仮想マシンを作成した場合は、上記の行が追加されており Etherexpress1000e 扱いされる。
VMware Workstation などでは NIC のタイプを指定することができるが、Fusion では簡単に指定する方法がない。なので、ここでは .vmx ファイルを直接編集、修正をしている。

なお、起動直後はまだNICは認識されない。しばらく待ってると下図の様なエラーが表示され、さらにしばらく待つとNICが追加される

しばらく待ってるとこの警告が出る
さらに待つと「ネットワーク接続」にNICが現れる
と同時に、右側に図にあるような選択画面が表示される

● 余談

なお、私の WindowsXP 仮想マシンは、仮想ディスクがIDE接続だったためさして問題なくアップグレードできたが、SCSI接続の場合アップグレードに失敗する?らしい話も聞いている。

vSphere で WindowsXP 仮想マシンを作成すると、デフォルトでは BusLogic SCSI HBA を経由して仮想ディスクが接続される。おそらく、AMD PCnet のドライバーがなくなり上記のような問題が起こったように、BusLogic SCSI HBA のデバイスドライバーもなくなったのだろう。

だいたいにおいて、BusLogic SCSI HBA のエミュレーションは過去のOSとの後方互換に使われている。WindowsServer 2003 などでは LSI Logic のより新しいSCSI HBA が使われ、Windows7, 2008R2 などでは LSI Logic SAS HBA のエミュレーションが行われる。

おそらく、LSI Logic HBA のエミュレーションなら Windows8 でも利用可能なのだろうと思われる。

WindowsXP でも LSI Logic HBA エミュレーションを使うことは可能だが、インストールメディアに LSI Logic のSCSI HBA のドライバーが入ってないためそのままでは新規インストールに失敗する。LSI Logic のサイトなりからデバイスドライバをダウンロード、仮想フロッピーメディアに展開しておき、インストール時に追加するといい。

この WindowsXP で LSI Logic HBA のエミュレーションを使わせるのは VMware View などのVDI環境でデスクトップ仮想マシンのパフォーマンスを上げるために必要な基本テクニックだ。


2012/08/23

VMware Fusion 5 リリース、でも、買うのはちょっと待った方が

本業に追われてだいぶご無沙汰してしまった。

さて、米国時間で 8/23に、無事 VMware Fusion 5 と VMware Workstation 9 がリリースされた。

http://www.vmware.com/products/fusion/overview.html

Fusion 5 では Windows8 への最適化など新しい機能がある。また、私自身はまだ確認していないが、Fusion 4 に比べ複数の仮想マシンを実行した際のメモリ消費が抑えられているという体験談を聞いている。vSphere にある透過的メモリ共有に類する技術を使っているのか、はたまたこれまで無駄に消費してたのがダイエットしただけなのかは不明だが、確認を取ってみたいところだ。

また、Professional Edition ができたのも1つの特徴だ。
http://www.vmware.com/products/desktop_virtualization/fusion/professional.html

ネットワークエディタは Workstation ではおなじみだが、vmnet0-8 までのネットワークに任意の設定をする事が可能になるというものだ。
Fusion ではこれまで vmnet0 をブリッジ、vmnet1 をホストとの通信だけが可能なネットワーク、vmnet8 をNATを行うネットワークとして使用してきた。が、あいている vmnet2-7 に任意の設定のネットワークを作ってNATや仮想マシン間ネットワークを個別に用意できる。また、vmnet1 や vmnet8 のDHCPで配布されるIPレンジを変更なども可能になる。

制限された仮想マシンを作成できるらしいのもポイントだ。VMware Workstation ではかつて VMware ACE という拡張機能があり、暗号化され利用者が設定を変更のできない仮想マシンを作ることができた。暗号化自体は Fusion 4 よりサポートされていたが、より細かい制約が作れるようだ。

管理者が制約を作り、利用者に仮想マシンを配布する、といった用途が期待できる。

価格の方は、VMware Store で Fusion 5 が $49.99、Fusion 5 Professional が $99.99 だ。Fusion 5 へのアップグレードはなく買い直しになる模様。

一方、 Fusion 5 Professional については Fusion 3,4 からのアップグレードパスがある。こちらも $49.99 なので、すでに VMware Fusion を使ってる方は Professional 版にして細かい機能を楽しんでみるのもいいだろう。

また、Fusion 2012 TechPreview を使ってきたβテスターには、後ほどプロモーションコードが配布されるようだ。このパブリックベータでテストしてきたユーザは、購入を少し待った方がいいだろう。

なお、Fusion に限らず VMware 製品は、ダウンロードしてそのまま実行すると評価版として一定期間動作する。なので、すぐに買わなくてもしばらくは評価版として利用が可能だ。
業務で使うなど明確な商利用などの都合がない、パブリックベータを試してこれたような個人ユーザなら評価版で待ってても問題はないだろう。

2012/06/27

Macbook Air で Windows XP を使う場合のライセンス

少々厄介な話になったので少しメモしておく。

Macbook Air や、今回発表になった Macbook Pro Retina ディスプレイモデルでは USB や Thunderbolt といったいくつかのインターフェイスを除いて拡張の余地がない。
たとえばメモリを増設したり、HDD/SSD を交換することが原則的にできなくなっている。


このため、 DSP版の Windows を購入することがほぼ不可能になっている。

本来ホワイトボックスPC向けに用意されている DSP版の Windows は安価な一方、サポートは販売店持ちとなり、かつ特定ハードウェアとの同時購入でそのハードウェアを使用しているコンピュータでの利用のみが許される。


特定のハードウェアは何でも良いという訳ではない。たとえば以下は DOS/V パラダイスのページだが、バンドル対象製品は、CPU、メモリ、HDD、SSD、光学ドライブ、マザーボード、ビデオカード、その帆は拡張カードと言う感じで「本体に組み込まれるもの」が前提となっている。
http://www.dospara.co.jp/5info/share.php?contents=info_win_dsp

USB接続のHDD など、本体を構成しない外付け機器やケースなどは対象外となっている。


これまで、巷で販売されている Windows ライセンス付きの VMware Fusion 製品は、その多くが「DSP版とのバンドル」で、よく見るとメモリなどがセットに含まれている。
ライセンス上は、そのメモリを使用した MacやPCでのみ、その Windows ライセンスは使用できる。


まあもちろん、一々そのメモリ(ないしは他の特定ハードウェア)を搭載しているかを確認する術はないし、確認して販売しているかは微妙、だろう。



しかし、Macbook Air、 Macbook Pro Retina ディスプレイモデルはそもそも拡張の余地がない。「できない」所に販売するのはさすがにできないだろう。


Macbook Air や、今回発表になった Macbook Pro Retina でぃすぷれいもでるといった本体と同時に Windows ライセンスを購入」しない限り、後から仮想環境や BootCamp 用の OSライセンスをDSP版で購入することはできない訳だ。
なお、聞いた限り銀座などの AppleStore では  DSP版の Windows は扱ってないようだ。



じゃあ、大人しくパッケージの Windows を買えばいいかというとこれも厄介な話がある。
なぜなら、パッケージの Windows にはダウングレード権がないからだ。

マイクロソフトの製品は、新バージョンが出ると旧バージョンの販売は終了してしまう。Windows7 が販売されている現在、Windows XP や Vista のパッケージはもう購入できない訳だ。(希に不良在庫がぽろっと出ることはあるが)

Windows7 を使いたい場合はそれでいいが、 仮想環境上で Windows XP を使いたい場合、ダウングレード権のないパッケージの Windows ではその役に立たないのだ。
(DSP版にはダウングレード権が存在する。)


あともう一つの方法はボリュームライセンスでの購入になる。ボリュームライセンスは法人利用を前提としたライセンスだけのまとめ買いシステムだが、別に個人が利用できない訳ではない。利用例は以下ページを参照してほしい
http://pc.watch.impress.co.jp/docs/topic/feature/20090911_314639.html

ボリュームライセンスで販売されるデスクトップ版の Windows は「アップグレード」のみで、フルライセンスは存在しない。つまりコンピュータにアップグレード対象となるOS が入っていないと利用できない。自作PCなどでOSなしで作られたPC にはインストールできない訳だ。

では Mac にも入れれないのでは?と思われるが、実は「アップグレード対象」には OS X も含まれるというのがポイント。これは以下ページに記載されている。

http://www.microsoft.com/ja-jp/licensing/about-licensing/windows7.aspx#tab=4


ボリュームライセンスの利用には最低でも3アイテムの購入が必要なのが少々厄介だが、それは先の impress  のページを見て対応してほしい。


まとめると、後で拡張ができない、DSP版の Windows が買えない Macbook Air や Macbook Pro Retina ディスプレイモデルでは、以下の手段での購入となる

  1. Macbook Air/Pro と同時にDSP版を購入する
  2. ボリュームライセンスの Windows 7 を購入する
  3. ダウングレード権を諦めて Windows 7 を使用する
  4. (開発/テスト/デモ限定)MSDN/Technet を利用する


2012/06/03

Mac で ESXi は動くのか?(2)

前回、Apple ハードウェアで ESXi が起動できるのは、公式には Xserve (Early2009)のみ、非公式でも Xserve とほぼ同じチップセットを採用した MacPro のみ、と記載した。

しかし世の中すごい人はいるもので、とうとう Mac mini で ESXi の起動に成功したようだ。

以下にあるが、要はNICドライバーを追加してこれまで認識しなかった Mac mini のオンボードNICを認識させたようだ。

http://paraguin.com/2012/01/10/the-mac-mini-vmware-esxi-5-server-part-2-installation/

これは、実機を入手したら確かめてみたいと思う。

2012/05/13

Fusion で Mac OS X のカーネルデバッグ

● Kernel space is the last frontier 

...とまでは言わないが、しかしカーネルコードをみたりいじったりするのは非常に楽しい。一方で、カーネル空間でのミスは簡単にOSクラッシュを引き起こす。なんだかんだいって OSがなんとかしてくれるユーザランドでのアプリケーション開発やブラウザの上のスクリプト書きとは違う厄介さがある。

通常、カーネル内に組み込まれるコードのデバッグには2マシンデバッグが行われる。開発中のコードを実行するテストマシンとは別にデバッグ用のマシンを用意し、何らかの方法で接続、デバッグ用のマシンでデバッガを動かし観察するというものだ。接続方法は、昔ならシリアルケーブル、最近だと(少々癖はあるが) TCP/IP が利用できる。
もっとも、私はこれまで2マシンデバッグできる贅沢な環境でコードを書いたことがない。昔作った W-ZERO3用のシリアルドライバは、気合い一発の printf デバッグだった...、ファイルに書き出す前に落ちるので、WindowServer 殺してコンソールモードにしてログをはき出させ、死んだ瞬間の画面をメモって開発するという。今にしてみれば呆れた方法だった。

Mac OS X はネットワーク越しの 2マシンデバッグをサポートしている。方法については Mac OS X のドキュメントに記載があるので読んでみると良い。

とはいえ、2台もMacを横に並べて開発を行うのは少々面倒だ。仮想環境を使えばこの2マシンデバッグも簡単にできるのではないか?という事で試してみた。


● 仮想環境でカーネルデバッグを行うには

まず Mac Developer Program には入っておいた方がいい。年 $99 の有償プログラムだが、その価値はあるだろう。

開発環境である Xcode は無償でダウンロードできる。なので有償プログラムに入らなくてもアプリケーションや KEXT の開発は出来なくもない。ただし Xcode 以外の開発リソース、例えばカーネルシンボルなどその他配布物が有償登録せずに手に入るかは確認していない。


Fusion を使った2マシンデバッグの大枠の手順は、以下のページに既に記載されている。先の Apple のドキュメントとあわせて読んでおくといいだろう。
"Reverse Engineering Mac OS X : Mac OS X Kernel debugging with VMware"
http://reverse.put.as/2009/03/05/mac-os-x-kernel-debugging-with-vmware/
上記の記事は、まだ Lion のリリースされていない 2009 年のもののため、OS X のインストール方法が少々あやしいことを書いていたりするが、さくっと忘れてほしい。Lion の場合は インストールアプリケーションの下から InstallESD.iso さえ取り出せれば、細工せずとも普通にインストールが可能だ。

上記記事を参考に、私のやった手順を以下に記す。

以降、Xcode4 で開発を行い、ビルドを実行するホスト環境を Develop Machine、実際にコードを実行しテストを行うゲスト環境を  Target Machine と書く。


● ゲスト環境( Target Machine ) での準備

まず、仮想環境上に Mac OS X Lion をインストールする。

アップデートなどが終わったところで一度シャットダウン、停止状態でスナップショットをとっておく。今後何度も何度もクラッシュさせることになるので、安全な状態を確保しておくのは必要なことだ。

ゲスト環境のネットワーク接続は NAT のままで構わない。ただ、IPアドレスはDHCPではなく固定IPに書き換えておいた方が楽かも知れない。Fusion の DHCPサービスは概ね同じIPアドレスを割り当ててくれるが、変わると少々ややこしいことになるので気になる場合は固定IPに変更をしておくといい。

Develop Machine から Target Machine へファイルをコピーする手段を整えておく。ファイル共有を使ってもいいし、scp をつかっても良い。私は  Target Machine のアカウントの .ssh/authorized_keys に Develop Machine での自分のアカウントのSSHの公開鍵を入れておき、パスワードなしで簡単コピーできるようにしておいた。

続けて、カーネルデバッグ特有の設定を行う。

Apple のドキュメントだと NVRAM に引数を設定するようになっているが、仮想環境では nvram ではなく /Library/Preferences/SystemConfiguration/com.apple.Boot.plist に記載する。このファイルは管理者権限ではないと編集できないので、sudo  を使って vi なり nano なりで編集して欲しい。

デフォルトでは、
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Kernel Flags</key>
<string></string>
</dict>
</plist>
となっているのを
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Kernel Flags</key>
<string>-v debug=0x04 pmuflag=1</string>
</dict>
</plist>
に修正する。「-v」は verbose オプションで、起動時に黒画面に起動メッセージが表示されるようになる。

-v を指定すると、起動中のメッセージが表示される
さらにカーネルクラッシュした場合に、画面の上にコンソールメッセージを出して止まってくれる。一般ユーザには忌み嫌われるクラッシュ画面だが、カーネル開発をしているときにはこの断末魔の悲鳴は重要なヒントになる。

通常のクラッシュ時の画面
debug= でカーネルデバッグを指定した場合
MACアドレスとIPアドレスが表示されているのが分かる
-v オプションを指定した場合

debug=0x04 はデバッグオプションの設定で、Apple のドキュメントによると以下の通りだ

シンボル
フラグ値
意味
DB_HALT0x01OS起動時に一時停止を行い、デバッガーの接続を待つ
DB_PRT0x02コンソール画面に kernel 内の printf 出力を表示させる
DB_NMI0x04NMI (Non Maskable Interrupt) 信号でOSを一時停止しデバッガーに落とす
DB_KPRT0x08kprintf の出力をシリアルポートに出す
DB_SLOG0x10外部のGDBではなく組み込みのddb(kdb)をデフォルトデバッガにする
 (ただし、通常のDarwinカーネルにddb は組み込まれていない)
DB_ARP0x20デバッガに ARP テーブルの操作やルータを介した通信を許す(セキュリティーホールになるので注意) -- なお、どのカーネルにも本機能は含まれていない
DB_KDP_BP_DIS0x08古いGDBをサポートする
DB_LOG_PI_SCRN0x08グラフィカルなクラッシュ画面を表示させない

先の Reverse Engineering Mac OS X のドキュメントでは debug=0x01 を指定している。

 Target Machine の起動時に一時停止されるので、その間に Develop Machine の GDB で接続するというものだ。その理由として「仮想環境でどうやって NMI を起こせばいいか分からなかった(because I couldn’t find a way to create NMI events inside the virtual machine.)」とある。

確かに通常は「Command-Option-Control-Shift-Escape」か「Command-Power」キー操作でNMIが発生すると Apple のドキュメントにはあるが、仮想マシン内ではこれはうまく動かないようだ。

そこで Reverse Engineering Mac OS X では起動時に一時停止する手段をとったが、これだと起動のたびに GDB の atacch が必要になり面倒だ。そこで、強制的にデバッガを起動する KEXT 「PseudoNMI」を用意した。

ソースコードは GitHub に置いたので好きにみてほしい。
https://github.com/shiro-t/PseudoNMI

使い方は以下の通りだ。

  1. この PseudoNMI.kext をダウンロード
  2. パーミッションなどを調整する(所有権は root:wheel で、読み取りと実行のみに)
  3. sudo kextload ./PseudoNMI.kext」でカーネルに組み込む。
  4. sudo sysctl -w debug.pseudo_nmi=1」を実行する

sysctl を実行すると、内部的にNMIが発行されたのと同じ処理が動く。debug=0x04 が設定定されていれば外部デバッガーの接続待ちになり、そうでなければクラッシュする。


接続は TCP/IP を通じて行われる。ただし、そのままでは上手くいかないので、あらかじめ ARPテーブルに設定が必要だ。

ARP テーブルとは IPアドレスと Ethernet でのハードウェアアドレス(MACアドレス)を紐付けする対応表で、通常はカーネルが自動的に保守をしている。
カーネルは知らないIPアドレスへの通信が行われる際に ARP というプロトコルを使ってそのIPアドレスに対応するMACアドレスを手に入れている。その都度手に入れていたのではネットワークに負荷がかかるので、カーネル内のメモリに一定期間保管している。このARPテーブルの内容は「arp -a」コマンドで確認できる。

ARPによる処理は自動的に行われるので通常は気にする必要がない。ただ、デバッガ起動時はどうも自動的に手に入れた値を全てクリアしてしまっているようで、そのままでは通信できなくなる。そこで、あらかじめ固定的な値を組み込んでおく必要があるのだ。

手順としては、まず、Develop Machine 側の IPアドレスとMACアドレスを手に入れる。これは仮想マシンがどの方式でネットワークに繋がっているかによる。NAT の場合は vmnet8 というホスト側の仮想NICを通じて仮想マシンと繋がっている。このNATネットワークは 「192.168.x.0/24」のネットワークで、x の部分はインストール時に決定される。

そして、192.168.x.1 はデフォルトルータとして使われ、Develop Machine そのものの通信は 192.168.x.2 で行われる。
192.168.x.2 に対応する MAC アドレスは、Develop Machine  ifconfig vmnet8 を実行するか、 Target Machine 側で arp -a で ARP テーブルを表示させて確認できる。

IPアドレスと MAC アドレスの対が分かったら、 Target Machine 側で以下コマンドを実行する
sudo arp -s 192.168.x.2 aa:aa:aa:aa:aa:aa
これでOSが再起動されるまで削除されない ARPテーブルの設定がなされる。
仮想マシンのネットワーク構成を変えない限りこの値は一定のため、以下設定を /Library/LaunchDaemons におくことで起動の都度 自動設定させることも可能だ。


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>jp.nest.debug.static_arp</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/sbin/arp</string>
                <string>-s</string>
                <string>192.168.203.2</string>
                <string>0:50:56:f6:cc:a8</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
</dict>
</plist>

このファイルを /Library/LaunchDaemons に配置したあとでリブートしてもよし、「sudo launchctl load /Library/LaunchDaemons/jp.nest.debug.static_arp.plist」を実行して読み込ませても良い。

これで、ゲスト側の準備は完了だ。


● ホスト環境(Develop Machine) でのデバッグ設定

さて、ホスト側の設定にうつる。

まず、Kernel Debug Kit を手に入れる。Kernel Debug Kit はシンボル情報(バイナリ中のどこがどの名前の関数に対応するかなどデバッグに必要な情報)が一式整ったものだ。OS のバージョンごとに存在するため、Lion の場合 kernel_debug_kit_10.7.3_11d50.dmg を手に入れる。入手先は http://developer.apple.com/sdk だ。

ダウンロード後、ダブルクリックしてイメージをマウントしておく。

必要に応じてカーネルのソースコードも手に入れておいた方がいいだろう。

http://opensource.apple.com から適切なバージョンを選んで、xnu-<xnuのバージョン> を選択、ダウンロードする。Lion (10.7.3) の場合は「xnu-1699.24.23」がそれだ。tar.gz アーカイブで手に入るので適当なところに展開しておく。カーネルソースがあれば、デバッガでソースコードを参照できる。


次に、ゲストで行ったのと同じ ARP テーブルの設定をホスト側でも行う。ゲスト側のNIC(en0)のIPアドレスと MAC アドレスを割り出した後
sudo arp -s <IPアドレス> <MACアドレス>
を実行する。Develop Machine側 vmnet8 のIPアドレスは常に一定だが、ゲスト( Target Machine )側の en0 のIPアドレスは、デフォルトではDHCPのため変わることがありえるので注意だ。冒頭にも書いたように、変わるのが面倒な場合は固定IPアドレスにしてしまうといい。

ここで準備は終了だ。

● ターゲットとなる KEXT を準備する

カーネルデバッグを行う最大の理由は、KEXT のデバッグであろう。

Xcode で開発を行い、KEXTをビルドする。ビルドすると KEXT と同じところに .sym のついたそのKEXTのシンボルファイルが生成されるのでこれも取得しておく。

開発した KEXT を  Target Machine にコピーする。
コピー後には 「所有者とグループを root:wheel に」「グループとその他の書き込み権限を削除」を忘れないように。セキュリティ上の都合から権限が甘い KEXT は読み込まれないようになっている。

KEXT が正しくロードできるかについては、kextutil というコマンドで確認できる。
sudo kextutil Foo.kext
なお、私はこの kextutil でチェックしてる時にクラッシュしたことがある。
出来の悪い KEXT だとそういう可能性もあるので注意してほしい。


● カーネルデバッグを行う

Develop Machine 側で GDB を立ち上げる
gdb /Volumes/KernelDebugKit/mach_kernel
Kernel Debug Kit をマウントしていると、/Volumes 以下にマウントされているはずだ。
以下コマンドを入力、準備を行う
gdb$ target remote-kdp
以下のコマンドを入力だけ行い、リターンを押さずに置いておく

gdb$ attach <Target Machine のIPアドレス>

 Target Machine  側にうつって以下コマンドを実行、PseudoNMI が存在するのを確認する
sysctl debug.pseudo_nmi
正常ならば「debug.pseudo_nmi: 0」と返ってくるはずだ。
存在していれば以下を実行する
sudo sysctl -w debug.pseudo_nmi=1
すると、実行した瞬間にゲストOS上の Mac OS X の実行が停止される。
すかさず Develop Machine 側で入力だけしておいた attach コマンドを実行する。

ARP テーブルが固定化されており、ちゃんと通信が出来るなら即座に「Connected.」と表示されプロンプトが表示される。もしそうならない場合は、ARPテーブルの設定忘れなので改めて設定をおこなってほしい。

接続できたら「gdb> c」 と c(ontinue) コマンドを実行する。すると、止まっていたゲストOSの実行が再開される。

これでGDBが接続された状態になっている。あとはブレークポイントを設定するなり、クラッシュしたらスタックトレースを引っ張るなりいつものデバッグができる。


2012/04/29

Bhyve が Fusion 上で動いた




動いたので記念撮影。このあと起動し、ちゃんと root でログインできている。

細かいことはもう少し詰めてから書くが、ポイントは
  • 急がば回れ。多分今の -curent なら深く考えなくても Fusion 上で動くのでソースからビルドが結局は近道
  • http://bhyve.org にバイナリきっとあるけど、これそのままでは Fusion 上で動かない
  • 問題は現在の Bhyve のコードでは治っている
  • 要点? vhv ではVM_EXIT_SAVE_PAT と VM_EXIT_LOAD_PAT が非対応のため
というところだ。

適当に -current 引っ張ってきて手直しした vmm.ko をこちら においたので、もし試したい場合は以下の手順でいけるだろう。(要追試)

  1. (必要かはまだ絞り込めていないが)、とりあえず4GB はメモリを持った仮想マシンを作っておく
  2. FreeBSD 9.0R を普通インストールする
  3. http://bhyve.org にリンクされている bhyve-0.0.1r225757.tar をダウンロードする
  4. pkg_add <ダウンロードした bhyve-0.0.1r225757.tar> でインストールする
  5. /boot/kernel/vmm.ko を上記のパッチ済みのもので差し替える
  6. http://bhyve.org にリンクされているゲストイメージをダウンロードする。1GB/400MBどちらでもよい
  7. xz -cd <ゲストイメージ.tar.xz> | tar xf -  で展開する
  8. 出来たフォルダを # mv ./bhyve-guest-400mb /usr/bhyve-guest で /usr/ 以下に配置する(トップフォルダの名前をリネームするので要注意)
  9. /boot/loader.conf を作成、以下の情報を書き込む(2GBをホストに割り振る)
  10. hw.physmem="0x80000000"
    debug.witness.watch="0"
  11. 再起動して設定を生かす
  12. root で cd /usr/bhyve-guest から sh ./vmprep.sh でカーネルモジュールを読み込ませる
  13. sh ./vmrun.sh で仮想マシンを起動する

詳細なことはまた改めて書く。

2012/04/25

[余談] ファイルを探索後、そのファイルを検索する

ちと本日ネタになったので覚え書き代わりに書くとする。

本日みたある資料では、以下のような感じになっていた。
grep ERROR `find . -name "debug*.txt" -print`
これがいけないこと、というのを指摘したのだが分かってもらえなかったようなので何故いけないかをつらつら語りたいと思う。


ある程度 UNIXの経験がある人ならば「何だその話かよ」で終わる話だが、様々な面でこれは問題のある表現である。


一番簡単な問題は「溢れる」ということだ。コマンド行の固定長で上限ある。
このサイズは ARG_MAX という定数で定義されている。

例えば、Mac OS X 10.5.8 では以下の感じだ。
grep -R ARG_MAX /usr/include/
(中略)
/usr/include/limits.h:#define _POSIX_ARG_MAX 4096
/usr/include/sys/syslimits.h:#define ARG_MAX   (256 * 1024) /* max bytes for an exec function */
POSIX な定数だとわずか 4KB, そうでなくても 256KB 程度になる。これ以上は保証されない。

上記の find の書き方だと「カレントディレクトリ (.) とそこから下のサブディレクトリ」を再帰するので、debug.txt と書かれたファイルが下のディレクトリにあるなら容易に溢れる訳だ。溢れると、のたうち回った末にこんなエラーが表示される

/usr/bin/grep: Argument list too long.
計算機資源に優しくないのでやめろ感じる訳だ。

また、サブディレクトリを探す意図はなかったというかも知れないが、ならばシェルの補完でも十分だ。「 grep ERROR debug*.txt 」で間に合う。どうしてもバッククオートを使いたいなら「grep ERROR `ls debug*.txt`」とでもすればいい。


もちろん「溢れ」の可能性については前世紀から分かってる事実であり、このため find には頼もしい助っ人である「xargs」コマンドがついている。

上記の例を「悪い」見本で直すとこんな感じだ
find . -name "debug*.txt" -print | xargs grep ERROR
xargs は標準入力で渡されたリストを ARG_MAX を越えない程度に分割して、それを引数で渡されたコマンドの引数にして実行する。また、コマンドの実行が一々増えていいのなら

find . -name "debug*.txt" -exec grep ERROR {}\;
と書けばいい。-exec は find がマッチしたファイルパスの一つ一つに対して指定のコマンドを実行する。{} の部分がファイルパスに置換される。また、-exec の引数となるコマンド列の末尾は ; で終わるが、これがシェルに解釈されないように \ を入れる。-exec hogehoge {} \; まではイディオムであり、よく見かけると思われる。

個人的には、上記二つで普通のUNIX屋であると認識する。


で、より上位の人に「一々 -exec するな」か「マッチしたファイル名に空白がはいってたらどうする」かで突っ込まれるのもまた普通の話と思われる。

そう、xargs で引き渡された標準入力に、普通の英数字以外が混じっているとそこが「区切り」と見なされることがある。


で、だ。そんなことも、xargs を作ったような在りし日のUNIX屋にとっては想定内である。そのため、find には -print0, xargs には -0 オプションがある。正しいのは以下になるだろう。
find . -name "debug*.txt" -print0 | xargs -0 grep ERROR
find の -print0 オプションは -print とほぼ同じだが、区切り文字を '\0'、ヌル文字にしてくれる。空白や制御文字はファイル名に入れることは出来ても、ヌル文字は決してファイル名に現れない。このため、一つの検出されたファイルパスが間違って分割されることもない。

一方、ヌル文字が区切りであることを示すのに、xargs には -0 (ゼロ)オプションがある。find の -print0 での出力を xargs -0 は正しく解釈し、ARG_MAXに越えないだけにまとめてコマンド実行をしてくれる。

いつ頃から find -print0 と xargs -0 があったかは知らないが、私が駆け出しの頃にはすでにあったものだ。今日日の環境ならどこにでもあるだろう。

ファイル名に空白があるは、かつて Apple も iTunes のアップデートでミスった問題だ。
決して少ない訳じゃない。


決して新しい知識ではないのだから、ここまでは配慮して欲しいと思ったのが、本日ぐだぐだ言ってた理由だ。








2012/04/24

vExpert 2012

今年も辛うじて、vExpert 2012 を頂きました。ありがとうございます。


2012/04/14

VMware Tools のアップデート追記

昨日公開した VMware Tools のアップデート情報だが、間の悪いことにこれに関係するもう一つ新しいアドバイザリ VMSA-2012-0007 が出ていたので追記したい。

これは、Windows 向けの VMware Tools のフォルダの権限付けにミスがあり、これを突くことでゲストOS上の特権を奪えるというものだ。

上記のアドバイザリを参照して頂ければ分かるが、この脆弱性をもつ製品は非常に幅が広い。

  • VMware Workstation 8.0.1 とそれ以前
  • VMware Player 4.0.1 とそれ以前
  • VMware Fusion なら 4.1.1 とそれ以前
  • ESX/ESXi なら 3.5, 4.x, 5.0 

まぁ、要するにこの脆弱性への対応パッチやアップデートを含まれてない製品全て、ということになる。ホスト製品の場合はそれぞれ後継製品に、ESX/ESXi の場合は該当パッチを適用することで内蔵される VMware Tools に更新されるので、アップデートやパッチ適用後、Windows をゲストOSとする仮想マシン全ての VMware Tools をアップデートする必要がある。手間がかかるが必ず実施した方が良い。

なお、VMware Fusion 4.1.2 をダウンロード、その中の VMwareTools を確認したところ、バージョンは 8.8.3 (8.8.3.12575)、ビルド番号は 683185 のようだ。

2012/04/13

VMware Tools のアップデート

少々旧聞だが、VMware 製品のセキュリティアップデートを通知する Security Advisories & Certifications に掲載された VMSA-2012-0004, VMSA-2012-0005 にて 「Windows版VMwareTools に含まれるディスプレイドライバ(XPDM, WDDM双方)にてメモリ管理の脆弱性があり仮想マシン内の Windows で特権を奪われる可能性がある」旨が告知されている。

対策としてはパッチ適用(ESXi500-201112402-BG など)になるが、これは ESX/ESXi に含まれる VMwareTools のイメージをアップデートするだけだ。具体的にこのパッチでのアップデート事項は KB 2007672 を参照して欲しい。

すぐに気がつかれたかと思うが、ただパッチを当てるだけでは問題は解決しない。各仮想マシンの VMware Tools をアップデートする必要がある。
逆に言えば、パッチを当てなくても VMware Tools さえ最新版を入手、アップデートすればこの問題については回避できる。

最新版の VMware Tools (Windows版)は以下ページから入手できる。


x86(32bit)と x64(64bit)があるのでそれぞれ入手して欲しい。


また、VMSA-2012-0005 では VMware Workstation 等ホスト製品については問題がないとされているが、これはその環境で仮想マシンを動かしている場合に限られる。

VMware Workstation 7.1.5 より前、Player 3.1.5 より前、VMware Fusion 4 より前の各製品で作成、当時の VMware Tools をインストールしている仮想マシンを ESX/ESXi 環境に持って行った場合、VMware Tools のバージョンが古くてやはり問題が発生する。
もちろん、そもそも仮想マシンを ESX/ESXi 環境に転送しないなら問題はない。

対策としては、VMware Workstation なら 8へアップグレードする、7.x なら 7.1.5 にする、Player なら 3.1.5 をダウンロードしてアップデートする、VMware Fusion なら 4 を購入し、その上で VMware Tools をアップデートしておくといい。
とはいえ、仮想化製品をそうもアップデートできない、購入できない場合もあるだろう。その場合はやはり上記のページから VMware Tools をダウンロード、アップデートしておいた方が安全だ。


なお、VMSA-2012-0004 では同じ問題を記述しているが、こちらは VMware View に対するアドバイザリで、対策として「View 5.0 か 4.6.1 へアップグレード後、各仮想マシンごとの ViewAgent をアップデートする」という手順が記載されている。

脆弱性は VMware Tools 内のディスプレイドライバなので奇妙な話だが、View を使ってる場合は ViewAgent もあわせてアップデートしておいた方がいいだろう。


カスタム静止スクリプト

かつて VCB (VMware Consolidated Backup)のころ、アプリケーションレベルでの静止点を取得するためにスクリプトを走らせる機能が存在した。これがカスタム静止スクリプトだ。

これは VCB時代のドキュメントの仮想マシンバックアップガイド(PDF) の P.44 に記載がある。VCBによるバックアップ開始時に  %WINDIR%\pre-freeze-script.bat が実行され、終了時に %WINDIR%\post-thaw-script.bat が実行される。

ただ、当時試したところ動いている様子がなく気になっていたのだが、その時は急ぎ確認する理由もなかったのでそのままにしておいた。

そして、先日 カスタム静止スクリプトについて調べる機会ができたので少々確認をしてみた。

ご存じの通り、VCB のサポートは vSphere 4 までで終了し、現在では VADP (vStorage API for Data Protection) が利用されている。VCBはコマンドベースの技術でバックアップソフトからVCBのコマンド(vcbMounter.exe)を呼び出して連携をとっていたが、VADPはライブラリで提供され、バックアップソフトはこのライブラリのAPIをコールする事で連携をとっており、より密接な制御が可能となった。

さて、では VADPでカスタム静止スクリプトがあるかというと、まだ存在する。これについては、KB1006671が詳しい。

ESX/ESXi のバージョン カスタム静止スクリプトのパス
3.5U1 とそれ以前
%WINDIR%\pre-freeze-script.bat
%WINDIR%
\post-thaw-script.bat
3.5U2 とそれ以降
C:\Program Files\VMware\VMware Tools\backupScripts.d\
4.x %WINDIR$\backupScripts.d\
5.0
両方の場所を確認する
5.1, 5.5
%WINDIR%\pre-freeze-script.bat
%WINDIR%
\post-thaw-script.bat

なお、backupScripts.d フォルダはデフォルトでは作成されていないので、利用する場合は自分で作成する必要がある。backupScripts.d フォルダ以下にあるバッチファイルなどが全て実行されるが、その順序はバックアップ作成時はアルファベットの昇順(A-Z)で、終了時は降順(Z-A)となる。
Windows XP では 3.5U2 以降で実行していても旧来の pre-freez-script.bat 等が使われるようだ。

見ての通り、実は ESX/ESXi 3.5U2 以降でパスが変わっているのだ。これで当時うまく動かなかった理由が判明した。

私が VMware Infrastructure 3.5 を使い出したのは U2 の頃からで、それ以前は 3.0.3 を中心に 3.5 は様子見をしていたからだ。

なお、Linux など Windows 以外のOSの場合は、/usr/sbin/pre-freeze-script, /usr/sbin/post-thaw-script が実行されるようだ。これについては VMware DataRecovery 管理ガイドの P.8〜9 あたりに記載がある


追記: VCB サポートは vSphere 4.0 までではなく 4.1 までだったので訂正。そういえば 4.1 も VCB1.5u2 でサポートされていたのでした。
追記:20150106, 気がついたら対応表が変わってたのでこちらも更新

2012/04/08

Mac で ESXi は動くのか?

結論から言うと、「動作はする、サポート機種なら」となる。

サポート機種があるのか? といわれると1機種だけ実は存在する。Xserve だ。

VMware 社の HCL で確認すると「Xserve3,1」が記載されている。
しかし、多くの人は「Xserve3,1」というのが何かさっぱりだろう。

これは、Apple での「機種ID」を意味する。マックをお持ちの方なら、アップルメニューから「このMacについて」を選択、「詳しい情報」を押すと「Apple プロファイラ」というアプリケーションが立ち上がり、その Mac の詳細情報が表示される。

メインウィンドウで 「ハードウェア」の項目を選択、右側を見ると「機種ID」というのがあり、「MacBookPro6,1」とか記載があるはずだ。

また、フリーソフトの Mactracker を使うと機種IDを調べる事が出来る。

機種IDはハードウェアとしての世代を表す。概ね「ハードウェア名」.「メジャーバージョン」,「マイナーバージョン」ともいえる形になっている。同時期に売られている機種でも、iMac10,1 と iMac11,1 という感じでマイナーバージョンは異なることがある。
(これは2009年度後半に発売された iMac の場合で、Core2Duo 搭載は iMac10.1, Core i5, i7 搭載は iMac11,1 であった)

Xserve の場合、この機種IDは少々数奇な運命を辿っている。2002 年に発売された初代 Xserve は、「RackMac1,1」であった。どうもぎりぎりまで Xserve という名前が決まらなかったようで RackMac というコード名のままになっている。翌年発売された第二世代は RackMac1,2 で、仕様にほとんど差はない。筐体の剛性が上がり共振が押さえられたのと、ファンの回転制御がOS側から行えるようになり、騒音で悪名高かった初代より静かになったぐらいだ。

機種IDが  Xserve1,1 となったのは 2006 年の Intel 版の Xserve のリリースからだ。これは Xeon5100 を搭載していた。2008年に Xeon5400 にアップデートされた Xserve (Early2008) がリリースされたが、これが Xserve2,1 の機種IDをもつ。

で、問題の Xserve3,1 を持つのは 2009年1月にリリースされた Xserve(Early2009)で、Xeon 5500 をCPUに搭載している。おそらく「Early2009」で調べるか、Xeon 5500 搭載で調べると見つけやすいだろう。

なお、この Xserve (Early2009)は Xserve の最終機種である。

そう、Apple は 2011年1月に Xserve という1Uサーバそのものをディスコンにしている。

そもそも Xserve はサーバ用途という Mac としては極めて特殊なため、出荷台数は極めて少ない。Early2009 に至っては「どれだけ国内にあるのか?」 と疑問を持つぐらい少ない。

Xeon5500 で今でも十分に利用可能なCPUで、さらに最終機種となったのもあってまだまだ現役で動作しているのだろう。中古市場でも見かけることはまずないぐらいレアだ。

私も残念ながら1台しか所有していない。出物があったらもう1台欲しいものだが...。


● Xserve への ESXi のインストール

インストール自体は通常の ESXi と変わらない。

ただ、ESXi のバージョンによっては最初の起動に失敗することがある。

VGA 640x480 などという標準解像度を持たない Mac では、解像度情報を本体側NVRAMに記憶しており、起動時にその解像度で起動しようとする。この解像度によっては vmkernel 側がうまく追従できずそこで止まることがあるようだ。

通常の Mac なら nvram のクリア(SMUリセット)を行えばいいが、これが Xserve では上手くいかない。
 私が試した限り、上手くいくのは  Xserve Intel ユーザーズガイド の P.12 にある方法だ。
  1. 一旦電源を落とした状態にする
  2. 全面にあるシステムIDボタンを押し続ける
  3. そのまま電源を投入すると、フロントのCPU負荷を示す青いランプが順番に点滅する
  4. これは起動時チェックを行っているのだが、その間システムIDボタンを押しっぱなしにする。
  5. 順番の点滅が終わったところで通常行われる起動が行われないので、そこでシステムIDボタンを離す。
  6. 上記マニュアルにあるようにシステムIDボタンを押すと一個ずつ青いランプが点灯するので、下の左から3つ目だけが点灯する状態にする。(NVRAMリセットして起動可能なドライブから起動する。)
  7. そして、システムIDボタンをまた押しっぱなしにして、上の列が全て点灯するまで待つ
この方法でやっと ESXi のリリースメディアから起動することができた。

● Xserve 以外では動かないのか?

とりあえず、Macbook や iMac, Mac mini といった通常の Mac ではベアメタルに ESXi をインストールすることは出来ないと考えた方がいい。ESXi側が適切なドライバを持っていないためだ。

私が試したのは Mac mini だが、USBデバイスの認識がおかしく、vmkernel 起動した瞬間にキーボードのキー入力を受け付けなくなった。スクリプトインストールで切り抜けようとしたが、オンボードNICを認識しない時点でハマってしまった。

意外に知られていないが、ESX/ESXi は「vmkernel が認識できるNICが一つもない場合、インストールできない」という仕様がある。これに引っかかった訳だ。

コンシューマ向けの Mac では上記から諦めた方がいい。

ベアメタルではなく、仮想環境の上なら容易に動作する。VMware Fusion 4 では ESXi を仮想環境上で動作させることができるようになっている。ご丁寧にも仮想マシンの作成時に選択可能だ。さらに Virtual  Hardware Virtualization (vhv) を有効にすれば Fusion 上の ESXi で 64bit の仮想マシンを動かすことも出来る...、メモリとCPUが耐え切れれば、だが。

● 6/3 追記
上記に Mac mini ではインストールできなかったと記載したが、ドライバーを整えることでインストールに成功した人がいる。
また、Mac mini を入手できたら試してみたい。




2012/03/21

Ubuntu Linux で VMware View Client を動かす

さて、前回 Ubuntu Linux 版の ViewClient が出たという話をしたが、手元の環境では少々動かすのに苦労したのでメモ代わりに。

● 本来の手順

手順としては、 http://downloads.vmware.com から「VMware View Client」を選択


クライアント一覧から「VMware View Client for Ubuntu Linux」のダウンロードをクリック


 すると、Ubuntu ソフトウェアセンターが起動、パッケージが選択されているのでそれをインストール...するはずが、以下のように「見つかりません」と言われてしまう。


さて、どうしてだろうと調べてみた。

● 問題その1: サポートOS

まあ、一つはリリースノートを読むと書いてある。サポートOSだ。

以下に、Ubuntu Linux 版の ViewClient のリリースノート(和訳)だ。
http://www.vmware.com/jp/support/support-resources/pubs/viewclients_pubs/viewclient-linux-release-notes.html
Ubuntu 32 ビット 10.04 および 10.10 のサポート
私が試した Ubuntu  は 11.04 と 11.10 のため、新しすぎた、というのが一つ目の敗因だ。
このため、10.10 日本語 Remix をダウンロード、LiveCDで起動して試してみた。

● 問題その2: レポジトリ

10.10 でもやはり「見つかりません」と言われるので少々確認をしてみた。
どうも、Ubuntu の vmware-view-client は 「Canonical Partners」 というレポジトリにあるらしい。
そこで、10.10 のアップデートセンターでレポジトリを追加した。

通常、 Canonical Partners は「その他ソース」の項目に設定されており、チェック一つでレポジトリとして有効になるようだ。( 参考: http://vpc.uconn.edu/help/linux/ )

しかし、日本語Remix のアップデートセンターの設定では、この項目が見当たらない。


そこで、下の「追加」ボタンを押し、以下のCanonical Partners の APTラインを追加する。
deb http://archive.canonical.com/ lucid partner

これで準備完了だ。

Ubuntu Linux の Firefox で再び、VMware 社のサイトにアクセス、Download ボタンを押すと、以下のように「ソフトウェアの追加インストールを行いますか」のパネルが表示された。


そしてダウンロードが終わると、 インターネットメニューに「VMware View Client」が追加されている。


やっとインストール完了だ。

なお、このAPTラインを追加しても 11.10 などサポートより新しい UbuntuLinux では vmware-view-client が選択肢に出てこない。当分は 10.10 と 10.4 しか使えないようだ。

● VMware View Client for Ubuntu

初回起動時にはライセンス条項の表示と、確認が行われる。



こちらをOKすると、ConnectionServer / SecurityServer のURLを入力するパネルが表示される。見た目こそ異なれ、他の ViewClient と同じだ。


URLを入力、「Continue」 ボタンを押すと認証処理が行われる。これも他の ViewClient と同じだ。


認証に成功すると、かなり大きなアイコンが並び、デスクトップVMを選択する画面になる。
これは Mac 版の ViewClient に近い。アイコンの下にプロトコルが表示、選択になるのも同じだ。


アイコンを選択すると、デスクトップが表示される。もちろん PCoIP を使っての接続も可能だ。


ここまでくると非常に快適に利用できる。

課題としては、キーボードについてだ。今回 UbuntuLinux はFusion上の仮想マシンで、かつ LiveCD のため 106 キーボードに設定されており、かつ Mac 側が英語キーボードで配列が厄介な状態だったため確認できていない。

しかし、PCoIP のためおそらくデスクトップVM側に設定したキー配列がそのまま使われるのではないかと思われる。
混乱を防ぐためにも配列を統一しておいた方がいいだろう。


2012/03/18

VMware View で RDP 接続しているとデスクトップVMが再起動してしまうことがある


出張が続いたのと、あと VMware Fusion がとある事情から一時的に動かなくなってしまってて更新が遅れてしまった。

さて、VMware View のクライアントソフトウェアが非常に拡充してきたのはご存じだろうか?

詳細は以下にあるので確認して欲しいが、Mac 用のクライアントが新しくなり、また Ubuntu Linux 用の公式クライアントが追加されている。
http://downloads.vmware.com/d/info/desktop_end_user_computing/vmware_view_clients/1_0

実のところ、これまでも Linux 用のクライアントがなかった訳ではない。

ただ、それは Googles Codes にソースコードの形で提供されていた。
http://code.google.com/p/vmware-view-open-client/

クライアントソフトウェア単体として動かすのではなく、Linux ベースのシンクライアント製品に組み込まれるためにこういうソースコード形態での提供がなされていた。

Linux は、今風に言うなら「断片化が激しい」ため、数多のディストリビューションをサポートするには手に余るし、それらを寄せ集めても Windows, Mac ほどの需要はなかったという訳だ。
しかし、ここ数年 Ubuntu Linux は(例のデスクトップ環境のごたごたはあるにせよ) Linux をデスクトップ端末として使う際の定番になっている。何か一つ Linux で ViewClient をサポートするなら、これは順当なところだろう。

また、 iPad 向けのソフトウェアも着実にアップデートされており、Android 用も増えている。

これらは全て PCoIP をサポートしており高精細の画面を効率よく転送することが出来る。
ここまで PCoIP 対応のクライアントソフトウェアが充実すると、VMware View で RDP を使うことはほとんどないだろう。

また今回紹介する以下の話からも、今後はRDPを使わない、PCoIP専門に持っていく方が良いといえる。
さて、前書きが長くなってしまったが本題に入りたい。

● 問題

非 Windows 環境の RDP クライアントで WindowsXP SP3 を実行する仮想マシンに接続した場合、接続先の WindowsXP SP3 がクラッシュすることがある。

● 原因

これは、Windows XP SP3 に含まれる RDPDD.DLL のバグである。
詳細は以下のKB963038 に記載があるので参照して欲しい。

・WindowsXP を実行しているリモートコンピューターへのリモートデスクトップ接続を確立すると、エラーメッセージ:"停止:0x1000008E"

また、以下の Blog にも類似の記載がある。

リモートデスクトップを利用していてリモート先PCがSTOPエラーでブルースクリーン
リモートデスクトップでOSが落ちる

確認方法としてはブルースクリーンを見るのが一番であるが、そもそもリモートアクセスしてるのだから vSphereClient でコンソールを見るなど難しいであろう。

事後の検証としては Nirsoft の BlueScreenView というソフトを使うと便利だ。
http://www.nirsoft.net/utils/blue_screen_view.html

これはクラッシュに生成される minidump を確認してくれるというものだ。
以下の図のように、ダンプ時の状況を表示してくれるが、ここで Bug Check Code を見ると確かに 0x1000008E であるのが分かる。

● 対応

ここまで分かれば話は早い。つまりはこの RDPDD.DLL の問題を解決すればいいのだ。
これには三つの手段がある。

  1. RDPを使わない
  2. マイクロソフトの 修正プログラム を適用
  3. RDPDD.DLL を差し替える
一番いいのは 1. だ。冒頭に触れたように PCoIP 対応のクライアントは増えてるのだからわざわざRDPを使うことはない。


二つ目は、先に紹介したマイクロソフトのKBにリンクされている 修正プログラム を適用するというもの。Fix253552 というそれをあてればこの問題は発生しなくなる。

ただし、この修正プログラムは WindowsUpdate でははいってこず、先のKB963038のページの「この技術情報に対応する修正プログラムのダウンロードのリスト」にあるリンクからしか手に入らない上、メールアドレスは取られるわ、CAPTCHA はあるわで少々面倒だ。

三つ目は、先ほどリンクしたブログにあるように、WindowsXP SP2 の RDPDD.DLL に置き換えてしまうことで問題が消えるというもの。実際に消えるのは確認したが無理矢理DLLを置き換えるのもあまりよろしくないし、なにより他の問題を引き起こさないかが未知数だ。
だったら、2つめの修正プログラムをあてた方がまだいいだろう。

あと、この問題は WindowsXP SP3 でしか発生しない。つまり Windows7 ならば問題はないのだ。仮想デスクトップも Windows7 にしてしまうというのも解法としてはアリだろう。





2012/02/20

[余談] MacOS X のVPN接続をコマンドラインから実行する

仮想化とは関係ないけど、余談で。

MacOS X では VPN接続機能が用意されており、システム環境設定の「ネットワーク」にて、左下の「+」ボタンを押すことで設定が可能になる。標準で用意されているのは、L2TP over IPsec, PPTP, Cisco IPSec の三つだ (Lion の場合)

それぞれを選択、アカウントなど適宜情報を記入することで L2で VPNを張ることができる。

ただ、その接続がシステム環境設定を開いて該当するネットワーク設定を選択、「接続」ボタンを押すか、メニューバーにVPN設定のアイコンをあらかじめ表示させておき、そこから選ぶか、になる。

そう頻繁にVPNを張らない人や、MacBookAir を利用しててメニューバーの横幅が足りないのであまりアイコンを表示させたくない人からすれば、一々システム環境を開くのは面倒だ。

そこで、ターミナルのコマンドラインから VPNを張れないかを調べてみた。
とりあえず、ざっと調べた限りではそれっぽいコマンドは見つけられなかった。のでスクリプトで対応させることとした。

#!/bin/sh
DoScript() {
/usr/bin/osascript << __EOF__
tell application "System Events"
   tell current location of network preferences
       set VPNservice to service "$2"
       if exists VPNservice then $1 VPNservice
   end tell
end tell
__EOF__
    return 0 ;
}
case $1 in
"connect")
    DoScript "connect" $2 ;;
"disconnect")
    DoScript "disconnect" $2 ;;
esac


DoScript 関数がこのシェルスクリプトの実体で、osascript にヒアドキュメントで AppleScript を流し込み、実行している。

tell application "System Events" により SystemEvents に対して指示を送り、さらにその中で「current location of network preferences」、つまり現在のネットワーク設定に指示を送っている。
OS X をあまり使われてない方には馴染みのないことだが、OS X では「場所」ないしは「ネットワーク環境」という名前で、使用するネットワークインターフェイスやインターフェイス冠の優先順位、IPアドレス、DNS、デフォルトルート、プロクシーなどの設定をまとめて切り替えることができる。ネットワーク管理をやってた頃はいく先々ごとにこのネットワーク環境を作り、ついたら切り替えることでたとえ固定IPアドレスや特別なプロクシの設定が必要でも一気に切り替えられたので便利なのだ。
ThinkPad など一部のベンダーのPCにも同様の機能はあるが、OS標準でないため細かいところで面倒だったのと、やはりUNIXコマンドが標準搭載なのもあり Macのノートは私の回りのネットワーク管理者にとっては必須のデバイスであった。

何を送ってるかというと $2 にはVPNサービス名が入り、$1 には connect か disconnect が入るため、set VPNservice to service "何らかのVPNサービス名" で、VPNService という変数にサービス名を突っ込む。

それから、if exist VPNservice でそのサービス名に該当する設定があるかを確認、あれば $2, つまり connect(接続)もしくは disconnect(切断)を行う。

case でくるんでるのは、コマンドラインからは connect でも start でもよくしようとして、途中で面倒になったからそうなっているだけだ。( "connect") を "connect"|"start") とかするだけなのだが)

さて、このスクリプトを vpnc という名前でパスの通るところに保存、実行フラグを立てる。システム環境設定のネットワークから「MyOffice」というVPN設定を作った後

$ vpnc connect MyOffice

とコマンドを叩けば、接続される訳だ。
なお、厳密には「接続を指示する」ところでこのスクリプトは終了してしまう。VPNの接続確立までに時間がかかる場合は、そのぶん待った方がいい。

私は接続先に既知のサーバがあるので、ちょっと待ってから ping を打って繋がってる確認した後に利用するようにしている。

もう少し頑張ればVPN明があるかをチェックしてなければエラーを返すとか、色々改善もできるだろうが私の用途ではこれで十分なのでそこから直していない。




2012/02/16

USBメモリから起動するOSを仮想マシンで利用する(1)

先日、とある事情にてUSBメモリに書き込まれたOS (Linux) を仮想環境上で起動することになった。その時の手順のメモ。

残念ながら、VMware Fusion は、いや VMware Workstation もその他製品も、USBメモリからのブートを直接対応していない。起動可能なデバイスは仮想環境上で
HDD, 光学ドライブ, FD と認識されるものか、ネットワークブート(PXE)だけだ。


これは、VMware が実現している仮想ハードウェアが Intel 440BX という90年代中盤に存在したチップセットのエミュレーションをしていることが遠因だ。

当時は CD-ROM ブートですらできるとは限らなかった。( Windows NT4 や OS/2 Warp など当時のOSはフロッピーで起動、ドライバを読み込んでからインストール用のCDを認識したものだ。)
そもそも USBについては  Windows 98 の登場までほとんど利用できず、実質的な普及は98年末の iMac の爆発的な普及の後からだ。USB起動は考えられてなかったのは仕方のないことだ。

この時はあまり時間もなかったので手っ取り早い手段で解決した。


● Plop Boot Manager

Plop Boot Manager はその名の通りOSの起動を制御するブートマネージャで、HDD や CD-ROM, USB メモリからOSを読み込み、起動させることができる。



この記事を書いてる時点の最新は 5.0.14 。実は試したときは 5.0.13 だったがそう大きな差はない。上記のダウンロードページから zip ファイルをダウンロード、展開すると iso イメージが入っている。



この iso イメージを、仮想マシンの設定の CD/DVD にて選択、仮想マシンに割り当てる。


そして仮想マシンを起動する。
まだOSを入れていない、空の仮想マシンならそのまま PLoP Boot Manager が起動する


なお、VMware は HDD にOSが入ってるとそちらから優先して起動される。CD/DVD ドライブから起動したい場合は設定の「起動ディスク」から選択するか、仮想マシンの起動直後、VMware のロゴの BIOS初期化中にタイミング良くウィンドウをクリックしキーボードのフォーカスを入れて F2 を押すと表示される Phonix BIOS の Boot メニューから CD-ROM の優先順位を上げるといい。後者は VMware  製品共通だが、タイミングが難しいので Fusionなら前者を選ぶのが良いだろう。

ともあれ、PLoP Boot Manager が起動すると星の流れる校歌の右上に「FLOPPY」「CDROM」「USB」といったメニューが表示されている。おもむろにUSBメモリを挿し、仮想マシン側へ割り当てた後にこのメニューからUSBを選択すると、USBメモリ内のOSで起動される。


ただし、製品にもよるが USB メモリからの起動は決して速くない。

結局のところ、Ubuntu Linux のインストールメディアから仮想マシンを起動、dd コマンドで USBメモリの内容を頭から丸ごと仮想ハードディスクに丸々コピーし、そちらから起動するようにしてしまった。フロッピーや CD/DVD-ROM などと異なり、USB メモリのレイアウトはHDDと同様なので、MBRから丸ごと全部コピーしてやればだいたい動いてしまうのだ。

2012/02/15

VMware Fusion で XP Mode は動くの?

VMware Fusion 上の Windows7 で XP Mode は動作するかどうか、というと動作する。
これは VMware の KB(ナレッジベース)で説明されている。

・Using Windows 7 Virtual PC XP Mode in Fusion
http://kb.vmware.com/kb/1017526

英文を読むと「ハードウェア仮想化機能が仮想マシン上にはないので XP Mode が動かない」とある。さらに読めば「MSからパッチが出てるので適用せよ」となっている。

以下は XP Mode のダウンロードページだが、持っている Windows7 のエディションと言語を選択すると 3つのコンポーネントがダウンロードできる。



「最初にインストール」とあるのは XP Mode の仮想マシン。VHD 形式のイメージと構成ファイルが用意されている。

「2番目にインストール」とあるのが Windows Virtual PC 。フリーで配布されている Virtual PC 2007 と違い、Windows7 専用のホスト型仮想化ソフトウェアで、エクスプローラとの統合されてて扱いやすい一方、同時に1つしか仮想マシンを実行できないという違いがある。細かい違いは MSのFAQを参照
なお、この時点ではまだ Intel-VT や AMD-V といったハードウェア仮想化機能が CPU に搭載されている悲痛用がある。

元々はこの2つをダウンロード、実行すれば良かったのだが、Windows7 登場時は思いの外 ハードウェア仮想化に対応したCPUを持つデスクトップマシンが少なかった。

また、ハードウェア仮想化機能は BIOSでPC起動時に有効化する必要があるのだが、対応CPUを搭載していてもほとんどの場合BIOSでは無効化されており、BIOS設定を変更して有効化する必要がある。一部PCに至っては BIOSにこの設定がなく(削除されており)、ハードウェア仮想化機能を有効化することができない。
デフォルトで無効なのは、使わないのにハードウェア仮想化機能が有効化されていると、そこにウィルスが入り込みOSの下に潜みこむことができてしまうから、つまりはセキュリティ上の要請からなのだが、さすがにどうやっても有効化できない、ってのはやり過ぎた。

筆者は Windows7 の登場時、何度も「このパソコンは XP Mode が利用できるか」や「XP Mode が利用できるパソコンを見積もって欲しい」という依頼を受けたが、ハードウェア仮想化機能を有効化できるかはメーカに聞いても教えてくれない事があまりに多く閉口したことがある。

普段扱っているサーバ機器でメーカ窓口が Intel-VT を有効化できるかできないかを知らないなんてあり得ない話だが、当時のデスクトップ/ノートPC側のサポート窓口ではまだそのような情報は出回ってなかったようだ。

結局、オンラインでダウンロードできるマニュアルをさがし、BIOS設定項目を探したものなのだ。

閑話休題。

ともあれ、マイクロソフトが思った以上にハードウェア仮想化機能はデスクトップ環境に広まってなかった。そこで「ハードウェア仮想化機能がなくても Windows Virual PC を動かせるパッチ」( KB977206 )が提供された。

上記ページで、「三番目にインストール」とある Windows XP Mode update が、この KB977206 のパッチなのだ。

つまり、3つ目までインストールした時点で、ハードウェア仮想化機能がなくても Windows Virtual PC が使えるようになる。

VMware の KB に記載されているのはこの KB977206 を適用せよ、という事なのだ。


なお、Windows Virtual PC が起動する際に NICをプロミスキャスモードに設定する。
VMware Fusion で Windows7 を実行、その上で XP Mode を使おうと Windows Virtual PC を起動すると仮想NICをプロミスキャスモードに設定しようとして、Fusion が警告パネルを表示するだろう。


全くの余談だが vSphere (ESX/ESXi) 上の Windows7 で XP Mode を使おうとするとこの点が問題になる。ESX/ESXi の仮想スイッチ上にポートグループのデフォルト設定では、プロミスキャスモードの設定を許可していない。リモートデスクトップなどで Windows7 仮想マシンに接続しながら XP Mode を有効にするとプロミスキャスモードへの移行を拒否する余波でリモートデスクトップが切れてしまい、何が何だか分からなくなる。

対処法はプロミスキャスモードを許可したポートグループに仮想NICを接続すること、だ。






VMware Fusion の「言語固有のキー マッピングを有効にする」 について

某勉強会で話したことの転載。

VMware Fusion の環境設定にある 「言語固有のキー マッピングを有効にする」 について。


結論から言うと、日本人はまったく気にする必要がない。

VMware Fusion のマニュアルによると、以下の機能を持つ
入力メニューをサポートされるキーボード レイアウトに変更すると、追加のキー マッピングがキー マッピング リストに追加されます。現在、VMware Fusion はフランス語とドイツ語をサポートしています。この機能は、Mac OS X Server 仮想マシンでは使用できません。
「追加のキーマッピング」とはなんぞや?と思われるが、これはフランス語やドイツ語のキーボードにある追加キーが有効になる機能を意味する。

日本語のキーボードにある「かな」「英数」などについてはこのチェックの有無にかかわらず、日本語キーボードを繋いでいれば利用可能だ。

つまり、日本人が日本語環境や英語環境で VMware Fusion を利用、仮想マシンを実行する限りは何の意味も持たない。気にする必要はないのだ。

VMXNET3 を使用した Windows7/ Windows2008 仮想マシンをクローンするとNICの名前が変わってしまう

● 問題

vSphere 環境にて、VMXNET3 を利用した、ゲストOSとして Windows7 もしくは Windows Server 2008 R2 をインストールした仮想マシンのクローンを取ると、ゲストOS上のネットワークデバイスの前が「ローカルエリア接続」ではなく「ローカルエリア接続 2」など、後ろに数字が付加されてしまう。


● 原因

この件に関する VMware 社の KB は以下の通り。

"Deploying Windows 2008 R2 and Windows 7 templates with vmxnet3 renames the NIC as #2"

上記に書いてあるとおりなのだが、かいつまんで説明すると...

Windows7/2008R2 では、PCIスロット上のデバイスは PCIのスロットIDをもって識別される。このため、あるPCI デバイスを別のスロットに挿すと「新しいデバイス」と見なされ別の認識をされる一方、同じスロットに同じ種類のカードで別のものを挿しても「同じデバイス」と見なされる。
例えばNICの場合、同じNICを別のスロットに移すと別NICと見なされる一方、異なるMACアドレスを持つ別の同メーカのNICを同じスロットに挿すと「同じNIC」扱いされて前と同じ設定が適用される。

一方、PCI Express に接続されたデバイスの場合はデバイスのシリアル番号などを引っ張って唯一性を確認するだけだ。例えばNICならば MACアドレスで違いを確認する。MACアドレスが同じならどのスロットにあっても同じデバイス、MACアドレスが異なれば同じスロットでも違うデバイス、扱いになる。

ここまで聞くと正しいと言えば正しいのだが、問題は仮想マシンでクローンを行った場合。

仮想NICでも Intel EtherExpress 互換(e1000) や AMD PCnet32 互換(フレキシブル) は PCIバス接続と見なされている。なのでクローンされて、MACアドレスが変わってしまっても「同じNIC」と見なされ、ゲストOSである Windows のレジストリにあるクローン前のNICの設定がそのまま利用される。

一方、VMXNET3は PCI Express 上に繋がっていると見なされるので、クローンされてMACアドレスが異なると「違うデバイス」扱いになる。レジストリにはクローン前の元のNICの設定とは別の設定が作られる。クローン前の設定が「ローカルエリア接続」ならば、新しく作られた方は「ローカルエリア接続 2」などになってしまうわけだ。

しかも、クローン前のMACアドレスを持つNICは繋がれないのにレジストリに設定が残ってしまって「ローカルエリア接続」の名前を占めてしまうので、できあがった「ローカルエリア接続 2」を「ローカルエリア接続」に名前変更を試みても失敗する。


● 対応

要するに Windows の挙動の問題のため、Windows 側にパッチを当てるしかない。

パッチは以下のマイクロソフトのKB から入手可能


それぞれのページの上の方に「View and request hotfix downloads」というリンクがあるのでこれをクリック、ダウンロードするパッチを選択、メールアドレスを記入、CAPTCHA を記入後、「リクエストを送信する」ボタンを押すと、パッチの入手先がメールで届く。

なお、パッチは x86, x64, ia64 でそれぞれ別物なので注意。普通は x86 と x64 が必要になるだろう。通常は現在実行しているアーキテクチャだけが表示されているので、「Show hotfixes for all platforms and languages」あるいは「すべての環境、言語用の修正プログラムを表示する」のリンクをクリックすると全部のパッチが見えるので、適切なチェックを入れるといい。

メールのリンクをクリックすると、自己解凍形式の EXE ファイルがダウンロードされる。
これを実行すると、拡張子 .msu のパッチが出てくるので、"クローン元になる仮想マシンの Windows" にこのパッチを適用する。

適用後にクローンを行うと、この問題は発生しなくなる。


● ワークアラウンド

なお、問題は VMXNET3 で起こるものなので、e1000 やフレックスを使っていれば問題は発生しない。

発生した場合も以下のサイトを参照にゴースト化してしまったクローン前のNICの設定情報をレジストリから削除してしまえば名前をもどす事が可能になる。

・ネットワーク アダプターに IP アドレスを設定する際のエラー メッセージ


・デバイスマネージャに表示されないネットワークアダプタを削除する方法



2012/02/14

VMware Fusion でリンククローンを実現する

リンククローンとは、vCenter LabManager, VMware View (ViewComposer), vCloud Director などで実現されている機能で、親となる仮想マシンに対する差分だけの仮想マシンを作成、実行する機能だ。

同様の構成の仮想マシンが複数ある場合、共通部分を親で実装した後にリンククローンで展開することで共通部分の占めるディスク領域を削減でき、さらに差分だけ作ればいいので高速に展開ができる。

この機能は VMware Workstation にも搭載されており、ちょっとした検証時にディスク容量を気にせず仮想マシンを生み出せるので重宝してるのだが、残念ながら VMware Fusion には搭載されていない。
( そもそも、VMwareFusion には仮想マシンの複製機能が搭載されていない。)

これは不便だ、ということで試してみたのが以下手順。


● そもそものリンククローンの実装を見てみる

VMware View で搭載された ViewComposer はやや特殊だが、それ以外の実装は概ねスナップショットの仕組みを利用している。VMware におけるスナップショットは、「その時点でのディスクイメージを書き込み不可に設定」(+必要に応じてその瞬間のメモリ内容や仮想マシンの状態をファイルに出力)することである時点の状態を保持するものだ。

スナップショット採取後のディスクへの書き込みは、新たに作られた差分ディスクイメージに書き込まれる。読み込み時はまず差分ディスクイメージを読み、そこになければ親のディスクイメージを参照する。

なお、差分ディスクイメージはログではない。仮想マシン上のアプリケーションが、同じディスクブロックに2回書き込めば、最後の1回だけが差分ディスクに残り、先の1回は上書きされて消えてしまう。つまり、最悪のパターンを考えると親ディスクイメージと同じサイズの差分ディスク領域が作成される。これは頭から尻尾まで何らかのデータで上書きされた場合だ。

経験則では差分ディスクイメージは元ディスクイメージの2割〜3割程度だけが書き換えられる。40GBのディスク領域をもつ仮想マシンが1回スナップショットを取るたびに、8GBぐらいは消費されると考えた方がいい。

通常のスナップショットは同じ仮想マシンの仮想ディスクに対する差分になる。なので同じフォルダの中に親も差分もまとめて入れられている。

別のフォルダの親ディスクイメージ対する差分、がつくれれば、ある仮想マシンの差分だけのディスクイメージを持つ仮想マシンが作れる。これがリンククローンだ。


● VMDK

VMware における仮想ディスクイメージは VMDK と呼ばれる。
Virtual Machine Disk の略で、拡張子も .vmdk である。

しかし、vmdk の拡張子を持つファイルは単一の形態でもなければ、単一のファイルであるとも限らない。

VMDKの定義は公開されている、URLは以下の通り。

歴史的な事情もあり、VMDKの内部形式は多様にある。が、とりあえずデータセンター製品(ESX, ESXi など)で使われている形式を忘れて VMware Fusion などホスト型製品で使われている形式だけを見ると、以下の違いで4種類+αに分けられる。
  • 2GB 単位で分割するか (single or split)
  • あらかじめ容量分の領域を確保するか (growable or preallocated)
例えば、1ディスクイメージで必要に応じて容量が増大する形式は single growable virtual disk であり、2GBごとに区切られたディスクイメージで最初から指定容量を確保したものは preallocated virtual disk split in 2GB files となる訳だ。

これは、VMware Fusion のディスクイメージのチェックボックスに表現されている。



この、「事前のディスク領域を割り当てる」「2GB ファイルに分割」の2つのチェックがそれぞれの選択を示す。なお、デフォルトでは「事前のディスク領域を割り当てる」のチェックはオフ、「2GB ファイルに分割」のチェックはオン、growable virtual disk split in 2GB となっている訳だ。
(+αの形式については、また別に機会に説明したい。)

では、このデフォルトの場合で VMDK の中身を簡単に説明したい。

growable virtual disk split in 2GB  のVMDKを作成すると、<ディスク名>.vmdk のファイルと複数の <ディスク名>-s<番号>.vmdk のファイルができあがる。

このうち、<ディスク名>.vmdk は実はテキストファイルで読み書きが可能だ。
少々大きいが引用してみる。

# Disk DescriptorFile
version=1
encoding="UTF-8"
CID=13b99327
parentCID=ffffffff
isNativeSnapshot="no"
createType="twoGbMaxExtentSparse"
# Extent description
RW 4192256 SPARSE "osx-s001.vmdk"
RW 4192256 SPARSE "osx-s002.vmdk"
RW 4192256 SPARSE "osx-s003.vmdk"
RW 4192256 SPARSE "osx-s004.vmdk"
RW 4192256 SPARSE "osx-s005.vmdk"
RW 4192256 SPARSE "osx-s006.vmdk"
RW 4192256 SPARSE "osx-s007.vmdk"
RW 4192256 SPARSE "osx-s008.vmdk"
RW 4192256 SPARSE "osx-s009.vmdk"
RW 4192256 SPARSE "osx-s010.vmdk"
RW 4192256 SPARSE "osx-s011.vmdk"
RW 4192256 SPARSE "osx-s012.vmdk"
RW 4192256 SPARSE "osx-s013.vmdk"
RW 4192256 SPARSE "osx-s014.vmdk"
RW 4192256 SPARSE "osx-s015.vmdk"
RW 4192256 SPARSE "osx-s016.vmdk"
RW 4192256 SPARSE "osx-s017.vmdk"
RW 4192256 SPARSE "osx-s018.vmdk"
RW 4192256 SPARSE "osx-s019.vmdk"
RW 4192256 SPARSE "osx-s020.vmdk"
RW 40960 SPARSE "osx-s021.vmdk"
# The Disk Data Base
#DDB
ddb.adapterType = "lsilogic"
ddb.geometry.sectors = "63"
ddb.geometry.heads = "255"
ddb.geometry.cylinders = "5221"
ddb.uuid = "60 00 C2 98 9f a9 e6 26-65 9d 58 77 e0 5b 46 f6"
ddb.longContentID = "f2f9ab1f6c644c8cb517ee3113b99327"
ddb.toolsVersion = "8322"
ddb.virtualHWVersion = "7"
ddb.deletable = "true"

バージョンはこの設定ファイルの記述形式 encoding は文字コードを示している。CID は content ID の略で、このVMDKを示す 32bit の番号で、VMDKの作成時に乱数で決められる。parentCID は、このVMDKの親ディスクイメージとなる VMDKの CID になる。これは親を持たないVMDKのため ffffffff が記載されている。createType は先の 2GB で分けるか分けないか容量可変か固定サイズかをしめす識別子だ。

# から始まる行はコメントで、そこから下の RW で始まる一連の領域は2GBの差分ディスクの名前とどこからどこまでを担当しているかを示す。DDB は Disk DataBase の略でこのディスクイメージの諸元情報が記載されている。HDDとしてのセクタ、ヘッダ、シリンダの数や SCSIか IDEか、SCSIの場合は SCSIインターフェイスが BusLogic のSCSIカードのエミュレーションか LSI Logic のSCSIカードのエミュレーションかを示している。

面白いのは ddb.toolsVersion だ。これは、実は VMware Tools がそのディスク上のOSにインストールされているか、されているならその内部バージョンが記されている。VMware Tools が古いとか、入っていないとかは実はここで識別されているのだ。

閑話休題、parentCID で親ディスクイメージとの関連が取られていることが分かるが、では親ディスクイメージはどこにあるか。CIDに対応するファイルのパスを一々仮想化ソフトウェア側が覚えているかというとそうではない。

スナップショットを取ってみると分かる。

VMware Fusion でスナップショットをとると「<ディスク名>-<6桁の番号>.vmdk 」と「<ディスク名>-<6桁の番号>-s<番号>.vmdk 」という一連のファイルができあがってるはずだ。この <ディスク名>-<6桁の番号>.vmdk 側はやはりテキストファイルで VMDK の設定情報が書かれている。こちらをみると、こんな記述があるはずだ
CID=5daf4124
parentCID=c07bdeb7
isNativeSnapshot="no"
createType="twoGbMaxExtentSparse"
parentFileNameHint="OPENSTEP-000003.vmdk"
この parentFileNameHint が親ディスクイメージの名前と場所を記録している、という訳だ。

なお、1ディスクイメージにまとめた場合は、VMDK ファイルの先頭にこのテキストと同等の情報が記載された後、実際のディスクの内容となるバイナリデータが連結された形となる。読んで読めなくはないが、以下に述べるような編集操作が難しいのが難点。

分割ファイルが 2GB ずつなのは、そもそもこの形式 FATファイルシステムで作られたため。Windows 95 までで主に使われてきた FAT16 形式では、ファイルサイズの最大は 2GB であったため、2GB ずつ分解するのが適切だったのだ。
(FAT32 の導入は Windows98 より正確には Windows95 OSR2から )

VMware Fusion でこの2GBごと分割形式がデフォルトなのは、TimeMachine との相性からだと思われる。TimeMachine はファイル単位で更新されたファイルをバックアップするため、1ファイル形式だと VMDKの中の1バイトがかわっただけでも全てのディスクイメージがバックアップされてしまう。2GB ごとなら変更されたブロックを含むエクステントファイルだけがバックアップされるので、少しは効率が良くなる。


● リンククローンをでっち上げる

さて、説明は長いが、やることは実はそう難しくない(笑)

まず、仮想マシンを作成し OSをインストール、必要なところまでシステムを構成する。
なおこのとき 「2GB ファイルに分割」は入れておくことをお勧めする。理由は述べたとおり、後で VMDK に細工するときに single 形式は面倒だからだ。

十分できあがったところで仮想マシンをシャットダウンする。

仮想マシンが止まったところで、Finder で .vmwarevm フォルダの下をみて、どういう名前で VMDK が作られているか確認しておこう。

確認できたらスナップショットを取る。

スナップショットは恐らく、「<ディスク名>-<6桁の番号>.vmdk 」と「<ディスク名>-<6桁の番号>-s<番号>.vmdk 」という一連のファイルができあがってるはずだ。

安全のためにここで仮想マシンを VMware Fusion の仮想マシンのリストから削除しておいた方がいい。なお、削除する際は「ファイルの保持」を選択、仮想マシンの構成ファイルが削除されないように気をつける。


次にリンク先の仮想マシンを作成する。名前は適当でいい。
そして仮想マシンの設定からハートディスクを選択、詳細オプションを広げて「ハードディスクの削除」を行う。

これで稼働ハードディスクのない仮想マシンができあがる。ここでまだ「設定」パネルは閉じない。

さて、ターミナルを起動、ウィンドウを1つ開く。コピー元の仮想マシンのフォルダにあるスナップショットでできた一連の VMDK ファイルを、リンク先の仮想マシンの .vmwarevm  フォルダに全部コピーする。

そして、適当なエディタで 「<ディスク名>-<6桁の番号>-s<番号>.vmdk 」ファイルを開き、
parentFileNameHint="VMname.vmdk"
parentFileNameHint="../VMname/VMname.vmdk"
という感じでパスに書き換える。相対パスでも絶対パスでもいいのだが、Fusion の場合 ホームの下の書類(Documents)の下の「仮想マシン」(VirtualMachine.localized) フォルダにまとめて置いておくことが多いので、例のように相対パスの方が楽、だろう。

そして仮想マシンの設定の右上にある「デバイスを追加...」ボタンを押し、「既存のハードディスク」を選択、上記でコピーした VMDK を選択する。

これでリンククローン(もどき)は完了。あとは仮想マシンの電源を入れれば起動する、はずだ。


なお、この方式で Windows のリンククローンを作った場合、SIDは全て同一になる。

SIDが同じでも普通は困らない。ActiveDirectory 環境下でも困らないことはマイクロソフト自身が明言している。

しかし、一部のアプリケーションなどで SID が一意であることを前提に作られたものがある。そういった場合は SIDが重複していると問題が起こるかも知れない。
(実は、VMware View の ViewManager や vCenterServer などでこの問題が発生する。)

問題が起こった場合は、リンククローンされた仮想マシンで sysprep を実行、SIDを再生成させればいい。