webOS Open Source Edition の観察(4)

webOSの本丸はどうやらWebAppMgrのようだ。

# WebAppMgr

WebAppMgrがリンクしているライブラリ。

```
# /lib/ld-linux-armhf.so.3 --list /usr/bin/WebAppMgr
	linux-vdso.so.1 (0x7eee1000)
	/lib/libSegFault.so (0x76f3f000)
	libcbe.so => /usr/lib/libcbe.so (0x70c2d000)
	libWebAppMgr.so.1 => /usr/lib/libWebAppMgr.so.1 (0x70be8000)
	libWebAppMgrCore.so.1 => /usr/lib/libWebAppMgrCore.so.1 (0x70ba9000)
	libluna-prefs.so.3 => /usr/lib/libluna-prefs.so.3 (0x70ba3000)
	libPmLogLib.so.3 => /usr/lib/libPmLogLib.so.3 (0x70b97000)
	libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0x70ad1000)
	libQt5Core.so.5 => /usr/lib/libQt5Core.so.5 (0x70726000)
	libpthread.so.0 => /lib/libpthread.so.0 (0x706fd000)
	libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x705f8000)
	libm.so.6 => /lib/libm.so.6 (0x7057a000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x70560000)
	libc.so.6 => /lib/libc.so.6 (0x70425000)
	libunwind-arm.so.8 => /usr/lib/libunwind-arm.so.8 (0x703f2000)
	libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x70397000)
	librt.so.1 => /lib/librt.so.1 (0x70380000)
	libdl.so.2 => /lib/libdl.so.2 (0x7036d000)
	libgobject-2.0.so.0 => /usr/lib/libgobject-2.0.so.0 (0x70336000)
	libfontconfig.so.1 => /usr/lib/libfontconfig.so.1 (0x70308000)
	libexpat.so.1 => /usr/lib/libexpat.so.1 (0x702ef000)
	libpangocairo-1.0.so.0 => /usr/lib/libpangocairo-1.0.so.0 (0x702e4000)
	libpango-1.0.so.0 => /usr/lib/libpango-1.0.so.0 (0x702b5000)
	libcairo.so.2 => /usr/lib/libcairo.so.2 (0x7022b000)
	libgconf-2.so.4 => /usr/lib/libgconf-2.so.4 (0x7020b000)
	libxkbcommon.so.0 => /usr/lib/libxkbcommon.so.0 (0x701db000)
	libwayland-egl.so.1 => /usr/lib/libwayland-egl.so.1 (0x701d8000)
	libwayland-client.so.0 => /usr/lib/libwayland-client.so.0 (0x701cf000)
	libwayland-webos-client.so.1 => /usr/lib/libwayland-webos-client.so.1 (0x701ca000)
	libasound.so.2 => /usr/lib/libasound.so.2 (0x70133000)
	libluna-service2.so.3 => /usr/lib/libluna-service2.so.3 (0x70100000)
	libndl-directmedia2.so.1 => /usr/lib/libndl-directmedia2.so.1 (0x700d1000)
	libdbus-1.so.3 => /usr/lib/libdbus-1.so.3 (0x7009f000)
	libumedia_api.so.1 => /usr/lib/libumedia_api.so.1 (0x7008a000)
	/lib/ld-linux-armhf.so.3 (0x54b71000)
	libcjson.so.1 => /usr/lib/libcjson.so.1 (0x70084000)
	libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0x70008000)
	libnyx.so.7 => /usr/lib/libnyx.so.7 (0x6fffb000)
	libpbnjson_c.so.2 => /usr/lib/libpbnjson_c.so.2 (0x6ffd5000)
	libpcre.so.1 => /usr/lib/libpcre.so.1 (0x6ffa0000)
	libz.so.1 => /lib/libz.so.1 (0x6ff90000)
	libicui18n.so.57 => /usr/lib/libicui18n.so.57 (0x6fe00000)
	libicuuc.so.57 => /usr/lib/libicuuc.so.57 (0x6fcee000)
	libunwind.so.8 => /usr/lib/libunwind.so.8 (0x6fcbd000)
	libffi.so.6 => /usr/lib/libffi.so.6 (0x6fcb6000)
	libpixman-1.so.0 => /usr/lib/libpixman-1.so.0 (0x6fc4f000)
	libpng16.so.16 => /usr/lib/libpng16.so.16 (0x6fc2f000)
	libpangoft2-1.0.so.0 => /usr/lib/libpangoft2-1.0.so.0 (0x6fc21000)
	libgthread-2.0.so.0 => /usr/lib/libgthread-2.0.so.0 (0x6fc1e000)
	libharfbuzz.so.0 => /usr/lib/libharfbuzz.so.0 (0x6fbc1000)
	libdbus-glib-1.so.2 => /usr/lib/libdbus-glib-1.so.2 (0x6fba9000)
	libgio-2.0.so.0 => /usr/lib/libgio-2.0.so.0 (0x6fabc000)
	libgmodule-2.0.so.0 => /usr/lib/libgmodule-2.0.so.0 (0x6fab8000)
	libsystemd.so.0 => /lib/libsystemd.so.0 (0x6fa5f000)
	libcap.so.2 => /lib/libcap.so.2 (0x6fa5a000)
	libresolv.so.2 => /lib/libresolv.so.2 (0x6fa36000)
	liblzma.so.5 => /usr/lib/liblzma.so.5 (0x6fa1b000)
	libopenmaxil.so => /usr/lib/libopenmaxil.so (0x6fa15000)
	libpbnjson_cpp.so.2 => /usr/lib/libpbnjson_cpp.so.2 (0x6fa07000)
	libmedia-resource-calculator.so.1 => /usr/lib/libmedia-resource-calculator.so.1 (0x6f9fc000)
	libavcodec.so.55 => /usr/lib/libavcodec.so.55 (0x6ed66000)
	libavutil.so.52 => /usr/lib/libavutil.so.52 (0x6ed1d000)
	libswresample.so.0 => /usr/lib/libswresample.so.0 (0x6ed0e000)
	libmdc_client.so.1 => /usr/lib/libmdc_client.so.1 (0x6ed04000)
	libmdc_content_provider.so.1 => /usr/lib/libmdc_content_provider.so.1 (0x6ecfa000)
	libresource_mgr_client.so.1 => /usr/lib/libresource_mgr_client.so.1 (0x6ece9000)
	libbcm_host.so => /usr/lib/libbcm_host.so (0x6ecd9000)
	libomxcomponents.so.1 => /usr/lib/libomxcomponents.so.1 (0x6ecce000)
	libums_connector.so.1 => /usr/lib/libums_connector.so.1 (0x6ecc4000)
	libyajl.so.2 => /usr/lib/libyajl.so.2 (0x6ecbd000)
	liburiparser.so.1 => /usr/lib/liburiparser.so.1 (0x6ecad000)
	libgmp.so.10 => /usr/lib/libgmp.so.10 (0x6ec67000)
	libicudata.so.57 => /usr/lib/libicudata.so.57 (0x6d3e9000)
	libvchiq_arm.so => /usr/lib/libvchiq_arm.so (0x6d3e1000)
	libvcos.so => /usr/lib/libvcos.so (0x6d3d8000)
	libdrm.so.2 => /usr/lib/libdrm.so.2 (0x6d3cd000)
	libums_connector_impl.so.1 => /usr/lib/libums_connector_impl.so.1 (0x6d3b8000)
```

