遅ればせならDockerを試してみた

先日のLinuxCon Japanでも話題になっていたDockerを遅ればせなら試してみた。
拍子抜けするほど簡単だった。誰かが用意してくれたものを使うだけなら。

Ubuntu 14.04 でのDockerのインストール

$ sudo apt-get install docker.io

これだけ。

busyboxの小さなルートファイルシステムを動かす

$ sudo docker.io run -i -t busybox /bin/sh

これだけで、自動でbusyboxのルートファイルシステムをダウンロードしてきて起動してくれる。
しばらく待っているとダウンロードが完了して/bin/shのプロンプトが出た。

/ # ls -l /bin/sh
lrwxrwxrwx    1 root     root             7 May 22 23:22 /bin/sh -> busybox
/ #

確かにbusyboxのルートファイルシステムが動いている。
同様にubuntuのルートファイルシステムを動かすには以下のようにすればよい。

$ sudo docker.io run -i -t ubuntu /bin/bash

簡単すぎた。これは楽だ。なるほどみんなが騒ぐわけだ。

Qemuを使ってARMのルートファイルシステムをDockerで動かす

Debian armhfなDocker imageを作ってみた - kotakのひまじめ日記
このページの通りにやったらできた。

dockerをsudo無しで使う

ユーザーがdockerのgroup権限があればsudoが不要になる。
ユーザー(koba)をdockerのgroupに入れるには

$ sudo addgroup koba docker

次にログインしたときに有効になる。

補足

Debian/Ubuntu ではすでにdockerという別のコマンドがあるため、パッケージ名とコマンド名がdocker.ioに変更されている。これをdockerの名前で使えるようにするための方法は以下に書いてある。
本家サイトのUbuntuのインストール方法

Dockerは何がうれしいのかがよくわかる記事。
Docker: Linuxコンテナを使ってアプリケーションの配置を支援する

Dockerの中が少しわかる記事。
Dockerが利用しているAUFSとLXC - $shibayu36->blog;

DockerはGo言語で書かれていてそのソースはgithubで公開されている。
https://github.com/dotcloud/docker
dockerのコマンドの頭のソースはdocker/docker.go

LLVMLinuxをビルドしてみた

LLVMLinuxLinux kernelをClang/LLVMでビルドできるようにしようというプロジェクトです。先日のELCでも紹介されていました。興味があったので、まずはビルドしてみました。

基本的には以下のページの手順に従ってやっただけ。
Useful links | ClangBuiltLinux

最初はUbuntu 12.04でやりましたが、以下のエラーがでました。

CMake Error at cmake/modules/HandleLLVMOptions.cmake:13 (message):
  Host GCC version must be at least 4.7!

gccは4.7以上が必要ということで、gccだけ追加しても他にも引っかかりそうに思ったのでUbuntu 14.04でやり直しました。

ソースの入手と準備

$ git clone http://git.linuxfoundation.org/llvmlinux.git
$ cd llvmlinux/
$ sudo apt-get install build-essential cmake git git-svn \
 kpartx libglib2.0-dev patch quilt \
 rsync subversion zlib1g-dev flex libfdt1 libfdt-dev \
 libpixman-1-0 libpixman-1-dev 
$ sudo apt-get install libc6:i386 libncurses5:i386
$ sudo apt-get install linaro-image-tools

ビルド

$ cd targets/vexpress
$ nohup make &
$ tail -f nohup.out 

これで、llvm, clang, kernel, qemuなど全てソースコードリポジトリからとってきて必要なパッチをあててビルドするところまで全自動でやってくれました。ログの最後に"# # # SUCCESS # # #"と出ているのでうまくいったのでしょう。

$ tail nohup.out 
input: ImExPS/2 Generic Explorer Mouse as /devices/mb:kmi1/serio1/input/input2

This root FS contains most basic linux utilities (implemented with busybox)
and the Lynx web browser.

Kernel config is available through /proc/config.gz

Log in as root with no password.
qemu login: Killed
# # # SUCCESS # # #
$

ビルドしたディレクトリを/home/koba/llvmlinux とすると、以下のコマンドでClang/LLVMでビルドしたkernelをqemuで起動できます。

