ラベル Linux の投稿を表示しています。 すべての投稿を表示
ラベル Linux の投稿を表示しています。 すべての投稿を表示

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 の上で実行、できてしまうわけだ。


2014/03/16

Hyper-V on Fusion

知己からの相談。Hyper-V 上の Linux (CentOS 6.5)が正しく動かないと。
CentOS 6.5 は Hyper-V のサポートリストにないと返答し逃れようとしたら、いや、統合サービスがカーネルに統合されているし動くはずだとの主張。そして送られてきたスクリーンショットを見たら、ただの Hyper-V ではなく、Fusion 上の WindowsServer 2012 であった。

Hypervisor on Hypervisor はテクがいるんだよと煙に巻いたのだが、しかしやったことがない、できないでは何とも面白くないのでサンフランシスコ出張中、まだ真っ暗闇の3時頃にむくっと起き上がり手元で構築をやってみた時のメモを再構成したのが以下のものだ。

なお、WindowsSever 2012では面白みがないので、今回は Windows 8.1 Enterprise の Client Hyper-V を使ってみた。

● Fusion 上で Hyper-V を実行させ、その上でLinuxを動かす条件

条件は以下の通りだ。
  1. Windows8 は 64bit 版がインストールされていること
  2. 仮想マシンの設定の「プロセッサとメモリ」にある「この仮想マシンでハイパーバイザーアプリケーションを有効にする」にチェックが入っていること
  3. 以下2行を VMX ファイルに書き足してあること
    • mce.enable = "TRUE"
    • hypervisor.cpuid.v0 = "FALSE"
  4. Hyper-V 上の仮想マシンのMACアドレスを"固定"させること
64bit 版でないと Hyper-V は利用できないのでこれは当然と言える。2. の設定により、vmx ファイルに 
vhv.enable = "TRUE"
が書き込まれる。ESXi など VMware製品ではこの設定だけで動くが、Hyper-V の場合、「Hyper-V をインストールできません。: ハイパーバイザーが既に実行されています」と出る(下図)

これを回避するために、3. のオプションを指定し、MCE(Machine Check Exception)拡張を有効にし、CPUID命令でハイパーバイザを検出されないようにする必要がある訳だ。

ここまでで Hyper-V は動作するが、このままだと知己の言うとおりでHyper-V 上の仮想マシンでの Linux がインストール後の起動時に panic してしまう。

この事象の回避には、「Hyper-V 上の仮想マシンのMACアドレスを静的にする」ことが必要なわけだ。この点は少々厄介なので、以下の手順を見て欲しい。

● インストールの実際

では、実際のインストールを追ってみよう。

まず、Fusion で仮想マシンを作成する。Windows8.1 のメディアかイメージがあるなら話は早い。
Fusion のメニューから「ファイル」-> 「新規...」を選び、「ディスクまたはイメージからインストール」を選んだまま「続く」ボタンを押せばいい。
簡易インストールパネルでアカウント名やプロダクトキーを入力、仮想マシンを作成すればOSのインストールから初期設定、ライセンス投入、VMware Tools のインストールまで一気にやってくれる。

インストールが終わったら一旦仮想マシンを停止して、先の条件2と3のセットをしておこう。(もちろん、仮想マシンの作成の折に「設定のカスタマイズ」を押して、作成後すぐに仮想マシンを起動させず、設定を編集するタイミングを作っても良い。なお、このときフロッピードライブを削除しないように。)

また、メモリサイズもデフォルトの 2GB から Hyper-V上の仮想マシンの実行分増やしておいた方がいいだろう。


Windows8.1 のデスクトップの左下端には復活したスタートボタンがある。ここを右クリックするとコントロールパネルに素早くアクセスできる。

今回は「プログラムと機能」を選択、Hyper-V をインストールする。
インストール後に再起動がかかるので、またログインし直し、デスクトップの右側から「Hyper-V マネージャ」を検索、でてきたら右クリックして「管理者で実行」をする
(普通の実行でも問題ないかもしれない)


Hyper-Vマネージャが起動したら、まず仮想スイッチマネージャから仮想スイッチを一つ作っておく。インターネットに接続する必要がある場合は「外部」で作っておく。また、「外部」の仮想スイッチを作ると以後 Windows8側のNICがプロミスキャスモードで動こうとして、その結果認証のパネルが表示される。都度パスワードを入れて許可しておこう。

