Home About Contact
Emacs , Wnn , QEMU

Wnn8 jserver を QEMU を使って Silicon Mac で動かす

Macbook Air M2 をブログ専用マシンにできないか考え始めた。 emacs と Wnn8 がないと日本語が書けない体質なので、 それを macOS で実現する方法を調査しました。 その覚え書きです。

Wnn8 は(試してはいないが)Arm 系CPUでは動かないので、 Silicon Mac ではそのまま動かせない。 しかし、QEMU を使えば普通に x86_64 の仮想マシンをつくることができるのでそれを使う。 colima や lima なども使うことを検討したが、まずはシンプルに QEMU をそのまま使うことにした。

なお、colima の docker コンテナで動かすことも軽く試したが colima の docker で動かした Ubuntu では Systemd が動かせなかったのであきらめた。 きっと方法はあるのだろうけれども。

QEMU の x86_64 は作動が遅いらしいけれど、Wnn8 サーバーを動かす目的には全く支障がない。

QEMU で Ubuntu 24.04 server を作動させる

こちらの記事を参考にしました。

QEMU を入れる:

brew install qemu

ubuntu 24.04 server をインストールする disk image を作成:

qemu-img create -f qcow2 my-ubuntu.img 16G

ubuntu-24.04-live-server-amd64.iso をカレントディレクトリにダウンロードしておきます。 そして普通に ubuntu インストールを開始:

qemu-system-x86_64 -accel tcg -boot menu=on -cdrom ubuntu-24.04-live-server-amd64.iso -m 2G my-ubuntu.img

8GB / 256GB のヨワヨワ macbook air なのでメモリは 2GB を指定...

Ubuntu のインストールは普通にベアメタルなマシンに入れるのと変わりません。 ローカルマックから通信できればよいだけなので、 ネットワークの設定は DHCP を選択(デフォルトのままで何も変更していない)。 sshd を入れるか質問されるのでチェックして入れた。

今回は Wnn8 の jserver を入れるだけなので必須でもないけれど、あった方がよい。

インストールが終わったら、再度起動する。

qemu-system-x86_64 -accel tcg -m 2G -nic user,hostfwd=tcp::20022-:22 my-ubuntu.img

この user,hostfwd=tcp::20022-:22 の部分でホストOSの ポート 20022 をゲストOSの ポート 22 に結びつけている(らしい)。

ローカルマックから ssh でアクセスできる:

ssh foo@localhost -p 20022

foo は設定した ubuntu のユーザー名を指定。

ssh でログインしたあとは普通の Ubuntu です。これは便利ですね。

もう colima よりこっちのがよくないか? 今回は入れていないが、Ubuntu のインストーラーで普通に Docker も入るし。

Wnn8 サーバー関連を入れる

この辺と同じです、省略。

ただし、 本来は Wnn8 のインストーラーでそれをインストールすると jserver が起動するのですが、 次のようなエラーが出て起動しません。

Unpacking dpkey8 (1.01-3) ...
Setting up dpkey8 (1.01-3) ...
Created symlink /etc/systemd/system/multi-user.target.wants/dpkey8.service → /usr/lib/systemd/system/dpkey8.service.
/usr/sbin/policy-rc.d returned 101, not running 'start dpkey8.service'

AI に解決策を聞いたところ、 /usr/sbin/policy-rc.d が 101 を返すのが原因で代わりに 0 を返すようにすればよい、とのこと。

/usr/sbin/policy-rc.d を次のように修正しました。

#!/bin/sh
exit 0
## see invoke-rc.d for exit codes. 101 is "do not run"
#while true; do
#   case "$1" in
#      -*) shift;;
#      makedev|x11-common) exit 0;;
#      *) exit 101;;
#   esac
#done

これで再起動したところ、jserver が起動できるようになりました。

ホスト側の macOS の emacs から jserver を使う