$ QEMU_AUDIO_DRV=none  /home/koba/llvmlinux/test/qemu/install/bin/qemu-system-arm -M vexpress-a9 \
 -kernel /home/koba/llvmlinux/targets/vexpress/tmp/kernel_dtb.img -m 256 \
 -append "mem=256M root=/dev/ram0 console=ttyAMA0 rw" \
 -initrd /home/koba/llvmlinux/targets/vexpress/tmp/initramfs.img -net none  -nographic -no-reboot

rootでログインして uname -a してみた結果。

 ~ # uname -a
Linux qemu 3.15.0-rc7-llvmlinux-Lr209792-Cr209794+ #1 SMP Thu May 29 22:14:44 JST 2014 armv7l GNU/Linux
 ~ # 

とりあえずはここまで。

「ARM 64bitがやってきた!」を発表してきました

"ARM 64bit has come!" というスライドを作ってテクニカルジャンボリーカーネル/VM探検隊で発表してきました。ARMv8のaarch64に関する話です。

テクニカルジャンボリーでのビデオ

デモしたときのフォントが小さすぎて見えませんね。f(^^;;
qemugdbの起動コマンドはスライドの通りです。
命令単位のステップ実行は、si または ni です。
ステップ実行のたびに自動的にPCのアドレスを逆アセンブル表示するのは、display/i $pc です。
レジスタのダンプは i r です。(info register)

カーネル/VM探検隊

(撮影:@hasegaw さん)

カーネル/VM探検隊でのビデオ

(Coming soon)

ウケを狙って直前でネタスライドを追加したのですが、そうしたら後半のスライドが壊れていました。すみません。すみません。orz
slideshareにアップしたスライドは壊れる前のものなのでそっちを見てください。

LinuxCon Japan 2014に参加しました

2014年5月20-22日にホテル椿山荘で開催されたLinuxCon Japan 2014に参加しました。

LinuxCon Japan 2014 day 1 #linuxcon - Togetter
LinuxCon Japan 2014 day 2 #linuxcon - Togetter
LinuxCon Japan 2014 day 3 #linuxcon - Togetter

今年はTizenやYoctoのトラックがなかったので組み込みLinux系のセッションは少なめでした。私はカーネルのトレースやトラブルシューティング関連のセッションをなるべく聴くようにしました。よくわかりませんがクラウドの分野では今年はDockerなどコンテナ系の技術がにぎわっていたようです。

面白いと思ったセッション

Improvements on Kdump Scalability Issues for Terabyte-Scale Memory System slide

メモリが12TB載っているサーバーだとクラッシュしてkdumpでメモリをダンプするだけで35時間もかかってしまう。(!!)
これを1時間にまで短縮したいという話。

Tracing the kernel, advance usage of ftrace slide

ftraceの使い方の最新情報。

Scalability Effort for Kprobes slide

Kprobesのテストの話から始まって、そのために全ての関数を一度にトレースすることに。
そして、それでも使い物になるように高速化した話。
カーネル/VM探検隊ではこれを日本語でやっていただけたので理解が深まりました。

How to obtain information for troubleshooting enterprise servers slide

盛りだくさんの内容。systemtapTomoyo Linuxを使ってシステムの動作状況のさまざまな情報を得る方法。

これを聴いていたなかで、

このツイートが意外にたくさんリツイートされたのですが、自分でもあまりよくわかっていなかったので、レセプションのときに発表者の半田さんに確認しました。
Systemtapはいろいろな安全装置があるため、なにかあるとその安全装置が働いて止まってしまう。そのため年単位で連続稼動させようとしてもそれで止まってしまうだろうとのことでした。

AndroidのARTでは実行中にプロファイリングを行ってそれに基づいて再コンパイルするようだ

DalvikVMのJIT vs ARTのAOT

AndroidのDalvikVMではDEXコードをインタプリタで実行しつつ、プロファイリングを行っていて実行頻度の高い部分をJITコンパイルします。コンパイルはメソッドよりも小さな単位で行われ、コンパイルにかかる時間もメモリも小さいのが特徴です。ただし、全体を見渡すような最適化を行うことはできません。コンパイルした結果は保存しません。本当に必要な部分しかコンパイルしないので、コードサイズの増大は最小限です。
それに対して、新しく登場したARTではDEXコードを実行する前にあらかじめコンパイルします。(=AOT: Ahead Of Time compile) コンパイルはインストール時などに行われます。コンパイルには多少時間がかかりメモリも消費しますが、JITに比べて最適化されたコードを生成することができます。コンパイルした結果は保存されるので、毎回のコンパイルは不要です。

AOTの欠点

しかし実行前にコンパイルするということは、実行中に初めてわかる情報、つまりどの部分がより多く実行されるか、ということがわからないままでコンパイルするので、基本的にどの部分も同じような重要度とみなしてコンパイルするしかありません。DEXコードをコンパイルすると元のサイズの10倍以上に大きくなります。そしてサイズよりも速度を優先するように最適化をかけるとさらに数倍のサイズに膨らみます。コードを配置するRAMのサイズは以前よりは大きくはなっていますが、すべてのDEXコードを速度優先でコンパイルするのはさすがにコードサイズの面で厳しいと思います。コードサイズが大きくなりすぎるとキャッシュの効きも悪くなります。

ARTはAOTだけではない!

AOSPのソースをビルドして動かしていたら興味深いログを見つけました。
(横スクロールして見てください。)

I/art     (  636): DexFile_isDexOptNeeded size of new profile file /data/dalvik-cache/profiles/com.android.launcher is significantly different from old profile file /data/dalvik-cache/profile-cache/com.android.launcher (top 90% samples changed in proportion of 18.75%)
I/PackageManager(  636): Running dexopt on: com.android.launcher
I/dex2oat ( 1047): dex2oat: /system/bin/dex2oat --zip-fd=6 --zip-location=/system/priv-app/Launcher2.apk --oat-fd=7 --oat-location=/data/dalvik-cache/system@priv-app@Launcher2.apk@classes.dex --profile-file=/data/dalvik-cache/profiles/com.android.launcher
 ...
I/dex2oat ( 1047): compiling method android.view.View com.android.launcher2.PagedView.getPageAt(int) because its usage is part of top 3.08642% with a percent of 0.205761%
I/dex2oat ( 1047): compiling method void com.android.launcher2.AppsCustomizeTabHost.onFinishInflate() because its usage is part of top 0.617284% with a percent of 0.617284%
I/dex2oat ( 1047): compiling method void com.android.launcher2.CellLayout.(android.content.Context, android.util.AttributeSet, int) because its usage is part of top 2.88066% with a percent of 0.411523%
I/dex2oat ( 1047): compiling method void com.android.launcher2.CellLayout.onDraw(android.graphics.Canvas) because its usage is part of top 3.08642% with a percent of 0.205761%
 ...
I/dex2oat ( 1047): compiling method void com.android.launcher2.Workspace.addInScreen(android.view.View, long, int, int, int, int, int, boolean) because its usage is part of top 3.08642% with a percent of 0.205761%
I/dex2oat ( 1047): dex2oat took 3.496627214s (threads: 1)
I/art     ( 1019): Starting profile with period 10s, duration 30s, interval 10000us.  Profile file /data/dalvik-cache/profiles/com.android.launcher

このログを見ると、実行中に別スレッドでプロファイルを行っていて、そのプロファイル結果で実行頻度の上位のメソッドは再度コンパイルを行っているようです。おそらく最初はサイズ優先の最適化で全体をコンパイルしておいて、実行頻度の高いものを再度コンパイルするときには速度優先の最適化でコンパイルするのでしょう。

"compiling method AAA because its usage is part of top xx% with a percent of yy%" というメッセージをだしているのは
art/compiler/driver/compiler_driver.cc の CompilerDriver::SkipCompilation(const std::string& method_name)

"Starting profile with period 10s, duration 30s, interval 10000us. "のメッセージをだしているのは
art/runtime/profiler.cc の BackgroundMethodSamplingProfiler::Start(int period, int duration, ... )

興味のある方はコードを追いかけてみてください。

プロファイラは現在はデフォルトでは無効になっている

なお、AOSPのリポジトリは日々更新されているので、現在のものではデフォルトではこのプロファイリングが無効になっています。有効にするには以下のようにプロパティをセットします。
"setprop dalvik.vm.profiler 1"

偶然に私が動かしたときには、デフォルトでプロファイラが有効になっていたようです。ただしそのときは過剰にコンパイルしていたようで、エミュレータの動作は明らかに遅くなっていました。
バックグランドでコンパイルするのはマルチプロセッサ向きです。Androidエミュレータで使用しているqemuではマルチプロセッサを効率よくエミュレートすることができません。そのこともあってプロファイラはデフォルトで無効に変更されたのかもしれません。いずれにしてもまだ未完成なので期待して待ちたいと思います。

Andoridの次の正式リリースでは、64bit化とARTが目玉になると思います。どのように仕上げてくるか楽しみです。

Android AOSPの64bit化の現在の状況

2014/05/03(#yapf)横浜Android and モバイルOSプラットフォーム部第35回勉強会での@hidenorly さんの発表Investigation report on 64 bit support in Android Open Source Projectに触発されて、現在(2014/5/10)のAOSPでarm64とx86_64でビルドしてみました。

arm64

$ . build/envsetup.sh 
$ lunch

You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng
     7. vbox_x86-eng
     8. aosp_manta-userdebug
     9. mini_x86-userdebug
     10. mini_mips-userdebug
     11. mini_armv7a_neon-userdebug
     12. aosp_mako-userdebug
     13. aosp_hammerhead-userdebug
     14. aosp_tilapia-userdebug
     15. aosp_deb-userdebug
     16. aosp_flo-userdebug
     17. aosp_grouper-userdebug

Which would you like? [aosp_arm-eng] 2

lunchコマンドでいつものaosp_arm-engでなく、aosp_arm64-eng を選んでビルドしました。

$ nohup make -j4 &

ビルドは完了しましたが、arm64用のemulatorはまだ無いので実行することはできません。
できたファイルを観察してみます。

$ cd out/target/product/generic_arm64
$ file root/init
root/init: ELF 64-bit LSB executable, version 1 (SYSV), statically linked, stripped

カーネルから一番最初に起動されるプロセスであるinitは64bit ELFでした。
system/lib と system/lib64 があります。前者は32bitのダイナミックリンクライブラリ、後者が64bit用です。
ダイナミックリンクライブラリは32bitと64bitで混ぜて使うことはできません。32bitのプロセスでは32bitのライブラリのみ使用可能で、64bitのプロセスは64bitのライブラリのみです。そのため同じライブラリが32bitと64bitの二通りで用意されています。

DalvikVMの本体である libdvm.so がありません。ARTの本体のlibart.so は32bit/64bit両方あります。
やはり64bitでのAndroidの本命はDalvikでなくARTのようです。これらの実行環境を開発して品質を上げていくには相当のエンジニアリングリソースが必要になるので、両方に分散させるのでなくひとつに集中させるのは理にかなっていると思います。

system/bin のコマンドはほとんどが64bitになっています。
Zygoteの元となるapp_processのコマンドが2通りあります。無印のほうが32bitです。

$ file system/bin/app_process*
system/bin/app_process:   ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
system/bin/app_process64: ELF 64-bit LSB shared object, version 1 (SYSV), dynamically linked (uses shared libs), stripped

おや?ARTのコンパイラであるlibart-compiler.so が32bitのものしかありません。そして、framework.jarなどのシステムライブラリをARTであらかじめコンパイルした system/framework/boot.oat も32bitのものしかありません。
そうすると現時点のAOSPではJavaを含むプログラムは32bit版しか動かすことができないですね。
system/priv-apps にプリインストールされるアプリがARTでコンパイル済みのものが置かれていますが、全て32bitでした。
そういえば、@hidenorly さんの発表の中でrenderscriptもまだ32bitに固定されていると言っていました。

つまり、今のところはarm64向けのLLVMバックエンドはまだ固まっていないようです。

x86_64

次に、lunchコマンドでaosp_x86_64-eng を選んでビルドしてみます。
こちらはemulatorがあるので、ビルドできたら動かすことができます。しかしずっとブートアニメーションのままで起動しません。
logcatのログでは

F/art     (  946): art/runtime/gc/space/image_space.cc:156] Failed to load image '/system/framework/boot.art': Failed to open oat file '/system/framework/boot.oat' referenced from image /system/framework/boot.art: Expected ISA X86_64 but found X86
F/art     (  946): art/runtime/runtime.cc:257] Runtime aborting...
F/art     (  946): art/runtime/runtime.cc:257] (Aborting thread was not attached to runtime!)
F/art     (  946): art/runtime/runtime.cc:257] Dumping all threads without appropriate locks held: thread list lock mutator lock
F/art     (  946): art/runtime/runtime.cc:257] All threads:
F/art     (  946): art/runtime/runtime.cc:257] DALVIK THREADS (0):
F/art     (  946): art/runtime/runtime.cc:257] 
F/libc    (  946): Fatal signal 6 (SIGABRT), code -6 in tid 946 (zygote64)