さて、次はHyper-Vでの仮想マシンの作成だ。
Hyper-Vマネージャの「編集」メニューから「新規」「仮想マシン...」を選択、ウィザードに従って仮想マシンを作成する。
「仮想マシンの世代」をきかれたら第一世代にしておく。第二世代は Windows 8,WindowsServer 2012 でないと意味がないからだ。

ネットワークの構成では、先に作った仮想スイッチを指定しておく。

メモリサイズとストレージ容量は適当でいいが、今回は 512MBと10GBを指定した。それぞれ動作チェックのため節約をしただけだ。

インストールは CentOSの ISOイメージから行うが、「Fusion 側でWindows8仮想マシンに ISOメディアをマウントして、Hyper-V側仮想マシンはDドライブを参照」と、「Windows8仮想マシンにISOメディアをコピーしておき、Hyper-V側仮想マシンでISOメディアをして」の二つのやり方が考えられるが、どうも前者はあまり安定しないようだ。面倒でも ISOイメージをコピーして、後者のやり方にした方がいい。

さて、ISOイメージを仮想CD-ROMにマウントさせたら、Hyper-V側で仮想マシンを起動する。
そして、CentOSのインストーラが起動したら、"Hyper-Vマネージャで仮想マシンの電源を落とす"。ここが重要なポイントだ。

Hyper-V側で仮想マシンを停止させた後、Hyper-Vマネージャで仮想マシンを右クリック、「設定...」を選択し設定パネルを開き、「ネットワークアダプター」の「+」ボタンを押し項目を展開、「高度な設定」から「MACアドレス」の「動的」のラジオボタンを「静的」に変更する。


動的に変更後、その下の6つの入力項目に00ではない、十六進の数値が入っていることをちゃんと確認した後、OKを押し設定を閉じる。

その後、Hyper-Vマネージャにて仮想マシンを起動、通常の手順で Linuxをインストールすればちゃんとインストールでき、その後もエラーなく利用が可能だ。

● Hyper-VのMACアドレスの仕様

Hyper-Vのデフォルトでは、MACアドレスの設定が「動的」になっており、仮想マシンの起動の際にMACアドレスが自動生成される。
ここまではまあ構わないのだが、困ったことに、このままだとMACアドレスは起動のたびに変わりうる。どうもそこで齟齬が起こり、パニックしているようだ。この件についてはマイクロソフト社のフォーラムにも記載がある。

手っ取り早く直すのに、MACアドレスを「静的」にして一意に固定してしまえばいいのだが、しかし一度も起動していないHyper-Vの仮想マシンは、MACアドレスが00-00-00-00-00-00 になっている。

これはこれで問題の元のため、「動的のまま一度起動することで適当なMACアドレスを割り当てさせ、その後停止、割り当てたアドレスのままで静的に設定を変更し、MACアドレスを固定する」という手順になる。

なお、クロックのところでパニックしているのでLinux側のクロックソースを直す、という解法もあるようだ。
ただ、CentOSを含むRHEL6系のOSでは、インストール時にMACアドレスを記憶してそのMACアドレスを持つNICに指定したIPアドレスを割り当てるようにする。MACアドレスがころころ変わると、その都度IPアドレスの設定をやり直す必要が出てくる。どのみち、MACアドレスは固定する必要がある。

そもそも Fusion 上で CentOSを動かせばこんな面倒はないのだし、やる人はそうそういないと思うが、引っかかると言えば引っかかるところなので、メモとして残しておく。


2014/01/08

[余談] CentOS 6.x で Oracle のインストーラで文字化けをさせず日本語でインストールする

新年早々ではあるが、昔の書きかけをずっとほったらかしていたのを世に出しておく。
仮想化と何の関係があるか?と言われると意外とある Oracle DBのインストールについてだが...。以下本文。


vCenterServer や View と付き合ってるとどうしてもリレーショナルデータベース(RDBMS)とのつきあいが深くなる。

ここ1年以上、5 Host / 50VM を越える場合は Oracle を使っている。特に vCenterServer での利用ではコスト面で10倍近くの差がある。意外に思われるかも知れないが、CPUライセンスでなければならない MS SQL Server Standard より、Named User が通る Oracle Standard One の方が大幅に安すくなるのだ。

さて、あらたに環境を作るに当たって、久方ぶりに Oracle を新規インストールしようとしたところで大きくハマってしまった。

事の元凶は CentOS 6 を使ってしまったこと。これまでは Oracle Linux か CentOS 5.x を利用していたが、後者は普通にインストールするとあまりに余計なもの、例えば X Window Server 、をインストールしてしまうので少々閉口していたのだ。