jserver は(変更していなければ)ポート 22273 で起動します。 したがって QEMU でこの仮想サーバーを起動するときにそのポートを転送設定します。

qemu-system-x86_64 \
  -nographic \
  -accel tcg \
  -m 1G \
  -nic user,hostfwd=tcp::22273-:22273,hostfwd=tcp::20022-:22 \
  my-ubuntu.img

20022 と 22 だけでなく 22273 と 22273 も ポートフォワードの設定をします。

macOS 起動時にこの仮想サーバも起動するようにする

LaunchDaemons に登録すればよい。だいたい AI にきいて解決しました。

まず qemu-system-x86_64 コマンドを使って 仮想サーバ Ubuntu を起動する起動スクリプトを /usr/local/bin/start-qemu.sh に用意:

/opt/homebrew/bin/qemu-system-x86_64 \
  -nographic \
  -accel tcg \
  -m 2G \
  -nic user,hostfwd=tcp::22273-:22273,hostfwd=tcp::20022-:22 \
  /somewhere/path/to/my-ubuntu.img

qemu-system-x86_64 はフルパス指定する必要があります。 フルパスは which qemu-system-x86_64 して確認してください。

そして /somewhere/path/to/my-ubuntu.img もフルパスで指定します。 配置場所は起動時にアクセスできる場所であればどこでもよいのですが、 macOS 的に適当な場所がわかりません。

ここでは(あまり常識的ではないのですが) /usr/local/bin/my-ubuntu.img に配置することにします。

なお安定稼働したら hostfwd=tcp::20022-:22 は削除してもよい。

そして実行権を付与しておく:

sudo chmod +x /usr/local/bin/start-qemu.sh

また my-ubuntu.img のオーナー・グループも変更:

sudo chown root:wheel /usr/local/bin/my-ubuntu.img

こんな設定になった:

/usr/local/bin $ ls -l -h
total 11043464
-rwxr-xr-x  1 root  wheel   155B May 21 07:55 start-qemu.sh
-rw-r--r--  1 root  wheel   5.3G May 21 07:58 my-ubuntu.img

次に LaunchDaemons 用ファイルを作成:

/Library/LaunchDaemons/com.mindboardapps.qemu.plist

<plist version="1.0">
  <dict>
    <key>Label</key>
      <string>com.mindboardapps.qemu</string>
    <key>ProgramArguments</key>
      <array>
        <string>/usr/local/bin/start-qemu.sh</string>
      </array>
    <key>RunAtLoad</key>
      <true/>
    <key>KeepAlive</key>
      <true/>
  </dict>
</plist>

Label はここでは com.mindboardapps.qemu にしましたが、適当にシステム上でかぶらない名前をつければよい。

そして権限とオーナー・グループ設定:

sudo chmod 644 /Library/LaunchDaemons/com.mindboardapps.qemu.plist 
sudo chown root:wheel /Library/LaunchDaemons/com.mindboardapps.qemu.plist

最後に登録する:

sudo launchctl load /Library/LaunchDaemons/com.mindboardapps.qemu.plist 

登録を解除するには:

sudo launchctl unload /Library/LaunchDaemons/com.mindboardapps.qemu.plist

あとは macOS を再起動して意図通り作動するか確認しましょう。

emacs からこの jserver を使う

ここまでできていれば、ローカルマシンで jserver が動いているのと実質同じ状態になるので、 普通に この辺でも書いている emacs + wnn7egg の設定をすれば OK です。

まとめ

LaunchDaemon 難しそうで敬遠していたが意外に簡単だった。

こんなに手軽ならば、 SpringBoot でつくったサーバーアプリをこの方法で常駐させるのも朝飯前だな。

そしてバッテリーライフが長いこの macbook M2 Air がモバイルでのライティングマシンになった。(たぶん) それから、常時 QEMU で仮想サーバーを起動すると、バッテリー消費にどれくらい悪影響があるかはまだわかっていない。