search
LoginSignup
0

More than 1 year has passed since last update.

posted at

updated at

NetBSD-9.0のmount_qemufwcfg(8)でqemuのfw_cfgデータを参照してみる

NetBSD Advent Calendar 2020 5日目の記事です。
今日はNetBSD-9.0で追加された、mount_qemufwcfg(8)コマンドの紹介をしようと思います。
NetBSD-9.0のリリースアナウンス(Announcing NetBSD 9.0 (Feb 14, 2020))を見ると、"support for the QEMU firmware configuration device"という一文があります。これに対応する機能が今日紹介するmount_qemufwcfg(8)のようです。

Improvements for using NetBSD as a guest OS, with support for the QEMU firmware configuration device, ...

mount_qemufwcfgとQEMU fw configuration file

QEMUにはQEMU fw_cfg(QEMU firmware configuration)という、ゲストOS側に対してBootの順番やACPIやSMBIOSテーブル、仮想マシンに割り振るUUID、SMPやNUMA情報といったデータをホストOS側から提供するためのインタフェースが提供されています。
NetBSD-9.0で追加された、mount_qemufwcfg(8)は、このQEMU fw_cfgデータを仮想ファイルシステム経由でmountして参照可能にするコマンドになります。

ホストOS側でのqemu起動オプション

さっそく順を追って試してみましょう。mount_qemufwcfg(8)はゲストOS側のNetBSDで実行するため、まずはホストOS側でqemuを起動します。起動時に -fw_cfg name=<NAME>,file=<FILE> のような形で必要なデータをゲストOS側に渡します。

name=... で指定した内容がゲストOS側での参照パスになります。 opt/... から始まるパスがユーザ用に予約されているため(※)、この例では opt/com.mycompany/blob というパスを指定しています。
QEMU fw cfgでは以下のように記載されています。

Names that begin with "opt/" are reserved for users.

そして file=... には参照させるファイルを指定します。この例では"Hello,World."というテキストが書かれたファイルを渡しています。

$ echo 'Hello,World.' > my_blob.bin
$ qemu-system-x86_64 \
        -m 512M \
        -boot order=c \
        -net nic \
        -net user,hostfwd=tcp::2222-:22 \
        -fw_cfg name=opt/com.mycompany/blob,file=./my_blob.bin \
        -snapshot \
        -hdd nbsd.img

mount_qemucfgを使用する

必要な準備

ゲストOSが起動したらmount_qemufwcfg(8)を試してみたいところですが、いくつか準備が必要です。
/usr/src/sbin/mount_qemufwcfg/fwcfg.cのソースコードを見ると、 /dev/qemufwcfg を参照するようです。

#define _PATH_FWCFG "/dev/qemufwcfg"

ゲストOS側のNetBSDでデバイスノードを作成するため、 mknod -lqemufwcfg のmajorデバイス番号を確認します。

$ mknod -l | grep qemufwcfg
qemufwcfg character major 342

mknod qemufwcfg c 342 0qemufwcfg のデバイスノードを作成します。

$ cd /dev
$ sudo mknod qemufwcfg c 342 0
$ ls -l /dev/qemufwcfg
crw-r--r--  1 root  wheel  342, 0 Dec  4 10:21 /dev/qemufwcfg

mount_qemufwcfg(8)でfw_cfgデータを参照する

これでmount_qemufwcfg(8)を使用してfw_cfgデータをマウントできます。この例では /mnt をマウントポイントにしています。

$ sudo mount_qemufwcfg /mnt

どうやらPUFFS(NetBSDのユーザランド上でファイルシステムを実現する機能)を利用しているようですね。
PUFFSについては、過去のNetBSD Advent Calendarにて紹介していますので併せてご参照ください。

$ df -h
Filesystem         Size       Used      Avail %Cap Mounted on
...
/dev/puffs           0B         0B         0B 100% /mnt

マウントしたディレクトリ以下では色々なデータが参照できる状態になっています。今回は -fw_cfg オプションで渡した /mnt/opt/com.mycompany/blob を見てみます。

$ find /mnt -type f | xargs file
/mnt/bios-geometry:            empty
/mnt/bootorder:                empty
/mnt/etc/acpi/rsdp:            data
/mnt/etc/acpi/tables:          data
/mnt/etc/boot-fail-wait:       ISO-8859 text, with no line terminators
/mnt/etc/e820:                 data
/mnt/etc/smbios/smbios-anchor: data
/mnt/etc/smbios/smbios-tables: SVr2 curses screen image, big-endian
/mnt/etc/system-states:        lif file
/mnt/etc/table-loader:         data
/mnt/etc/tpm/log:              empty
/mnt/genroms/kvmvapic.bin:     BIOS (ia32) ROM Ext. (18*512)
/mnt/opt/com.mycompany/blob:   UTF-8 Unicode text

ファイルの中身を見てみると、ホストOS側で指定したファイルが参照できています!
ただし、ゲストOS起動後にホストOS側がファイルの中身を変更してもゲストOS側のファイルには変更が反映されず、どうやらゲストOS起動時点ででのファイルの中身が常に参照されるという挙動になっています。

$ cat /mnt/opt/com.mycompany/blob
Hello,World.

まとめ

NetBSD 9.0で追加されたmount_qemufwcfg(8)コマンドを試してみました。ホストOS側からファイルを渡すことができるため、ゲストOS起動時にssh鍵やクレデンシャル情報等を渡すといった柔軟な応用ができそうです。

参考URL

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0