2016/12/03

vSphere 上での Nano Server のインストール

所用があり確認したので、メモ。

Windows Server 2016 では Nano Server と呼ばれる、軽量化されたOSが含まれています。Windows Server 2016 をベースに新しいアプリケーションやインフラストラクチャーを対象に、そのための機能に研ぎ澄ましたもので、稼働させるだけなら数百MB程度のメモリとディスクがあれば動きます。

Windows Server 2016 そのものも 512MB が最低必要量になってますが、インストール時には 800MB 程度、デスクトップエクスペリエンスを備えるならやはり 2GBが必要となります。ストレージ容量なら32GBが最低容量となります。

一方、Nano Server は「研ぎ澄まされ」ているため、用途としては不適となります。たとえばローカルコンソールで操作できることは本当に最低限のため、リモート管理が必須となります。役割や機能もフルインストールの Winodows Server がサポートするものが全てサポートされるわけではありません。ライセンスから見ても、アップデートがCBBモデルなのもありSAが必須となります。

こうしたことから、インストーラーでぽんとインストールできるわけではありません。

Windows Server 2016 のインストーラーでは、デフォルトのの Server Core か、
デスクトップエクスペリエンス付きかの選択肢しかない

むしろ、インストールしてから用途に向けてセットアップしていくのではなく、コマンドラインで
「必要な機能を組み込んでいく」必要があります。

インストール手順自体はこちらにありますが、少々敷居の高いものとなっています。
では、VMware の仮想マシン上にインストールするにはどうすればいいでしょうか? ちょっと試してみました。

● EFI か、BIOSか?

まず最初に決めるべき事は、ファームウェアを従来のPC-BIOSか、UEFIにするかです。PC-BIOS
はこれまで使われてきたファームウェアで、リアルモードで動作するものになります。UEFI はより新しいファームウェアで、ブート前の状態でより多くの機能を提供できるものです。

Nano Server をインストールするにはどちらでも構いません。多くの VMware 製品は普通に仮想マシンを作ると PC-BIOS を設定します。VMware Fusion については macOS をゲストOSにしない限り、EFI は選択されません。(ユーザーインターフェイスから設定できない。ただし vmx ファイルを直接書き換えることで設定可能)

ここでは、最初に BIOS でのインストールを、次に EFI でのインストールを試してみます。

● Nano Server のインストール (BIOS編)

まず、仮想マシンを作成する。特に普通に作れば良い。今回はメモリは 1GB程度にしました。
仮想ディスクのサイズも1GB以上ならば問題ありません。

ESXi の仮想マシンのプロパティ
「リソース」の「起動オプション」にてファームウェアの指定が可能


注意点としては、ゲストOSとしては「Windows Server 2016(64bit)」を選択すると言うことぐらいです。

仮想マシンの作成画面より
OSは Windows Server 2016 (64bit) にする

できあがった仮想マシンに Windows Server 2016 のインストールメディアを認識させ、こちらから起動します。
Windows Server 2016 のインストールメディアから起動
通常はここでキーボードや言語の選択を行いウィザードを進めるが
Nano Server の場合はここで一旦停止

この画面が表示されたところで「SHIFT+F10」をおす。すると、コマンドプロンプトウィンドウが開きます。

Windows Server のインストールメディアでは、SHIFT-F10 でコマンドプロンプトウィンドウが開く
ここでは、D: ドライブの内容を dir で確認している

デフォルトの状態では、X:ドライブに一時的な起動ドライブが作成されております。インストールメディア自体はD:ドライブにマウントされており、初期状態では仮想ディスクはフォーマットもされていないため、どこにもマウントされていません。
D:\NanoServer フォルダ以下に、Nano Server の素の状態のイメージ(NanoServer.wim) と、デバイスドライバや役割、機能を備えたパッケージ(*.pkg)があります。


さて、ここからインストールを行います。インストールで行わなければならないことは、以下の4つです。

  1. ディスクのパーティション作成と、フォーマット
  2. Nano Server イメージの展開
  3. その他必要なパッケージのインストール
  4. 起動パーティションとして指定

・パーティションの作成

パーティションの作成とフォーマットは diskpart コマンドで実施します。まず、「diskpart」と入力し実行して、diskpart コマンドを起動します。このとき、「DISKPART>」のプロンプトが出ずハングする場合があります。その時は Ctrl-C をおして diskpart コマンドを終了し、しばらく待ってから再度実行するとプロンプトが出てきます。

diskpart コマンドを実行

DISKPART> のプロンプトが出たら、以下のコマンドを実行します。
  • select disk 0
  • create partition primary
  • format quick fs=ntfs label="nano server"
  • assign letter=c
  • active