CentOS 6 はそうした余計なものをインストールしない、なんせ Perl すらデフォルトでは入らない、という事に好感を持っていた。

そのせいでついうっかりと CentOS 6 のテンプレートをデプロイしてそこに Oracle を突っ込もうとしたのだが...、甘かった。
いくつかあるのだが、一つ目はパッケージ名の問題。Oracle Linux や CentOS 5 で必要としてたRPMと名前が異なるため、一々確認と yum  install のし直しが起こってしまった。

Oracle Linux 6 ではどうしているのか気になってみてみたら、どうも "専用のRPM"を用意して対処してしまった模様。この専用RPM、RHEL互換なら Oracle Linux でなくても突っ込めそうな感じだが、さすがに CentOS6 にこのRPMを入れるのは気が引けたので、地道に調べることとなった。(しかし、pdksh をいまさら ksh に変更するのは勘弁して欲しかった...。)


パッケージは地道に調べれば何とかなる。しかし、それだけではうまくいかい。
そう、CentOS 6 の日本語フォントを入れてもインストーラが文字化けする(下図)

Oracle のインストーラは Java を使っているが、Linux の場合、X Window System を必要とする。Mac の XQuartz とか、Xming など Windows でのディスプレイサーバを使うことはできるが、XLib など Xの基本システム一式は Oracle をインストールする Linux にインストールしておく必要がある。

RHEL5互換のOSの場合、それだけで日本語インストーラががちゃんと立ち上がったのだが、RHEL6互換の CentOSでは、Xの日本語フォントをちゃんと入れても文字が豆腐になるのだ。

これは、JRE で定義されているフォントと実際のフォントがあってないとこういうことが起こっているためだ。一般的な対処は、JRE の持つ定義ファイルを書き換えることなのだが、Oracle のインストーラはJREを自前で抱えており、インストーラ起動時に JRE (正確にはJDK)を展開し起動前に差し替える手が存在しない。

色々あまり言えない手を使って調べたところ、Oracle のインストーラの抱えるJREは RHEL互換環境ではさざなみフォント(kochi-*-subst)があることを仮定している。RHEL6 系統は VLフォントとIPAフォントはあるが、さざなみフォントが入っていない。

そこで、IPAフォントをさざなみフォントに誤認させることで対処を行った。
ざっくり言うと、手順は以下の通り。


  1. ipa-gothic, ipa-mincho の RPM をインストールしておく
  2. cd /usr/share/fonts ;  mkdir -p ja/TrueType を実行し「/usr/share/fonts/ja/TrueType/」ディレクトリを作っておく
  3. cd /usr/share/fonts/ja/TrueType ; ln -s ../../ipa-gothic/ipag.ttf ./kochi-gothic-subst.ttf を実行
  4. cd /usr/share/fonts/ja/TrueType ; ln -s ../../ipa-mincho/ipam.ttf ./kochi-mincho-subst.ttf を実行
  5. runInstaller を実行して Oracle のインストールを始める
さざなみフォントは「/usr/share/fonts/ja/TrueType/kochi-{gothic, mincho}-subst.ttf」にあることになっている。なのでシンボリックリンクで IPAフォントを配置してしまう訳だ。


これによりインストーラが日本語で起動した。


なお、日本語が化けた状態のままインストールをしてもインストールは可能で、Oracle のデータベース自体は問題なく動作する。ただし、Enterprise Manager の一部のボタンが文字化けしてしまう。これは、インストール時にボタンのGIFファイルなどを動的生成しているのだが、フォントがないためボタンに書き込むべき文字がレンダリングできないためだ。

Oracle のインストールぐらいは日本語がなくても困らないが、後で人にメンテナンスさせることを考えると Enterprise Manager がちゃんと表示されないのは少々困る。

上記対処を行ってからインストールすればこの問題は発生しないが、化けたままインストールしてしまった場合は、まず上記対処で強制的にフォントを割り当ててからEnterpriseManager を停止し、キャッシュとして作成されているGIFファイルを削除してしまうといい。Enterprise Manager  を起動し直すと、その時にGIFファイルを再生成してくれる。
インストール直後にフォントが割り当てられてなかったので文字が豆腐になってしまってるが、今回の再生成時にはフォントが強制割り当てされているので文字が書き込まれ、正しいボタンができてくれる。

...なお全くの余談だが、私は Java が大嫌いだ。

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側に設定したキー配列がそのまま使われるのではないかと思われる。
混乱を防ぐためにも配列を統一しておいた方がいいだろう。