この記事は、NetBSD Advent Calendar 2021の7日目の記事です。
はじめに
今回は、VirtIO SCSI Host Device (virtio-scsi)を使う場合について、書きたいと思います。
VirtIO SCSI Host Deviceとは?
仕様書によると、いわゆるvirtio-scsiというのが、VirtIO Host Deviceのことであるようです。 NetBSDですと、vioscsi(4)というのが それに当たるようです。 VirtIO SCSIには、scsi-hdとscsi-block、scsi-genericという3つの種類の設定ができるようです。 qemu.orgによりvirtio-blkとvirtio-scsiの各設定の比較記事によると、 通常の仮想ディスクイメージを使う場合には、最も性能の良いscsi-hdを使うので良さそうです。 この比較記事によると、virtio-blkの方がvirtio-scsiよりもランダム読み取りの性能が高いそうです。 しかし、接続できるディスクデバイスの数はvirtio-scsiの方が多いそうです。
Google Cloud Compute Engineで提供されている VPSの標準のブロックデバイスは、このvirtio-scsiになっていました。
qemuでvirtio-scsiを使うように指定してNetBSD/amd64-currentをインストールする
virtio-scsiでは、光学ディスクドライブもサポートしているようです。 インストールするために利用するISOイメージファイルもvirtio-scsi経由で設定してみます。
qemuを起動するシェルスクリプトを用意します。VirtIO機能を利用する場合には、コマンドライン引数が長くなりがちですので、 シェルスクリプトの形にまとめておくのが良いと思います。 qemu-virtio-scsi_install.shというファイル名で、以下のようなシェルスクリプトを作成しておきます。
#!/bin/sh
INSTALLISO=../NetBSD-9.99.92-amd64_202112102310Z.iso
# Install
qemu-system-x86_64 \
-smp 4 \
-m 4G \
-accel nvmm \
-device virtio-scsi-pci,id=scsi \
-device scsi-cd,drive=cd0 \
-drive if=none,id=cd0,file=${INSTALLISO},media=disk,format=raw \
-device scsi-hd,drive=hd1 \
-drive if=none,id=hd1,file=netbsd.qcow2,format=qcow2 \
-net nic,model=virtio -net user \
-rtc base=localtime,clock=host \
-device intel-hda -device hda-duplex \
-vga qxl
起動は以下のように実行すれば良いでしょう。 cd0 at scsibus0 at vioscsi0から起動できます。 インストールの各手順を割愛します。
$ sh ./qemu-virtio-scsi_install.sh
インストールが完了したら、仮想マシンはシャットダウンしておきます。
インストールしたNetBSD/amd64-currentを起動させる
インストールに必要な設定は省いたコマンドライン引数を指定してqemuを起動させるシェルスクリプトを以下のように用意します。
ファイル名は、qemu-virtio-scsi.sh
としておきます
#!/bin/sh
qemu-system-x86_64 \
-smp 4 \
-m 4G \
-accel nvmm \
-device virtio-scsi-pci,id=scsi \
-device scsi-hd,drive=hd1 \
-drive if=none,id=hd1,file=netbsd.qcow2,format=qcow2 \
-net nic,model=virtio -net user \
-rtc base=localtime,clock=host \
-device intel-hda -device hda-duplex \
-vga qxl
起動するとdmesgは以下のようになります。
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
2018, 2019, 2020, 2021 The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
NetBSD 9.99.92 (GENERIC) #0: Fri Dec 10 21:57:13 UTC 2021
mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC
total memory = 4095 MB
avail memory = 3941 MB
timecounter: Timecounters tick every 10.000 msec
Kernelized RAIDframe activated
timecounter: Timecounter "i8254" frequency 1193182 Hz quality 100
mainbus0 (root)
ACPI: RSDP 0x00000000000F5980 000014 (v00 BOCHS )
ACPI: RSDT 0x00000000BFFE1A2B 000034 (v01 BOCHS BXPC 00000001 BXPC 00000001)
ACPI: FACP 0x00000000BFFE18C7 000074 (v01 BOCHS BXPC 00000001 BXPC 00000001)
ACPI: DSDT 0x00000000BFFE0040 001887 (v01 BOCHS BXPC 00000001 BXPC 00000001)
ACPI: FACS 0x00000000BFFE0000 000040
ACPI: APIC 0x00000000BFFE193B 000090 (v01 BOCHS BXPC 00000001 BXPC 00000001)
ACPI: HPET 0x00000000BFFE19CB 000038 (v01 BOCHS BXPC 00000001 BXPC 00000001)
ACPI: WAET 0x00000000BFFE1A03 000028 (v01 BOCHS BXPC 00000001 BXPC 00000001)
ACPI: 1 ACPI AML tables successfully acquired and loaded
ioapic0 at mainbus0 apid 0: pa 0xfec00000, version 0x20, 24 pins
cpu0 at mainbus0 apid 0
cpu0: Use lfence to serialize rdtsc
cpu0: CPU base freq 1500000000 Hz
cpu0: CPU max freq 3900000000 Hz
cpu0: TSC freq CPUID 1497600000 Hz
cpu0: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz, id 0x706e5
cpu0: node 0, package 0, core 0, smt 0
cpu1 at mainbus0 apid 1
cpu1: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz, id 0x706e5
cpu1: node 0, package 0, core 0, smt 1
cpu2 at mainbus0 apid 2
cpu2: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz, id 0x706e5
cpu2: node 0, package 0, core 1, smt 0
cpu3 at mainbus0 apid 3
cpu3: Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz, id 0x706e5
cpu3: node 0, package 0, core 1, smt 1
acpi0 at mainbus0: Intel ACPICA 20210930
acpi0: X/RSDT: OemId &t;BOCHS ,BXPC ,00000001>, AslId <BXPC,00000001>
LNKS: ACPI: Found matching pin for 0.1.INTA at func 3: 9
LNKB: ACPI: Found matching pin for 0.2.INTA at func 0: 10
LNKC: ACPI: Found matching pin for 0.3.INTA at func 0: 11
LNKD: ACPI: Found matching pin for 0.4.INTA at func 0: 11
LNKA: ACPI: Found matching pin for 0.5.INTA at func 0: 10
acpi0: SCI interrupting at int 9
acpi0: fixed power button present
timecounter: Timecounter "ACPI-Fast" frequency 3579545 Hz quality 1000
hpet0 at acpi0: high precision event timer (mem 0xfed00000-0xfed00400)
timecounter: Timecounter "hpet0" frequency 100000000 Hz quality 2000
pckbc1 at acpi0 (KBD, PNP0303) (kbd port): io 0x60,0x64 irq 1
pckbc2 at acpi0 (MOU, PNP0F13) (aux port): irq 12
fdc0 at acpi0 (FDC0, PNP0700): io 0x3f2-0x3f5,0x3f7 irq 6 drq 2
lpt0 at acpi0 (LPT1, PNP0400-1): io 0x378-0x37f irq 7
com0 at acpi0 (COM1, PNP0501-1): io 0x3f8-0x3ff irq 4
com0: ns16550a, 16-byte FIFO
qemufwcfg0 at acpi0 (FWCF, QEMU0002): io 0x510-0x51b
qemufwcfg0: <QEMU>
ACPI: Enabled 2 GPEs in block 00 to 0F
pckbd0 at pckbc1 (kbd slot)
pckbc1: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard
pms0 at pckbc1 (aux slot)
pckbc1: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pci0 at mainbus0 bus 0: configuration mode 1
pci0: i/o space, memory space enabled, rd/line, rd/mult, wr/inv ok
pchb0 at pci0 dev 0 function 0: Intel 82441FX (PMC) PCI and Memory Controller (rev. 0x02)
pcib0 at pci0 dev 1 function 0: Intel 82371SB (PIIX3) PCI-ISA Bridge (rev. 0x00)
piixide0 at pci0 dev 1 function 1: Intel 82371SB IDE Interface (PIIX3) (rev. 0x00)
piixide0: bus-master DMA support present
piixide0: primary channel wired to compatibility mode
piixide0: primary channel interrupting at ioapic0 pin 14
atabus0 at piixide0 channel 0
piixide0: secondary channel wired to compatibility mode
piixide0: secondary channel interrupting at ioapic0 pin 15
atabus1 at piixide0 channel 1
piixpm0 at pci0 dev 1 function 3: Intel 82371AB (PIIX4) Power Management Controller (rev. 0x03)
timecounter: Timecounter "piixpm0" frequency 3579545 Hz quality 1000
piixpm0: 24-bit timer
piixpm0: interrupting at ioapic0 pin 9
iic0 at piixpm0 port 0: I2C bus
vga0 at pci0 dev 2 function 0: Red Hat QXL Video (rev. 0x05)
wsdisplay0 at vga0 kbdmux 1: console (80x25, vt100 emulation), using wskbd0
wsmux1: connecting to wsdisplay0
drm at vga0 not configured
virtio0 at pci0 dev 3 function 0
virtio0: network device (rev. 0x00)
vioif0 at virtio0: features: 0x31070020<EVENT_IDX,INDIRECT_DESC,NOTIFY_ON_EMPTY,CTRL_RX,CTRL_VQ,STATUS,MAC>
vioif0: Ethernet address 52:54:00:12:34:56
virtio0: allocated 20480 byte for virtqueue 0 for rx0, size 256
virtio0: using 8192 byte (512 entries) indirect descriptors
virtio0: allocated 81920 byte for virtqueue 1 for tx0, size 256
virtio0: using 69632 byte (4352 entries) indirect descriptors
virtio0: allocated 8192 byte for virtqueue 2 for control, size 64
virtio0: config interrupting at msix0 vec 0
virtio0: queues interrupting at msix0 vec 1
virtio1 at pci0 dev 4 function 0
virtio1: SCSI device (rev. 0x00)
vioscsi0 at virtio1: features: 0x10000000<INDIRECT_DESC>
virtio1: allocated 86016 byte for virtqueue 0 for control, size 256
virtio1: using 73728 byte (4608 entries) indirect descriptors
virtio1: allocated 86016 byte for virtqueue 1 for event, size 256
virtio1: using 73728 byte (4608 entries) indirect descriptors
virtio1: allocated 86016 byte for virtqueue 2 for request, size 256
virtio1: using 73728 byte (4608 entries) indirect descriptors
vioscsi0: cmd_per_lun 128 qsize 256 seg_max 254 max_target 255 max_lun 16383
virtio1: config interrupting at msix1 vec 0
virtio1: queues interrupting at msix1 vec 1
scsibus0 at vioscsi0: 16 targets, 1024 luns per target
hdaudio0 at pci0 dev 5 function 0: HD Audio Controller
hdaudio0: interrupting at msi2 vec 0
hdaudio0: HDA ver. 1.0, OSS 4, ISS 4, BSS 0, SDO 1, 64-bit
hdafg0 at hdaudio0: vendor 1af4 product 0022
hdafg0: DAC00 2ch: Speaker [Jack]
hdafg0: ADC01 2ch: Line In [Jack]
hdafg0: 2ch/2ch 16000Hz 22050Hz 32000Hz 44100Hz 48000Hz 88200Hz 96000Hz PCM16
audio0 at hdafg0: playback, capture, full duplex, independent
audio0: slinear_le:16 2ch 48000Hz, blk 1920 bytes (10ms) for playback
audio0: slinear_le:16 2ch 48000Hz, blk 1920 bytes (10ms) for recording
spkr0 at audio0: PC Speaker (synthesized)
wsbell at spkr0 not configured
isa0 at pcib0
attimer0 at isa0 port 0x40-0x43
pcppi0 at isa0 port 0x61
spkr1 at pcppi0: PC Speaker
wsbell at spkr1 not configured
midi0 at pcppi0: PC speaker
sysbeep0 at pcppi0
attimer0: attached to pcppi0
acpicpu0 at cpu0: ACPI CPU
acpicpu0: C1: HLT, lat 0 us, pow 0 mW
acpicpu1 at cpu1: ACPI CPU
acpicpu2 at cpu2: ACPI CPU
acpicpu3 at cpu3: ACPI CPU
cpu0: CPU base freq 1500000000 Hz
cpu0: CPU max freq 3900000000 Hz
cpu0: TSC freq CPUID 1497600000 Hz
cpu0: TSC freq calibrated 1396657000 Hz
timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
autoconfiguration error: ERROR: 43778851 cycle TSC drift observed
fd0 at fdc0 drive 0: 1.44MB, 80 cyl, 2 head, 18 sec
sd0 at scsibus0 target 0 lun 0: <QEMU, QEMU HARDDISK, 2.5+> disk fixed
sd0: 30720 MB, 16383 cyl, 16 head, 240 sec, 512 bytes/sect x 62914560 sectors
sd0: GPT GUID: 65ba8dc6-924e-42ea-a203-23da6b8a35d4
dk0 at sd0: "VMROOT", 54523904 blocks at 64, type: ffs
dk1 at sd0: "VMSWAP", 8388608 blocks at 54523968, type: swap
sd0: async, 8-bit transfers, tagged queueing
IPsec: Initialized Security Association Processing.
aes: Intel AES-NI
chacha: x86 SSE2 ChaCha
WARNING: 1 error while detecting hardware; check system log.
boot device: sd0
root on dk0 dumps on dk1
root file system type: ffs
kern.module.path=/stand/amd64/9.99.92/modules
clock: unknown CMOS layout
wsdisplay0: screen 1 added (80x25, vt100 emulation)
wsdisplay0: screen 2 added (80x25, vt100 emulation)
wsdisplay0: screen 3 added (80x25, vt100 emulation)
wsdisplay0: screen 4 added (80x25, vt100 emulation)
無事にdk0 at sd0 at scsibus0 at vioscsi0 at virtio1から起動できました。