select disk 0 で接続されている最初のドライブを選択します。
次の create partition で選択されたドライブに新しいパーティションを作ります。このとき、 primary を指定することでMBR のプライマリパーティションとしてパーティションが作成されます。
(MBRでは、そのままだと最大4つのパーティションしか作成できない。これらを「プライマリパーティション」と呼ぶ。4つ以上パーティションが必要な場合は、そのうちどれかを入れ子にして、別途パーティションテーブルを作成、分割する。この入れ子で作成されるパーティションを「論理パーティション」と呼ぶ )


上記コマンドに従い、パーティションを作成、フォーマットを実行
最近?の diskpart では、作成したパーティションが選択された状態になっているので、そのまま fomat コマンドを実行することで作成したばかりのパーティションをフォーマットします。fs=ntfs でntfsを選択、ボリュームラベルは nano server を指定、quick を付けることでクイックフォーマットを行ってます。
assign letter=c で、このパーティションを「C」ドライブと名付けます。名付けた時点で C: でアクセスが可能になります。

最後が重要です、active を実行することで、MBRに「このパーティションから起動する」という指名をします。この操作をしていないと、起動パーティションが分からずブートに失敗しますので注意してください。

起動パーティションを指定
list partition で先頭に*があるのがそれだ


終わったら、DISKPART> のプロンプトで exit を入力する、もしくは Ctrl-C で終了できます。

・Nano Server イメージの展開

空のC:ができたところで、ここにOSのイメージを流し込みます。
まず、カレントディレクトリを d:\NanoServer に移動しておきます。

ここで、以下コマンドを実行します。少々長いので打ち間違いに気をつけてください。

  • dism /apply-image /imagefile:.\NanoServer.wim /index:1 /applydir:c:\

dism コマンドでWIMイメージを展開

dism.exe は WindowsVista から用意された、Windows の展開イメージの管理コマンドです。インストーラーが使用する WIM形式のイメージや仮想ディスクイメージである VHD/VHDX形式、それからディスクに展開された Windows のシステムを管理することができます。

ここでは、imagefile で指定した WIM形式のイメージを applydir で指定したパスに書き出しています。/index:1 は、WIMイメージの2つめのボリュームを対象にしていることを指します。このWIMイメージの中にはEFIシステムパーティションがあるので、C: に相当するのは二つ目の(0オリジンで1の)ボリュームだからです。

dir c: とかすると、Program Files や WINDOWS など、おなじみのフォルダが展開されているのが分かります。

・その他必要なパッケージのインストール

このままでは Nano Server そのものしかインストールされておらず、起動する以上の意味を持ちません。追加のデバイスドライバや役割、機能をここでインストールします。

CABパッケージの追加インストールには、dism /add-package を使用します。
パッケージは d:\NanoServer\Packages フォルダの下に格納されております。

ここでは、d:\NanoServer\Packages フォルダにカレントディレクトリを移動させた後、Microsoft-NanoServer-OEM-Drivers-Package.cab を追加しています。

  • dism /add-package /packagepath:.\Microsoft-NanoServer-OEM-Drivers-Package.cab /image:c:\

add-package ではインストール先の「システムイメージ」を指定しますが、ここでは c:\ 以下に展開されたイメージが対象のため、c:\ としています。

パッケージを追加
警告が気になる場合は、2GB以上のディスクを用意する事

ここではディスク容量が小さく作業領域(ScratchDir)が小さいせいで警告が出ています。確かに、今回ディスクサイズを1GBにしたので、イメージを展開した分容量が取られており、空き領域が 1GBを切っています。仮想マシンのディスクサイズをそもそも2GB程度にすればこの警告は生じませんし、今回のように強行しても、1個ぐらいのパッケージなら問題なく展開できたりもします。

VMware 上の仮想マシンの場合、この Microsoft-NanoServer-OEM-Drivers-Package.cab は必ず入れてください。この中に LSI Logic の SCSIドライバなども含まれているため、このパッケージを追加しないと、OS起動後に C:ドライブをマウントできず、BSODになります。

その他の役割については、こちらのページを参照してほしい。「Creating a custom Nano Server image」の項目にある表が、概ね機能と対応するパッケージになります。厳密にはこの表は、事前にパッケージを組み込んだ NanoServer.wim を作るために使用する New-NanoServerImage コマンドレットの引数になってますが、たとえば Hyper-V の役割をインストールするための「-Compute」なら、「Microsoft-nanoServer-Compute-Package.cab」とか類推がつくかと思います。

また、c:\NanoServer\Packages フォルダの直下だけではなく、言語ごとのフォルダもあります。日本語の場合、c:\NanoServer\Packages\ja-jp というフォルダがあり、同名のパッケージがあるのでこちらもインストールしておいてください。
(ただし、NanoServer のコンソール画面は英語しか表示できないため、ローカルコンソールでの日本語関係は化けてしまいます。)

・起動パーティションとして指定

さて、最後に起動パーティションとして指定します。これは、bcdboot コマンドを使用します。

  • bcdboot c:\Windows /s c:

