Linux on Power (ppc64le)をPCでお試し (binfmt_misc / qemu-user-static使用)

本記事ではIBM Powerサーバー上でのLinux、**Linux on Power**をお手軽にPC上で動作させたい
場合のとても簡単なお試し方法を記載します。
**Linux on Power**の評価はIBM Powerサーバー実機を用意して評価するのが一番なのですが、
実機での評価が難しい場合は、下記の方法でPCでのお試しが可能です。

* Intelサーバー上でのプログラムがIBM Power上で問題なく動くか簡単なプログラムを試したい
* IBM Powerに対応したマルチアーキテクチャー対応のプログラムを作成したい
* IBM Powerに対応したマルチアーキテクチャー対応のコンテナを作成したい

などといった用途でのお試しであればPC上での動作も可能です。

* パフォーマンスを測定したい
* PCでは動作が難しい複数CPU / 大容量メモリー / 大容量ストレージ / 高速ネットワークを使用したプログラムを動かしたい
* 複数VMを連携させたい
* IBM Powerで動作するLinux以外のOS、AIX / IBM iを試したい

といった場合は実機が必要になってしまうかと思います。。

今回はなるべくお手軽に試すためにDockerもしくはPodmanでのコンテナ環境を使用した方法となります。

# Macでお試し

Docker DesktopかPodmanを使用します。

### Docker Desktopの場合

下記からDocker Desktopを導入後、以下でコンテナを立ち上げればOKです。
https://www.docker.com/products/docker-desktop

```sh
docker run --rm -it --platform linux/ppc64le ubuntu:20.04 /bin/bash
```
上記はUbuntu 20.04のコンテナを使用する例です。
これだけで**Linux on Power**環境ができちゃいます :smiley_cat: 
試しにこのコンテナ上で`uname -m`を実行してみると

```
# uname -m
ppc64le
```
となりPowerアーキテクチャー環境になっていることがわかります。

### Podmanの場合

Docker Desktopがライセンス上使えないといった場合はPodmanも使用できます。
下記の手順でPodmanを導入後、以下でコンテナを立ち上げればOKです。
https://podman.io/getting-started/installation#macos

```
podman machine ssh sudo rpm-ostree install qemu-user-static
podman machine ssh sudo systemctl reboot
podman run --rm -it --platform linux/ppc64le ubuntu:20.04 /bin/bash
```

# Windowsでお試し

WSL2環境でDockerもしくはPodmanで使用可能です。
下記はWSL2のディストリビューションにubuntu20.04を選択した場合のDocker環境でコンテナを立ち上げる例です。

```
sudo apt update
sudo apt install qemu-user-static
docker run --rm -it --platform linux/ppc64le ubuntu:20.04 /bin/bash
```

# Linuxでお試し

Ubuntu環境であれば、上記WSL2環境と同じ手順で使用可能です。
その他の比較的新しい環境であれば、下記のqemu-user-staticのページにある手順で以下のようにコンテナで使用できるはずです。
https://github.com/multiarch/qemu-user-static

```
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker run --rm -it --platform linux/ppc64le ubuntu:20.04 /bin/bash
```

少し古いDockerの環境、例えばRHEL7/CentOS7のDocker環境だと、以下のような手順となります。

```
docker run --rm --privileged multiarch/qemu-user-static --reset
wget https://github.com/multiarch/qemu-user-static/releases/download/v6.1.0-8/x86_64_qemu-ppc64le-static.tar.gz
tar xzf x86_64_qemu-ppc64le-static.tar.gz
sudo cp qemu-ppc64le-static /usr/bin
docker run --rm -it -v /usr/bin/qemu-ppc64le-static:/usr/bin/qemu-ppc64le-static ppc64le/ubuntu:20.04 /bin/bash
```

上記のようにMac / Windows / Linuxのどの場合でも数コマンドで**Linux on Power**のコンテナ
環境を作成することが可能です。

ちなみに同様の方法でIBM Zのコンテナも動作させることができると思います。
ARMのコンテナも動作させることが同様にでき、こちらは既にQiitaで多く記事化されているようです。

# Linux on Powerのコンテナが動作する仕組み

**Linux on Power**のコンテナが動作する仕組みについても補足として記載しておきます。
Mac / Windows / Linuxのどの環境でも基本Linuxが動作しており (MacはHyperKitやQEMU+HVFのVM上 / Windows WSL2はHyper-VのVM上)、そのLinux上でbinfmt_miscおよびqemu-user-staticを使用して異なるアーキテクチャーのLinuxユーザープログラムを動かしています。

### binfmt_miscとは？
Linux kernelの機能でoffset/magic/maskとインタープリターのセットをkernelに教えておくことで特定の実行ファイルフォーマットを指定のインタープリターで動作させる仕組みです。
https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html

**Linux on Power**の動作のエントリは以下になります。

```
# cat /proc/sys/fs/binfmt_misc/qemu-ppc64le
enabled
interpreter /usr/bin/qemu-ppc64le-static
flags: 
offset 0
magic 7f454c4602010100000000000000000002001500
mask ffffffffffffff00fffffffffffffffffeffff00
```
このエントリによって、このoffset/magic/maskのバイナリの実行は/usr/bin/qemu-ppc64le-staticに実行させてね、と指定しているわけです。

### qemu-user-staticとは？

その名の通りQEMUのUser Mode Emulationのstatic link版です。
https://github.com/multiarch/qemu-user-static

* QEMUはオープンソースのマシンエミュレーター・仮想化エンジンです。
* QEMUはOS全体をエミュレーションするSystem Emulationとユーザープログラム部分のみをエミュレーションするUser Mode Emulationがあります。
* LinuxのUser Mode Emulationにはkernelはエミュレーションせずに、ユーザープログラムのみをエミュレーションし、system callやPOSIX signalをうまく変換する仕組みが入っています。kernel部分はエミュレーションしないため、kernel部分のマシン固有の機能確認はできませんが、ユーザープログラムはより高速な実行が可能となります。

前述のqemu-ppc64le-staticがQEMUのUser Mode Emulationのppc64le版となっています。

コンテナ環境ではこの2つがうまく連携して動作することにより異なるアーキテクチャーのユーザープログラムのエミュレーションを行っています。

1. コンテナ内でppc64leバイナリが呼ばれる。
1. kernelに処理が移りbinfmt_miscによりppc64leバイナリが検知されてqemu-ppc64le-static経由でppc64leが実行される。
1. qemu-ppc64le-staticによりppc64leバイナリのUser Mode Emulationがなされる。

この際kernelはMac/WindowsはVM上のものが、Linuxはnative上のものがそのまま使用されます。そのため、コンテナ上で`cat /proc/cpuinfo`などしても実際のマシンもしくはVMのCPU情報が表示されます。
また、ppc64leバイナリが呼ばれた際に使用されるqemu-ppc64le-staticはコンテナ空間のものとなりますが、Linux kernelでのbinfmt_misc設定時のbinaryを使用するfix-binaryオプションを使用することでコンテナ空間にqemu-ppc64le-staticがなくとも実行が可能となっています (kernel 4.8以降のオプションとなります)。

以上、PCにて**Linux on Power**を簡単に試す方法について紹介させていただきました。

* より多くのプラットフォームで自身のユーザープログラムを使ってもらいたい
* IBMや他のIBM Powerユーザーに自身のユーザープログラムの**Linux on Power**対応を依頼された

などありましたらぜひ試してみてはいかがでしょうか？