That's Done!

thatsdone's (mostly technical) memorandum

[ja] libvirt notes


話の発端と何が書いてあるか

Generic qemu qemu notesでvirtio-canの話を書きましたが、qemu-system-ARCHを直叩きするのではなく、libvirtを使い、かつあまり一般的ではないdeviceを使いたいという話です。

/usr/bin 以下のシステム標準品を入れ替えてしまってもよいのですが、切り替えて使えるようにしたい場合、 またlibvirt標準でサポートされていないdeviceを使いたい場合、 VM(というかlibvirt用語ではdomain)を定義するにはどうするか?

2通りのやりかた

ざっくり、以下の2通りのやりかたがあります。

  1. 標準品libvirtでdomain定義した後、virsh edit や virt-xml で書き換える
  2. virt-installのオプションでがんばる

1.はちょっとうざいので2.の方法を模索していました。なんとか最低限やりたいことはできたのでまとめておきます。

emulatorの変更

上記の記事に書いたように、qemuのmainlineにマージされていないデバイスを使いたいことがあります。 この場合、システム標準の qemu-system-aarch64 や qemu-system-x86_64 とは違うバイナリを使うことになります。

AIサーチだと、virt-install に --emulator というオプションがあるよと出てきたのですが、 手元の virt-install だと使えなかったので(or ハルシネーション?)、もう少し調べたところ virt-install の --boot オプションに emulator=XXXX と書けることがわかり、フルパスで指定しました。

なお、libvirtdのサーチパスを変更する…といった手法でもイケるようです。

標準的ではないdeviceを使う

qemuレベルだと、CAN device自体については公式にマニュアルがあるように、qemu側の仮想deviceについては -object で定義した上で、対応するqemu側のdriverを指定すればよいです。

qemu mainlineに入っている KVASER というCANのデバイスを、ホスト側のcan0に接続するには、qemu-system0-XXXに以下のように指定すればよいことがわかります。

-object can-bus,id=canbus0
-device kvaser_pci,canbus=canbus0
-object can-host-socketcan,id=canhost0,if=can0,canbus=canbus0

これをlibvirtのdomain定義するのは現状無理な模様です。

ではどうするか?なのですが、libvirtのdomain定義に qemu-system-XXX の command line パラメータを 指定することができるので、これを使いました。

virt-install の場合は --qemu-commandline というパラメータに渡します。

PCI IDが衝突することがある

当初、virt-install に以下のようなオプションを付けて試行したのですが、virt-instaellはPCI bridgeをたくさん接続してくれる関係で、IDぶつかってエラーになってしまいました。

--qemu-commandline="-object can-bus,id=canbus2 -device virtio-can-pci,canbus=canbus2 -object can-host-socketcan,id=canhost2,if=vcan2,canbus=canbus2"

じゃあどうするか?なのですが、virtio-can-pci の場合は addr というパラメータがあり、PCIの function IDを指定できることがわかり、lspciの結果とてらしあわせて空きIDを指定することで回避できました。

私の環境の場合はBus 0の 06 まで埋まっていたので、07.0を使いました。以下の通りです。

--qemu-commandline="-object can-bus,id=canbus2 -device virtio-can-pci,canbus=canbus2,addr=07.00 -object can-host-socketcan,id=canhost2,if=vcan2,canbus=canbus2"

なお、Bus 0は PCI Bridgeなので避けたいと思ったのですが、上記を 07:00.0 と書いたところこれもエラー。 (空きのBus IDとdevice IDが両方7なので紛らわしいですね) そこで、同じく virtio-can-pci で使えることになっている busnr が使えるかなと思ったのですが、 指定してみたところ「writableではない」という趣旨のエラーが出てしまいました。 コードは未調査ですが、最低限やりたいことはできたのでここまででヨシとすることにしました。

なお、qemuのdriverごとのoptionは以下で調べられるようです。 以下のvirtio-can-pciを目的のdriverに置き換えてください。

$ qemu-system-aarch64 -device virtio-can-pci,help

また、組み込まれているdriverの一覧は以下で見られます。

$ qemu-system-aarch64 -device help

気づき(未解決)

virt-install の場合、VMを定義するとpower onまでしてくれるのですが、emulatorの変更と --qemu-commandline の指定を入れたところ、power onしてくれなくなりました。virsh start DOMAIN_NAME(等)すればよいのですが、 いったん置いてあります。

続くかもしれません。