bcdboot でブートローダーの設定を作成


bcdboot.exe もまた WindowsVista から導入されたコマンドで、winload によるOS起動を制御します。ここでは、c:\Windows から Windows  を起動することを指定しています。その設定は c: に、つまり同じドライブに書き込まれます。

実のところ、これはちょっとした手抜きです。Windows をGUIからインストールした場合は PC-BIOS の場合も先頭に100MB程度のシステムパーティションが作成され、こちらに OS起動の設定が書き込まれます。UEFIの場合、EFIシステムパーティションが必須であり、こちらで認識する必要があるから別パーティションを用意する必要はあります。

一方、PC-BIOS の場合はその必要性はさしてないですし、仮想マシンの場合固定したOSを固定したパーティションから起動する、せいぜい起動オプションを変えたモードを用意するぐらいですので、これでも問題ない、という判断からです。
なお、Microsoft のページでも、「不要なら削除して構わない」となってます。

気になる方はシステムパーティションを作成し、/s の指定先をそちらにした方が良いでしょう。

bcdboot で設定が正しく書き込まれたかは、bcdedit コマンドで確認できます。
  • bcdedit /store c:\Boot\BCD
bcdedit コマンドでブートローダーの設定を確認
bcdedit 単体で実行すると、現在起動したOS(この場合はX:)の設定を表示するため、
ここでは /store でどこにある設定を読み込むかを指定している

Windows ブートマネージャー の項目が、ブートマネージャーそのものの設定、たとえば表示言語(ここではen-us)などが表示されます。ブートマネージャーの default に表示されている Identifier の項目が起動時に使われます。また、次の displayorder に複数の Identifier が表示されている場合、この順でメニュー表示され、どの設定から起動するかを選択することができます。メニューを表示して何秒待ったら起動するかは、timeout に設定されます。

ここでは {default} という Identifier の設定が一つだけ、 Windowsブートローダーの項目に表示されています。

詳細な内容については、こちらのページもあわせてご参照ください。


さて、これで準備は終わりました。コマンドプロンプトウィンドウを閉じて、下のインストーラーのパネルを閉じる事で再起動されます。または、コマンドプロンプトウィンドウから「wpeutil reboot」コマンドを実行する事でも再起動が行われます。

再起動後、HDDから起動が行われ、Nano Server が起動してきます。

Nano Server 起動中
ブートローダーはフルインストールと同じためここだけはグラフィカルだ


Nano Server 起動。
本当に何のUIもなく真っ黒だった 以前のTPと異なり、
TP5やリリース版では最低限のUIはついた。本当に最低限だが

初期状態では Administrator にパスワードが入っていませんので、ユーザ名に Administrator を指定してリターンをたたくと、初期パスワードを入力を要求されます。

ここで Administratror のパスワードを設定

DHCPから採取された IPアドレスなどは画面に表示されるので、あとはRSATを使って管理する、または SMTを使って管理するなどで、Nano Server を扱うことができます。
( Azure 管理コンソールで Windows Server もまとめて管理できる SMT は、マイブームだったり(笑) )

Networking を選択、リターンを押すとIPアドレスの設定が確認できる

● EFI の場合は?

PC-BIOS と EFI で異なるのは、ブートの手順になります。
BIOSの場合は、MBR に記載されたシンプルな一次ブートローダーがアクティブに指定されたパーティションの二次ブートローダー、つまりは winload を呼び出し、winload が bcdboot で記入した設定を読み込み、ブートします。MBR に入れることができるブートローダーはリアルモードかつ容量も限られているので、winload そのものを入れるのではなく、二段構えになっています。

EFI の場合は、 EFI システムパーティションに組み込まれたブートローダーがOSを起動します。Windows の場合は EFI に winload が存在し、これが Windows を起動します。EFIシステムパーティションは100MBないしそれ以上あり、EFIがブートローダーに提供する機能も BIOS に比べ張るかに高機能なことから、winload が直接利用できるわけです。

このことから、二つの部分がかわってきます。
一つはパーティションの作成。GPTパーティション形式にした上で、EFIシステムパーティションを用意する必要が出てきます。
二つ目は、bcdboot での指定。BIOSの場合は winload も bcdboot の設定も c: にごっちゃに入れてましたが、EFI の場合は /s で指定する格納先は EFIシステムパーティションになります。

では、手順を見てみましょう。

最初に重要なのは、仮想マシンを作成したら「ファームウェアをEFIにしておく」事です。ゲストOSの設定にもよりますが、Windows Server 2016(64bit)を選択してもデフォルトはBIOSになってます。

仮想マシンのプロパティの「オプション」「起動オプション」で
ファームウェアをEFI にして、OKを押す
そこからインストールメディアで起動し、diskpart を起動するところまではBIOSとわりません。

Windows Server 2016 のインストールメディアから起動
ここからコマンドプロンプトウィンドウを出すところは同じ