zygote64が起動に失敗しています。/system/framework/boot.oat がX86_64用のはずがx86用のためのようです。
さきほどarm64のほうで思ったことがそのまんま実際に起こっていました。

/default.prop でro.zygote=zygote32_64 のところを ro.zygote=zygote32 に変更して、zygote64を使用しないようにしたら起動して最初のランチャーメニューの画面まで表示されるようになりました。
/はread onlyでmountされているため、いかのパッチをあててルートファイルシステムを再度作成しました。
build/target/product/core_64_bit.mk

 --- core_64_bit.mk.org	2014-05-08 17:02:56.192121328 +0900
 +++ core_64_bit.mk	2014-05-08 17:03:57.339841240 +0900
 @@ -27,7 +27,8 @@
  
  # Set the zygote property to select the 32-bit primary, 64-bit secondary script
  # This line must be parsed before the one in core_minimal.mk
 -PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32_64
 +#PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32_64
 +PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.zygote=zygote32
  
  # Temporary hack to prefer launching processes as 32 bit
  # instead of 64 bit.

このx86_64のemulatorではkernelのバージョンは3.10でした。arm版は3.4だったので、LTSのカーネルを使っていることがわかります。

まとめ

AOSPは開発途上なので、日に日に更新されていくとは思いますが、現段階では64bit向けのARTのコンパイラが(arm64, x86_64ともに)まだできていません。