ps で見ると複数のWebAppMgrが動いている。

```
# ps ax |grep [W]ebAppMgr
  737 ?        SLsl   0:03 /usr/bin/WebAppMgr --application-cache-domain-limit=10485760 --application-cache-size=52428800 --browser-subprocess-path=/usr/bin/WebAppMgr --disable-direct-npapi-requests --disable-extensions --disable-gpu-rasterization --disable-low-res-tiling --disk-cache-size=52428800 --enable-aggressive-release-policy --enable-accelerated-plugin-rendering --accelerated-plugin-rendering-blacklist=device;drmAgent;sound;service --enable-key-event-throttling --enable-threaded-compositing --enable-watchdog --hide-selection-handles --ignore-gpu-blacklist --ignore-netif=p2p --in-process-gpu --max-unused-resource-memory-usage-percentage=0 --network-stable-timeout=3 --noerrdialogs --num-raster-threads=2 --ozone-platform=wayland --remote-debugging-port=9998 --resource-buffer-max-allocation-size=262144 --resource-buffer-size=1048576 --touch-events=disabled --ui-disable-opaque-shader-program --user-data-dir=/var/lib/wam --enable-devtools-experiments --webos-wam --skia-font-cache-size-mb=8 --skia-image-cache-size-mb=80 --skia-background-font-cache-size-kb=512 --gpu-program-cache-size-kb=6144 --watchdog-render-timeout=200 --enable-local-resource-code-cache --disallow-code-cache-from-file-uris-with-query-string --js-flags \
  770 ?        S      0:00 /usr/bin/WebAppMgr --type=zygote --no-sandbox --no-sandbox --webos-wam
  791 ?        Sl     0:00 /usr/bin/WebAppMgr --type=renderer --disable-direct-npapi-requests --disable-low-res-tiling --disallow-code-cache-from-file-uris-with-query-string --enable-aggressive-release-policy --enable-local-resource-code-cache --enable-threaded-compositing --js-flags --no-sandbox --touch-events=disabled --ozone-platform=wayland --network-stable-timeout=3 --webos-wam --enable-watchdog --watchdog-render-timeout=200 --skia-image-cache-size-mb=80 --skia-font-cache-size-mb=8 --skia-background-font-cache-size-kb=512 --primordial-pipe-token=D63B0C7165AE1596A434D9E3EA60C518 --lang --no-sandbox --webos-wam --enable-pinch --num-raster-threads=2 --content-image-texture-target=3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553 --video-image-texture-target=3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553,3553 --mojo-channel-token=5D89B229E5B548C1639C9DA073575C82 --mojo-application-channel-token=D63B0C7165AE1596A434D9E3EA60C518 --channel=737.2.1095503763 --v8-natives-passed-by-fd --v8-snapshot-passed-by-fd
```