実行する DISKPART のコマンドが少し変わって、以下になります。
  • select disk 0
  • convert gpt
  • create partitoin efi size=100
  • format quick fs=fat32 label="System"
  • assign letter=s
  • create partition msr size=128
  • create partition primary
  • format quick fs=ntfs label="nano server"
  • assign letter=c

select disk0 で1本しか繋いでいない仮想ディスクを選択するところまでは一緒です。
次の convert gpt でパーティションの記録形式をデフォルトのMBR形式から EFI で使用する GPT パーティション形式にしておきます。

次に、create partiton efi で、EFIシステムパーティションを作成しておきます。GPTパーティション形式では、内部的には UUID でそのパーティションがどういうものかを記録しております。が、一々 長い UUID を入力するのは人間業では辛いので、「efi」というシンボルで EFIシステムパーティションであるというUUIDを入れてもらっている訳です。なお、size=100 は 100MiB のサイズで確保する事をさします。create partition でサイズ無指定だと開いてる所全部、となります。

その後、FAT32形式でフォーマットします。EFIシステムパーティションの実体はFAT32のため、FAT32でフォーマットする次第です。ボリュームラベルは Windows のデフォルトインストーラにあわせて「System」にしています。

また、ここでドライブレター「S」を割り当てております。EFIシステムパーティションはOS起動後はマウントされない、不可視のものですが、ここではBCDの起動設定を入れなければならないので、邪魔にならないところにマウントしている訳です。

EFIシステムパーティションの作成。
なお、EFIシステムパーティションを略してESPと呼ぶこともあります。
続けて、「create partition msr size=128」で MSR を128MiBで確保してます。MSRは、Microsoft 予約パーティションの略で、他のシステムパーティションに関する情報が格納される、とあります(どうも、Reserved の R ではなく Recovery の R ではないのか?って気はするけど、さておき。)

ともあれ、EFIシステムパーティションの次、C: ドライブとなる Windows パーティションの前に配置することになってます。これはパーティションが存在すれば良く、フォーマットしたり一時的にドライブレターを割り当てて中に何かかき込む必要はありません。

さて、三つ目がプライマリパーティションで、要は Windows をインストールするパーティションです。パーティション作成後、NTFSでフォーマットして、C:をアサインしてます。

なお、BIOSでの起動(MBRパーティション形式)の時と異なり、active でアクティブパーティションを決める必要はありません。EFIは必ず、EFIシステムパーティションを見に行き、そこのブートローダを利用する、どのパーティションから起動するというのはブートローダ側の仕事となっているからです。
続き、MSRとC:ドライブを作成

WIMイメージからの展開と、ドライバーなどのパッケージの導入はBIOSの時と同じです。

さて、ブートローダの設定がBIOSの時とはまた変わってきます。

今回、実行するコマンドは以下になります。

  • bcdboot c:\Windows /s s:

WIMイメージの展開、パッケージの導入の後、bcdboot で起動ドライブを設定

起動するOSとして c:\Windows を指定するところまでは同じです。が、その後、ブートローダの設定をかき込むのは EFIシステムパーティションである s: ドライブになります。
その後の bcdedit での確認も、以下になります。

  • bcdedit /store s:\EFI\Microsoft\Boot\

EFIシステムパーティションでのブートローダなどは、ルートのEFIフォルダに格納されます。Windows のブートローダーwinload の設定は EFI\Microsoft\Boot 以下に記載される訳です。これはBIOSの時の\Boot\BCD とパスが違うので注意です。

さて、あとはシャットダウンして再起動するだけで、BIOSの時と同じように起動してきます。
一応、EFIから起動した Nano Server...別にBIOSの時と変わらないのですが。
BitLocker などを使わない限りは別にEFIでもBIOSでもOS起動後の動作は変わらないですし、そもそも vSphere では TPMが使えない(仮想TPMが存在しない...これも何とかしてほしいのですが)ので、ことさら EFI にする必要はない、といえます。

.

2016/12/01

Pico process

とある事情で少々調べたので、ここにメモしておく。

だいたいの元ネタは、以下のページになります。
https://blogs.msdn.microsoft.com/wsl/2016/05/23/pico-process-overview/


● PE と ELF

Windows は Portable Executable (PE)という実行ファイル形式をサポートしている。逆に言えば、PE形式のバイナリしか起動させることができない。NT系の Windows では、環境サブシステム(Environment Subsystem) という名前のパーソナリティを、NT Executive というマイクロカーネル上に複数実装できるようになっており、実際に OS/2, POSIX, Interix などのサブシステムが存在した。

しかし、実はこれらの、Win32とは異なるサブシステム上のバイナリも、実質的に PE形式のバイナリ(OS/2については変種だが)を実行するものであった。Service for UNIX の UNIXコマンドも PE形式だったわけだ。

