NetBSD Advent Calendar 2019 8日目の記事です。超絶遅れてごめんなさい🙇
@ozaki-r さんがNetBSDにvip9p(4)を実装して下さいました!
これとQEMUの -virtfs
を使えば、QEMU guestのNetBSDからhost Linux1のファイルを直接読み書きできるようになります。NFSサーバー要らずで便利2。
vip9p(4)を有効にしたkernelのビルド・インストール
sys/arch/amd64/conf/GENERIC
の vio9p
を有効にしてGENERIC kernelをビルドします。
vio9p* at virtio? # Virtio 9P device
ビルドしたkernelをインストールして、試しに起動してみましょう。
# host (Linux)
mkdir ~/tmp/
touch ~/tmp/foo/
qemu-system-x86_64 -m 1G -hda /path/to/netbsd.qcow2 \
-virtfs local,path=$HOME/tmp/,mount_tag=vfstag_tmp,security_model=mapped \
-nographic -nic user,hostfwd=tcp::10022-:22 -enable-kvm -no-reboot -rtc base=utc
vio9p0
at virtio0
at pci0
が認識されます。
...
[ 1.0228059] wm0 at pci0 dev 3 function 0: Intel i82540EM 1000BASE-T Ethernet (rev. 0x03)
[ 1.0228059] wm0: interrupting at ioapic0 pin 11
[ 1.0228059] wm0: Ethernet address 52:54:00:12:34:56
[ 1.0228059] makphy0 at wm0 phy 1: Marvell 88E1011 Gigabit PHY, rev. 0
[ 1.0228059] makphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
[ 1.0228059] virtio0 at pci0 dev 4 function 0
[ 1.0228059] virtio0: Virtio 9P Transport Device (rev. 0x00)
[ 1.0228059] vio9p0 at virtio0: Features: 0x10000000<INDIRECT_DESC>
[ 1.0228059] vio9p0: tagged as vfstag_tmp
[ 1.0228059] virtio0: interrupting at ioapic0 pin 11
[ 1.0228059] isa0 at pcib0
[ 1.0228059] com0 at isa0 port 0x3f8-0x3ff irq 4: ns16550a, working fifo
[ 1.0228059] com0: console
...
ちなみにvip9p(4)が有効になっていない場合はこんな感じです:
[ 1.0228059] makphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
[ 1.0228059] vendor 1af4 product 1009 (prehistoric, subclass 0x02) at pci0 dev 5 function 0 not configured
[ 1.0228059] isa0 at pcib0
pcictl
でも確認できます。
# guest (NetBSD)
pcictl pci0 list -N | grep virt
# 000:04:0: Qumranet Virtio (prehistoric, subclass 0x02) [virtio0]
mknod
/dev/vio9p*
を手動で作ります。
# guest (NetBSD)
# majorの確認
cat /proc/devices | grep vio9p # 356 vio9p
# 16個(適当)作っておく
mknod /dev/vio9p0 c 356 0
mknod /dev/vio9p1 c 356 1
mknod /dev/vio9p2 c 356 2
mknod /dev/vio9p3 c 356 3
mknod /dev/vio9p4 c 356 4
mknod /dev/vio9p5 c 356 5
mknod /dev/vio9p6 c 356 6
mknod /dev/vio9p7 c 356 7
mknod /dev/vio9p8 c 356 8
mknod /dev/vio9p9 c 356 9
mknod /dev/vio9p10 c 356 10
mknod /dev/vio9p11 c 356 11
mknod /dev/vio9p12 c 356 12
mknod /dev/vio9p13 c 356 13
mknod /dev/vio9p14 c 356 14
mknod /dev/vio9p15 c 356 15
/usr/sbin/mount_9p
の更新
kernelだけでなく mount_9p
もvio9p対応版 (-c
が使える版) にする必要があります。本家のsets/baseから持ってくることにします。
# guest (NetBSD)
mv /usr/sbin/mount_9p /usr/sbin/mount_9p.orig
# host (Linux)
cd 汚しても良い適当な作業ディレクトリ
wget http://nycdn.netbsd.org/pub/NetBSD-daily/HEAD/latest/amd64/binary/sets/base.tar.xz
tar xvJf base.tar.xz
scp -P10022 ./usr/sbin/mount_9p root@localhost:/usr/sbin/
# guest (NetBSD)
/usr/sbin/mount_9p -h
# usage: mount_9p [-su] [-o mntopts] [-p port] [user@]server[:path] mountpoint
# mount_9p -c [-su] [-o mntopts] devfile mountpoint
マウントしてみましょう。
# guest (NetBSD)
mkdir /root/tmp_mnt/
mount_9p -cu /dev/vio9p0 /root/tmp_mnt/
mount # /dev/vio9p0 on /root/tmp_mnt type puffs|9p
ls tmp_mnt/ # foo (hostの ~/tmp/foo)
umount tmp_mnt/
-virtfs
が複数ある場合は、/dev/vio9p0, /dev/vio9p1, /dev/vio9p2, ...
と順番に割り当てられます。mount_tag
とdmesgを比較しても確認できます。
qemu:
-virtfs local,path=$HOME/tmp/,mount_tag=vfstag_tmp,security_model=mapped
^^^^^^^^^^
-virtfs local,path=$HOME/tmp2/,mount_tag=vfstag_tmp2,security_model=mapped
^^^^^^^^^^^
dmesg:
[ 1.0228059] vio9p0: tagged as vfstag_tmp
^^^^^^ ^^^^^^^^^^
[ 1.0228059] vio9p1: tagged as vfstag_tmp2
^^^^^^ ^^^^^^^^^^^
/etc/fstab
/etc/fstab
で設定する場合はこんな感じです。
/dev/vio9p0 /root/tmp_mnt0/ 9p rw,-cu
/dev/vio9p1 /root/tmp_mnt1/ 9p rw,-cu
rebootする前に mount -a
でapply、mount
で確認しておきましょう。
-virtfs
を付けずに起動した場合は
Starting syslogd.
Mounting all file systems...
mount_9p: /dev/vio9p0: Device not configured
mount_9p: /dev/vio9p1: Device not configured
/etc/rc.d/mountall exited with code 1
とエラーメッセージが出ますがマウントせずに普通に起動します。