現状のARTのコンパイラのバックエンドは quick と名前がつけられている独自のものですが、LLVMベースのものも準備されていて、いずれはそれが使われるようになると思います。
ARM 64bit のLLVMバックエンドに関しては先日の以下の記事が関連しています。
ARM 64bit でLLVMは見逃せない - 組み込みの人。

Computer History Museumでは一番最初に日本のソロバンがでてきたぞ

シリコンバレーに行ったときには見に行くといいよと複数の人から薦められていた "Computer History Museum" に行ってきました。
Welcome | Computer History Museum
場所はMountain View。Caltrain/路面電車の駅から3kmくらいのところ。駅でタクシーを捕まえるとよいでしょう。重い荷物がなければ歩いてもいけます。

料金は大人$15。そのチケットは当日有効で、一度外に出て再入場OKです。荷物はクロークで預かってもらえます。むしろ、バックパックを含む大きなカバンを持ったまま展示室に入るのは禁止なので、預けなければなりません。
展示室はフラッシュをたかなければ撮影OKです。
無料WiFiが使えます。隣のイタリアンレストランは美味しかったです。

一番最初に日本のソロバンがでてきたぞ

ソロバンはデジタル計算機だからな。
映像でソロバンの数字の置き方と足し算のしかたを説明していました。


上は伝統的なソロバンで、下はシャープ製の電卓付ソロバン。

有名なパーソナルコンピュータ

おっさんなら誰でも知ってるApple IIと初代IBM PC


有名なスーパーコンピュータ

角度が悪くてわかりにくいですが、「世界一高価なソファ」と言われたCray-1。


Androidの聖地

Computer History Museumから歩いていける距離にあの有名なAndroidのマスコットが置いてあるGoogleのオフィスがあります。