一方、Linux は ELF形式のバイナリを実行するようになっている。

Windows Service for Linux (WSL) が Ubuntu のバイナリを無変更で実行していると言うことは、とりもなおさず ELF形式の、本来実行できないバイナリを実行していることになる。

これはどうやって実現しているのだろうか?

● pico process

WSL のキモが、この pico process を使った ELF バイナリの実行だ。
pico process というものは Microsoft Research で開発された Drawbridge より持ち込まれた、より軽量なプロセスを指す。下図の右側が通常の Windows でのアプリケーションプロセスだ。

NT Process, Minimal Process, Pico Proess
https://blogs.msdn.microsoft.com/wsl/2016/05/23/pico-process-overview/  より抜粋

Windows のカーネルは、アプリケーションの起動時、アプリケーションが必要とするメモリを確保した後、アプリケーションの実行に必要なモジュールをそのメモリ内にロードする。全てのプロセスで共通の NTDLL.DLL や、アプリケーション間で共有されるユーザの情報、スレッドが実行するのに必要な情報(TEB)等々だ。もちろん、アプリケーションのバイナリやDLLもこのプロセス内に展開される。アプリケーションが実行をはじめた時には、アプリケーションが必要な情報はメモリに全部用意された状態になっている。

これは便利だが、言い換えれば、Windows のお仕着せの方式でメモリが利用されてしまっている。何らかの理由でメモリ上の位置を最初から変えておきたい場合、これは不都合が多い。

Windows10 では、Minimal Process と Pico process というこれまでとは違うメモリの使い方をしたプロセスを用意した。


Minimal Process はメモリ内のお仕着せの準備を一切やめた。プロセスが用意されたときはメモリはすっからかんで用意される。スレッドも用意されないので、このプロセスはほっとくとメモリを食ってるだけでCPUがスケジュールされず、つまり実行されない。それ以前に実行すべきプログラムもメモリ上に展開されていないのでCPUが割り当てられても実行することができない。
ただ、環境サブシステムなど特権的なプロセスはこのメモリ内に色々書き込むことができる。適切なコードを割り当て、スレッドを作れば実行もできるようになる。通常の Windows のアプリケーションとは別種のものを実行しつつ、最低限の管理は NT カーネル 側で実施されるわけだ。
Windows10 では、メモリ圧縮や「Device Guard」「Credential Guard」といった仮想化を利用したセキュリティ機能で、この Minimal Process が利用されている。


Minimal Process はメモリはすっからかんでも、特定の手順(システムコール)でOSを呼び出させば、他のアプリケーションと同じく Windows のOSの機能を呼び出すことができた。
Windows も Linux も、最近の x86-64 (x64) の OS では、CPU のもつ sysenter もしくは syscall という命令を使用する。呼び出したいシステムコールの番号をCPUのレジスタに記録、指定したあと sysenter 命令を実行する。sysenter を実行した瞬間にアプリケーションは停止、各OSのカーネル側に処理がうつり、CPUのレジスタの中を見てアプリケーションがどのシステムコールを呼ぼうとしたか、どういうデータをわたそうとしたかを確認、処理を行う。ただ、どのシステムコール番号がどの処理に対応しているかとか、そもそも処理の有無や機能がOSごとに異なっているわけだ。


通常のプロセスでも Minimal Process でも、sysenter 命令が実行された場合の処理は同じ NTカーネルが担う。

一方、Pico Process では、Pico Provider と呼ばれるカーネルのモジュールが sysenter 命令の処理を行う。Windows に代わってお仕置き...ではなく対応を行うわけだ。WSL の場合、カーネルに組み込まれる LxCore.DLL, LXSS.DLL のどちらか(多分 LxCore)が Pico Provider になっている。ここには Linux のシステムコールが「そのまんま」実装されている。つまり Windows のシステムコールではなく、Linux のシステムコールの番号として判断され、適切な処理が呼び出される。


● bash 起動から、Linux コマンドの実行まで

bash.exe をアイコンから実行すると、これはただのコンソールアプリケーションのため、コマンドプロンプトウィンドウが開き、その中でコマンドが実行される。LxCore, LXSS が必要に応じてNTカーネルに読み込まれ、LxssManager が起動される。

(多分)LxCore が pico process を生成し、(多分)LXSS とサービスとして起動される LxssManager が協力してファイルシステムにある ELF形式の init や bash のバイナリを読み込み、すっからかんのプロセスメモリ内に「さもLinux のように」展開を行い、スレッドを作ってCPUを割り当てる。通常の命令はCPUによりそのまま実行される。


ファイルを読み込んだりテキストを出力を試みると、これはOSの力を借りることになるのでシステムコールが呼ばれる。このとき、sysenter の結果は NTカーネルではなく(多分)LxCore が引き取り、Linux のシステムコールとして処理がなされる。簡単なものなら (多分)LxCore に記述された Linux と同じ処理が行われて、結果が pico process に返される。コンソールへの出力の場合は、LXSS 経由で LxssManager が呼び出され、bash.exe にわたされ、コマンドプロンプトウィンドウに出力がなされる。