# zygote

3つ動いていたWebAppMgrのプロセスのうちのひとつに `--type=zygote` というオプションがついている。zygote といえばAndroidで使われていたテクニックで、起動を高速化するたけに、初期化処理を済ませたプロセスからforkしていくというもの。同じような技がつかわれているのだろうか？

"zygote" で検索したら、7年前に書いた自分の記事を発見。
http://blog.kmckk.com/archives/3551546.html

ソースコード中のzygoteをさがす。webOS全体は一気にgrepをかけるのは大きすぎるので、なかなかさがすのに苦労した。

WebAppMgr の実行ファイルは `build-webos/BUILD/work/raspberrypi3-webos-linux-gnueabi/wam` 以下のディレクトリでビルドされるが、ここには"zygote"の文字列は含まれていなかった。どれかのライブラリの中のようだ。

rootfsのバイナリに対してgrep をかける

```
$ cd build-webos/BUILD/work/raspberrypi3-webos-linux-gnueabi/webos-image/1.0-r3/rootfs
$ grep -r zygote *
etc/init/WebAppMgr.conf:        --in-process-zygote \ "
etc/systemd/system/scripts/webapp-mgr.sh:    --in-process-zygote \ "
Binary file usr/lib/libcbe.so matches
```

libcbe.so がヒットした。

```
$ cd build-webos/BUILD/work/raspberrypi3-webos-linux-gnueabi
$ ls */*/image/usr/lib/ > /tmp/t
$ less /tmp/t
```

これでようやく`chromium53/53.0.2785.34-1-r12.10/image/usr/lib/libcbe.so`だとわかった。chromium とは。

```
$ cd chromium53/53.0.2785.34-1-r12.10/git
$ git grep zygote
```

`src/docs/linux_zygote.md` というドキュメントを発見。

https://github.com/webosose/chromium53/blob/master/src/docs/linux_zygote.md

```
A zygote process is one that listens for spawn requests from a master process
and forks itself in response. Generally they are used because forking a process
after some expensive setup has been performed can save time and share extra
memory pages.

  ...

The zygote process is triggered by the `--type=zygote` command line flag, which
causes `ZygoteMain` (in `chrome/browser/zygote_main_linux.cc`) to be run. The
zygote is launched from `chrome/browser/zygote_host_linux.cc`.
```

おお。まさにzygote。
しかし、ドキュメントをよく読んでみると、zygoteは起動高速化としての効果はそれほどではなくて、browserとrendererのバージョンのミスマッチを防ぐためにこうしているらしい。
なるほど、AndroidのときにはJavaのクラスロードがあったからzygote方式が有利だったけど、Javaでなければそれほどでもないのか。