Linuxのバイナリは何一つ書き換えられることなく、Linux カーネルの上で実行されていたのと同じように、Windows10 のNTカーネル+LxCore+LXSS の上で実行、できてしまうわけだ。


2016/05/15

Fusion 上の仮想マシンのネットワークとパケットキャプチャ


Fusion 上の仮想マシンは、通常、以下3種類のいずれかで外部ネットワークと接続している

NAT :  仮想的なスイッチに接続、外部とはアドレス変換(NAT)を通して接続
ブリッジ: 指定のNICをホストOS(Mac)と共有、NICを通じて直接接続
ホストオンリー: ホストOS(Mac)とだけ接続

デフォルトでは、NATのネットワークは VNET8, ホストオンリーは VNET1 と定義されており、OS X 側の vmnet8 というインターフェイスが VNET8 に接続、vmnet1 が VNET1 に接続されている。

VNET8 については、さらに vmnet-dhcpd と vmnet-natd が起動しており、それぞれ DHCPによるIPアドレスの割り当てと、NATの制御を行っている。

VNET1 は vmnet-dhcpd のみが起動しており NATが行われない。このためホストOS(Mac)としかつながらない。

Fusion の仮想ネットワーク構成
なお、Fusion Professional ではVNET1.8以外のネットワークをカスタム構成できる
さて、仮想マシンがどういったパケットを送出しているかを確認したいときがある。
OS X にはデフォルトで tcpdump が用意されているので、ターミナルから以下のように実行することでパケットのキャプチャを行うことができる
sudo tcpdump -i vmnet8 port 80
なお、Fusion 8.0.1 まででは上記のコマンドではパケットキャプチャができず、以下のように pktap デバイスを併用する必要があった。(こちらのブログに詳しい説明あり)
sudo tcpdump -k pktap,vmnet8 port 80
これは VMware の提供する vmnet デバイスが tcpdump などパケットキャプチャツールが使用する Berkley Packet Filter (BPF) をサポートしていなかったためだ。

この問題は Fusion 8.0.2 にて解消されている









2016/02/06

vExpert 2016 受賞しました

転職したのもあって今回ばっかりは無理かなぁと思ってましたが、なんとか今年も vExpert 2016 を受賞できました。ありがとうございます。

http://blogs.vmware.com/vmtn/2016/02/vexpert-2016-award-announcement.html

2016/01/31

Fusion でリカバリモードで起動する

VMware Fusion 上の OS X でリカバリモードでの再起動をおこなう場合だが、KBによると実機のOS Xと同じく、起動画面で Command-R を押すといいとある。

しかし、実際に試すとこれがなかなかうまくいかない。VMware の提供する EFIの BootManager が表示されてしまう。もっと確実に起動できる手順はないか、ということで行ったのが次の方法だ。

まず、EFI の BootManager を表示させる。これは、Command-R を押しながら起動して失敗した場合でもいいし、「ファームウェアをパワーオン」を使ってもいい。


ここで、「Enter Setup」を選択する


次の画面で「Configure Boot Option」を選択する


さらに、「Add Boot Option」を選択する

3番目に「Recovery HD」があるはずなので、これを選択する。
なお、OS X をインストールすると三つのパーティションが作られる。一つが EFI システム領域、一つが OS X そのもののインストール領域、そして最後が Recovery HD だ。

選択したパーティション内のファイル一覧が表示される。


ここでは、<com.apple.recovery.boot> フォルダを選択


し、その中の「boot.efi」を選択する。

boot.efi を使った起動の設定画面が表示されるので、「Input the description」を選択、この設定の名前を入力する。ここでは、「Recovery HD」とした。


その後、下の Commit changes and exit を選択し、元のメニューに戻る。


さらに、Exit the Boot Maintenance Manager を選択、元の起動メニューに戻る。


すると、先ほど作った「Recovery HD」がメニューに増えているのでこれを選択する。

後は起動を待つだけだ。
起動に時間がかかるので待つべし

起動してしまえば、実機のリカバリモードと同じように使用できる。


なお、二度目からはメニューに登録されているので、単に「ファームウェアをパワーオン」を選択、Recovery HD を選ぶだけになる。

【余談】メモリ解放とかメモリ最適化という迷信

OS X のメモリ管理は十分に近代化されており、アプリケーションに対して最適な配置をし、IOの性能確保にディスクキャッシュを行い、アクセス頻度の低い部分を圧縮したり、ディスクに書き出して解放したりを自動的に行う。

非常に端的に言って、性能を持つためにユーザが何か操作する必要はない。まったくない。ほっておけば自動的に行われる。

しかし、OS X のリリース以来、メモリの最適化とかメモリ解放などの操作や、それを行うアプリケーションが取りざたされてきた。定量的な性能評価もなくただ印象で「速くなった」って感想と共に、ね。

古典的なソフトのよくある挙動は、ただひたすらメモリを要求し、実際にアクセスして確保するというものだ。Mach はメモリの要求(vm_allocate)を行っても実際の物理メモリを確保しない。アクセスされるときにはじめて確保動作が行われる。なぜって?プログラマは往々にして多めに多めにメモリを要求するものだ。要求道理に渡しても使われないことは多々ある。だったら、使われる段に割り当てた方が遙かに効率的な訳だ。

メモリを要求し、ひたすら物理メモリを確保する、その後、終了すると大量のメモリが一気に空く。対価としてそのアプリを実行が終わるまでの待ち時間と、全てディスク上に追い出され読み込み直しになるバックグラウンドアプリの時間を引き替えに。そんな気休めアプリが有償であったりもしたのだ。

そして、今度は「システム標準のメモリ解放コマンドがある」という噴飯物の記事を見かけた訳だ。

https://book.mynavi.jp/macfan/detail_summary/id=37786 より

...この人、とりあえず man を見てないことだけは理解した。
いかが、purge の man の結果だ。

man purge

見ての通り、「ディスクキャッシュの解放」をするだけで、malloc や vm_allocate で確保されたアプリケーションのメモリには何ら影響がないことが明言されている。

てか、先の記事の解放内容も見ると分かる。この記事の書き手は、使用済みメモリが 14.90GB から 13.12GB に減ったことをわざわざ赤枠で示しているが、その横のアプリケーションメモリを見ると 10.92GB から 11.03GB に「増えて」いる。その代わりファイルキャッシュが 2.21GB から 268.9MB に減ってる。
2GB弱のディスクキャッシュを吹っ飛ばして、その分の空きが増えたことを喜んでるのだ。

先のページの結果を上下に並べて表示
purge コマンドの内容通りの結果になってるのが分かる。

そして、横にあるアプリケーションメモリとかファイルキャッシュの変動に気がついてもいない、訳だ。なお、アプリケーションメモリが増えればディスクキャッシュは自然と解放される、つまり必要のないことだ。

これでどのような効果があるか? せいぜい、再び同じIOがあったときにディスクを読み直すのでIO性能が劣化する、ぐらいだろうね。

Mac の記事の多くはこのような無知と願望にもとづいたものが多い。

ライターの頭は治しようがないので、せめて読み手がよく気をつけることだ。


2015/12/23

【Windows10】コンパクトOSでディスク占有量を削減する

Macbook Air(2012)を業務に利用しているが、3年前の機種とはいえ性能的には全く不満はない。ただ、ディスク容量が 256GB しかないため、仮想マシンを沢山作っていると容量が足りないことがままある。そこで、普段使いの Windows10 についてはできるだけ小さくインストールすることを試してみた。


● コンパクトOSとは

Windows10 では、コンパクトOSという、主に小容量ディスクのマシン向けにシステムを圧縮して占有ディスク領域を削減する機能が用意されている。詳細は、以下ページを参照して欲しい。
https://blogs.windows.com/japan/2015/04/01/how-windows-10-achieves-its-compact-footprint/
https://msdn.microsoft.com/ja-jp/library/windows/hardware/dn940129(v=vs.85).aspx


以前の Windows8.1 では、同様の目的で wimboot という機能が存在した。wimboot はシステムファイルそのものをインストールせず、リカバリパーティションにある再インストール用イメージの中のファイルをつど参照することで、システムの占有するディスク容量を節約することができた。ディスク容量の少ないネットブックやタブレットなどで便利だっだのだが、一方で様々な問題が存在した。

たとえば、WindowsUpdate で更新されたシステムファイルは通常のディスク領域に配置され、かつ圧縮されていないため、時間がたつにつれシステム領域が肥大していくという難点があった。wimboot が参照しているイメージファイルを書き換えられないことからくる制限だ。
wimboot は SSD/eMMC といったソリッドステートドライブ向けで、HDD はサポートされない、ファームウェアに EFI が必須で PC-BIOS をサポートしないなどの制限もあった。


そこで、Windows10 では wimboot ではなく、コンパクトOSという方式に切り替えられた。

コンパクトOSでは、通常と同じくシステムファイルはインストールされる。ただし、ファイルごと個別に圧縮がかかった状態になっている。WindowsUpdate がかかったときにはシステムファイルが置き換えられるが、更新されたファイルも圧縮されているので容量の肥大は緩やかにとどまる。
また、wimboot とは逆に、リカバリパーティションにはファイルそのものが配置されず、通常のシステム側のファイルを参照するだけとなっている。

これにより、システムファイルを圧縮、リカバリ用イメージとの重複を避けることでディスク領域を削減するという wimboot と同じ特徴を持ちつつ、アップデートによる肥大を避けることができるようになった。

ハードウェアについても、SSD向けであるのは変わらないとしても、PC-BIOSでもブートできるよう制限が緩和された。


● 圧縮がかかってるかの確認

圧縮がかかっているかは、compact コマンドで確認ができる。

管理者権限のコマンドプロンプトで compact コマンドを実行、引数に /compactos を
指定、query オプションをつけることで現在の状態を確認できる

wimboot も windows10 のシステムの圧縮もどちらかというとタブレットなど、ディスク容量に制約がある機器向けのもので、通常のパソコンに Windows10 をインストールするとシステムの圧縮はまず使用されていないはずだ。

圧縮してインストールするかどうかは、システムをインストールするディスクの容量と、そのマシンのCPUスペックを見るとある。システムを圧縮、展開するのはそれなりに負荷がかかるため、非力なマシンの場合はかからないことがあるようだ。

物理ハードウェアにインストールする際は、それでもいいだろう。

タダ今回は仮想マシンにインストール、さらにクローンでディスク容量を取らないようにするのが目的だ。CPUパワーは充分にあるし、ディスク容量はクローンするごとに差がでてくるので、強制的に圧縮したインストールを行った。



● 仮想マシン上での、システムの圧縮されたままでインストールする

まずは VMware Fusion などで普通にWindows10 のインストールメディアから仮想マシンを作成する。
通常のインストール手順を使わないので簡単インストールはオフにしておくこと。

仮想マシンを起動したら、最初の画面でSHIFT-F10 を押し、コマンドプロンプトウィンドウを呼び出す。

コマンドが使えるようになったら、以下コマンドを実行してインストール先となるパーティションを作成、NTFSでフォーマットしておく。

X:\Sources> diskpart
DISKPART> elect disk 0
DISKPART> create partition primary
DISKPART> select partition 1
DISKPART> format quick
DISKPART> assign letter=e
DISKPART> active
DISKPART> list partition
DISKPART> list volume
DISKPART> exit

diskpart コマンドを起動、最初のディスク(disk 0)を選択、プライマリパーティションを一つ作成する。容量を指定していないのでディスクの空き全てをそのパーティションに、つまり全領域で一つのパーティションが作成される。

select partiton 1 で作成したその最初のパーティションを指定する。なお、ディスクやボリュームと異なり、パーティションだけは1から始まるので要注意。

format quick でNTFSでのNTFSでのクイックフォーマットをかけ、仮に Eドライブと設定しておく。アクティブパーティションとサインすることで、終了だ。

list partiton ではパーティション一覧が、list volume では Windowsが最終的に認識するドライブ一覧が表示される。パーティションの先頭に * があってアクティブである事、ボリューム一覧で DドライブとEドライブがあることを確認しておこう。また、Dドライブはブートした isoイメージだ。



確認が終わったら終了をし、こんどは OS イメージの書き込みを行う。
X:\Sources> dism /apply-image:D:\source\install.wim /index:1 /applydir:e:\ /compact
最後にある /compact がシステム圧縮されたままのインストールの指定となる。忘れないように。

dismコマンドの実行が終わりイメージのインストールが終わったら、以下コマンドでブートローダをセットアップする
X:\Sources> bcdboot e:\Windows /s e:
セットアップが終わったら、一旦シャットダウンする。
再起動でなくてリブートでもいいと思うだろうが、再起動だとなぜか直後のブートに失敗することが頻発した。リセットして起動しなおすと次のフェイズに行くのだが、ここは確実性を取っていったん仮想マシンごと停止している。
X:\Sources> wpeutil shutdown
再び仮想マシンを起動し直すと、初期設定のフェイズに入る。

初期アカウントの作成、WindowsUpdate の適用などが行われ、デスクトップが表示されてインストールが完了する。

この時点での VMDK サイズだが、おおむね 5〜6 GB 程度になる。通常のインストールだと 9GB 程度になるので、3-4GB 程度、4割ぐらいが削減できたようだ。


● すでにインストールされた Windows10 をコンパクトOSにする

通常のインストールを行ったWindows10でも、後からコンパクトOSに圧縮し直すことは可能だ。管理者権限で compact /compactos:always を実行すると、システムファイルに圧縮がかけられ、コンパクトOS化される。

既存の Windows10 をコンパクトOSに変更。
それなりに時間がかかり、CPUやディスクに負荷がかかるので注意
この処理は CPUとディスクIOをかなり使う処理なので、時間と電源に余裕がある場合に実行すべきだ。上記手順でコンパクトOSとしてインストールしたものと、インストール後にコンパクトOS化では容量差はない模様。CPUと時間を節約したければ最初からコンパクトOSを、手軽さを考えるなら通常インストールからの compact /compactos:always を入れる、という感じだろう。