Qemuでオプションを直打ちして起動させていたが、libvirtにして自動起動させたいと思ったのでできるだけ同じ環境を構築して移行させることにした。
結果的に、OSはブルースクリーンになってしまったので、これまで使っていたVMイメージは破棄したが、ほぼ同じ構成の仮想PCを作ることはできたと思う。
注意点としては、libvirtはSystem Management BIOS(SMBIOS)のUUIDの重複が許容されないこと、またそれぞれの仮想OS(libvirt用語だとDomain)ごとにUUIDをランダムに振って仮想OS起動時に明示的に引き渡してくれるため、Qemuと同じようにしたければ手動で変更することが必要になる。
Qemuでは指定しない場合は、00000000-0000-0000-0000-000000000000になる。そのため、既存のディスクを引き継ぐと、Windowsがアクティベーションエラーを出す。
当初のQemuのオプション
これまで使っていたQemuの設定はこちら(Windows11を使用するのにTPMを利用する必要があったため、swtpmを使っているのでシェルスクリプト)
#!/bin/sh
swtpm socket --tpm2 --tpmstate dir=/VM_images/tpm0 --ctrl type=unixio,path=/VM_images/tpm0/swtpm-sock &
exec qemu-system-x86_64 \
\
-global driver=cfi.pflash01,property=secure,value=on \
-drive if=pflash,format=raw,unit=0,file=/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd,readonly=on \
-drive if=pflash,format=raw,unit=1,file=/VM_images/OVMF_VARS_win11.fd \
\
-machine type=q35,smm=on,accel=kvm \
-global ICH9-LPC.disable_s3=1 \
\
-device ich9-ahci,id=ahci \
-object rng-random,id=rng0,filename=/dev/urandom -device virtio-rng-pci,rng=rng0 \
-enable-kvm \
-cpu host \
-drive file=/VM_images/Win11VM_master.img,if=virtio,index=0,media=disk,cache=none \
-net nic,macaddr=00:00:00:00:00:01,model=virtio -net tap,ifname=tap0,script=no,downscript=no,vhost=on \
-m 4G \
-name "Windows" \
-rtc base=localtime,clock=host \
-smp 4,sockets=1,cores=4 \
-spice port=5920,addr=0.0.0.0,disable-ticketing=on,streaming-video=filter,playback-compression=on \
\
-audiodev spice,id=snd0 \
-device intel-hda \
-device hda-output,audiodev=snd0 \
\
-device virtio-serial-pci \
-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 \
-chardev spicevmc,id=spicechannel0,name=vdagent \
\
-chardev socket,id=tpmc,path=/VM_images/tpm0/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=tpmc \
-device tpm-tis,tpmdev=tpm0 \
\
-vnc 0.0.0.0:0 -k ja \
-monitor stdio \
-vga qxl \
$@"
これをファイルに保存して、そのまま走らせていただけ。ファイルのあとにQemuのオプションを付ければ追加することはできるようにしているが、通常は追加しない。
仮想TPMのソケット名、UEFIイメージ(OVMF)の書き込み用ファイル名、OSイメージファイル名、ネットワークカードのMACアドレス、SPICE接続のポート番号、VNC接続のポート番号が重複するので、複数稼働させる場合はこれらを要変更。
virt-installコマンドのオプション
いろいろと試行錯誤した結果、以下のようなvirt-installコマンドにすることで、だいたい似たような構成にできた。
virt-install \
\
--name Win11VM \
--os-variant win10 \
\
--boot loader=/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd,loader.readonly=yes,loader.type=pflash,nvram.template=/VM_images/OVMF_VARS_Win11VM_libvirt.fd,loader_secure=yes \
\
--machine q35 \
--features smm.state=on \
--virt-type kvm \
\
--rng /dev/urandom,driver.iommu=on,model=virtio \
\
--clock offset=localtime,timer.name=kvmclock,kvmclock_present=yes, \
--vcpus 4,cores=4,sockets=1 \
\
--cpu host \
\
--memory 4096 \
--memballoon virtio \
\
--metadata uuid=00000000-0000-0000-0000-000000000000 \
\
--disk path=/VM_images/VM_IMG_Win11VM_libvirt.img,format=qcow2,device=disk,boot.order=1,cache=none,target.bus=virtio \
\
--network bridge=br0,model=virtio,mac=00:00:00:00:00:01 \
\
--graphics spice,listen=0.0.0.0,defaultMode=insecure,image.compression=auto_glz,streaming.mode=filter,clipboard.copypaste=yes \
--video qxl \
--channel spicevmc \
\
--sound ich9 \
\
--tpm backend.type=emulator,backend.version=2.0,model=tpm-tis \
\
--noautoconsole \
\
--import
インストールをするのにインストールメディアをマウントしたければ、最後の--import移行をこんな感じで変更する。(Windowsの場合)
--import \
--cdrom /data/samba1/share/Win11_22H2_Japanese_x64v1.iso \
--disk /data/samba1/share/virtio-win-0.1.225.iso,device=cdrom
事前準備
- OSインストール用のディスクイメージをqemu-imgで作成しておく
- OVMF_VARS.fdをコピーして用意しておく
- 仮想PC名(Domain名)、SMBIOSのUUID、MACアドレス、SPICE接続のポートを決めておく
- SPICEのポート以外のそれぞれを所定のオプションの中に埋め込む
事後作業
virsh edit <Domain名>
コマンドを利用して作成した仮想PCのSPICEポートの設定を手動変更する。以下のような感じで、grahicsの中のportに利用したいポート番号をいれ、autoportをnoに変更する。
<graphics type='spice' port='5920' autoport='no' listen='0.0.0.0' defaultMode='insecure'>
<listen type='address' address='0.0.0.0'/>
<image compression='off'/>
</graphics>
その他のメモ
作成した仮想PCをlibvirtの登録上から「virsh undefine <Domain名>
」で削除しようとしてもエラーが出て削除できない。これは、UEFIイメージ(OVMF)の削除をするには追加オプションが必要なためなので、「virsh undefine --nvram <Domain名>
」で削除できる。
インストール用にメディアをマウントしていた場合は、「virsh detach-disk
<Domain名> sda --config」「virsh detach-disk
<Domain名> sdb --config」で削除できる。
libvirtd起動時に自動起動させたい場合は、「virsh autostart <Domain名>
」
Windowsのhiberfil.sysを消そうと管理者モードで開いたcmdでpowercfg.exe /hibernate off
をやっても、ハイバネートが停止しない。これは、Qemuのオプションに-global ICH9-LPC.disable_s4=1 \
が含まれているため。libvirtの設定で編集する方法を調べきれなかったので、-global ICH9-LPC.disable_s4=1 \
を外してQemuを直打ちで起動して対応した。
libvirtでのQemuのオプション
前述のvirt-installコマンド及び手作業での修正の結果、Qemuのオプションは以下のようになる。
# virsh domxml-to-native qemu-argv --domain Win11VM | sed -e 's/ -/ \\\n -/g' -e 's+ \(/usr/bin/qemu-system-x86_64\)+ \\\n\1+g'
LC_ALL=C PATH=/bin:/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/bin HOME=/var/lib/libvirt/qemu/domain--1-Win11VM USER=root XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-Win11VM/.local/share XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-Win11VM/.cache XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-Win11VM/.config \
/usr/bin/qemu-system-x86_64 \
-name guest=Win11VM,debug-threads=on \
-S \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-Win11VM/master-key.aes"}' \
-blockdev '{"driver":"file","filename":"/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \
-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/Win11VM_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}' \
-machine pc-q35-7.0,usb=off,vmport=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format \
-accel kvm \
-cpu EPYC-Milan,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,vaes=on,vpclmulqdq=on,spec-ctrl=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,pcid=off,kvmclock=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff \
-global driver=cfi.pflash01,property=secure,value=on \
-m 4096 \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":4294967296}' \
-overcommit mem-lock=off \
-smp 4,sockets=1,dies=1,cores=4,threads=1 \
-uuid 00000000-0000-0000-0000-000000000000 \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain--1-Win11VM/monitor.sock,server=on,wait=off \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=localtime \
-no-shutdown \
-global ICH9-LPC.disable_s3=1 \
-global ICH9-LPC.disable_s4=1 \
-boot strict=on \
-device '{"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"}' \
-device '{"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"}' \
-device '{"driver":"pcie-root-port","port":18,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x2.0x2"}' \
-device '{"driver":"pcie-root-port","port":19,"chassis":4,"id":"pci.4","bus":"pcie.0","addr":"0x2.0x3"}' \
-device '{"driver":"pcie-root-port","port":20,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x2.0x4"}' \
-device '{"driver":"pcie-root-port","port":21,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x2.0x5"}' \
-device '{"driver":"pcie-root-port","port":22,"chassis":7,"id":"pci.7","bus":"pcie.0","addr":"0x2.0x6"}' \
-device '{"driver":"pcie-root-port","port":23,"chassis":8,"id":"pci.8","bus":"pcie.0","addr":"0x2.0x7"}' \
-device '{"driver":"pcie-root-port","port":24,"chassis":9,"id":"pci.9","bus":"pcie.0","multifunction":true,"addr":"0x3"}' \
-device '{"driver":"pcie-root-port","port":25,"chassis":10,"id":"pci.10","bus":"pcie.0","addr":"0x3.0x1"}' \
-device '{"driver":"pcie-root-port","port":26,"chassis":11,"id":"pci.11","bus":"pcie.0","addr":"0x3.0x2"}' \
-device '{"driver":"pcie-root-port","port":27,"chassis":12,"id":"pci.12","bus":"pcie.0","addr":"0x3.0x3"}' \
-device '{"driver":"pcie-root-port","port":28,"chassis":13,"id":"pci.13","bus":"pcie.0","addr":"0x3.0x4"}' \
-device '{"driver":"pcie-root-port","port":29,"chassis":14,"id":"pci.14","bus":"pcie.0","addr":"0x3.0x5"}' \
-device '{"driver":"qemu-xhci","p2":15,"p3":15,"id":"usb","bus":"pci.2","addr":"0x0"}' \
-device '{"driver":"virtio-serial-pci","id":"virtio-serial0","bus":"pci.3","addr":"0x0"}' \
-blockdev '{"driver":"file","filename":"/VM_images/VM_IMG_Win11VM_libvirt.img","node-name":"libvirt-1-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.4","addr":"0x0","drive":"libvirt-1-format","id":"virtio-disk0","bootindex":1,"write-cache":"on"}' \
-netdev tap,fd=23,vhost=on,vhostfd=31,id=hostnet0 \
-device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"00:00:00:00:00:01","bus":"pci.1","addr":"0x0"}' \
-chardev pty,id=charserial0 \
-device '{"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0}' \
-chardev spicevmc,id=charchannel0,name=vdagent \
-device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":1,"chardev":"charchannel0","id":"channel0","name":"com.redhat.spice.0"}' \
-chardev null,id=chrtpm \
-tpmdev emulator,id=tpm-tpm0,chardev=chrtpm \
-device '{"driver":"tpm-tis","tpmdev":"tpm-tpm0","id":"tpm0"}' \
-device '{"driver":"usb-tablet","id":"input0","bus":"usb.0","port":"1"}' \
-audiodev '{"id":"audio1","driver":"spice"}' \
-spice port=5920,addr=0.0.0.0,disable-ticketing=on,plaintext-channel=default,image-compression=auto_glz,streaming-video=filter,seamless-migration=on \
-device '{"driver":"qxl-vga","id":"video0","max_outputs":1,"ram_size":67108864,"vram_size":67108864,"vram64_size_mb":0,"vgamem_mb":16,"bus":"pcie.0","addr":"0x1"}' \
-device '{"driver":"ich9-intel-hda","id":"sound0","bus":"pcie.0","addr":"0x1b"}' \
-device '{"driver":"hda-duplex","id":"sound0-codec0","bus":"sound0.0","cad":0,"audiodev":"audio1"}' \
-chardev spicevmc,id=charredir0,name=usbredir \
-device '{"driver":"usb-redir","chardev":"charredir0","id":"redir0","bus":"usb.0","port":"2"}' \
-chardev spicevmc,id=charredir1,name=usbredir \
-device '{"driver":"usb-redir","chardev":"charredir1","id":"redir1","bus":"usb.0","port":"3"}' \
-device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.5","addr":"0x0"}' \
-object '{"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"}' \
-device '{"driver":"virtio-rng-pci","iommu_platform":true,"rng":"objrng0","id":"rng0","bus":"pci.6","addr":"0x0"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
これはJSON形式になっているので、イコールとコンマでの区切りに変換する。なお、ハイフンのようでハイフンでない文字(-
)があった。また、正規表現でネストを扱うのは難しい(やり方がわかる人がいたら教えてほしい)ので、cacheのところの変換は手抜き。
# virsh domxml-to-native qemu-argv --domain Win11VM | sed -e 's/ -/ \\\n -/g' -e 's+ \(/usr/bin/qemu-system-x86_64\)+ \\\n\1+g' | sed -e 's/"\([a-zA-Z0-9\.\-\_-]\+\)":"\?\([a-zA-Z0-9\.\-\:\/\_-]\+\)"\?/\1=\2/g' -e 's/"cache":{\([a-z=\-]\+\),\([a-z=\-]\+\)}/cache.\1,cache.\2/' -e "s/'{\([^}]\+\)}'/\1/g"
LC_ALL=C PATH=/bin:/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/bin HOME=/var/lib/libvirt/qemu/domain--1-Win11VM USER=root XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-Win11VM/.local/share XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-Win11VM/.cache XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-Win11VM/.config \
/usr/bin/qemu-system-x86_64 \
-name guest=Win11VM,debug-threads=on \
-S \
-object qom-type=secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain--1-Win11VM/master-key.aes \
-blockdev driver=file,filename=/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd,node-name=libvirt-pflash0-storage,auto-read-only=true,discard=unmap \
-blockdev node-name=libvirt-pflash0-format,read-only=true,driver=raw,file=libvirt-pflash0-storage \
-blockdev driver=file,filename=/var/lib/libvirt/qemu/nvram/Win11VM_VARS.fd,node-name=libvirt-pflash1-storage,auto-read-only=true,discard=unmap \
-blockdev node-name=libvirt-pflash1-format,read-only=false,driver=raw,file=libvirt-pflash1-storage \
-machine pc-q35-7.0,usb=off,vmport=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format \
-accel kvm \
-cpu EPYC-Milan,x2apic=on,tsc-deadline=on,hypervisor=on,tsc-adjust=on,vaes=on,vpclmulqdq=on,spec-ctrl=on,stibp=on,arch-capabilities=on,ssbd=on,cmp-legacy=on,virt-ssbd=on,rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on,pcid=off,kvmclock=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x1fff \
-global driver=cfi.pflash01,property=secure,value=on \
-m 4096 \
-object qom-type=memory-backend-ram,id=pc.ram,size=4294967296 \
-overcommit mem-lock=off \
-smp 4,sockets=1,dies=1,cores=4,threads=1 \
-uuid 00000000-0000-0000-0000-000000000000 \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain--1-Win11VM/monitor.sock,server=on,wait=off \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=localtime \
-no-shutdown \
-global ICH9-LPC.disable_s3=1 \
-global ICH9-LPC.disable_s4=1 \
-boot strict=on \
-device driver=pcie-root-port,port=16,chassis=1,id=pci.1,bus=pcie.0,multifunction=true,addr=0x2 \
-device driver=pcie-root-port,port=17,chassis=2,id=pci.2,bus=pcie.0,addr=0x2.0x1 \
-device driver=pcie-root-port,port=18,chassis=3,id=pci.3,bus=pcie.0,addr=0x2.0x2 \
-device driver=pcie-root-port,port=19,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x3 \
-device driver=pcie-root-port,port=20,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x4 \
-device driver=pcie-root-port,port=21,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x5 \
-device driver=pcie-root-port,port=22,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x6 \
-device driver=pcie-root-port,port=23,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x7 \
-device driver=pcie-root-port,port=24,chassis=9,id=pci.9,bus=pcie.0,multifunction=true,addr=0x3 \
-device driver=pcie-root-port,port=25,chassis=10,id=pci.10,bus=pcie.0,addr=0x3.0x1 \
-device driver=pcie-root-port,port=26,chassis=11,id=pci.11,bus=pcie.0,addr=0x3.0x2 \
-device driver=pcie-root-port,port=27,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x3 \
-device driver=pcie-root-port,port=28,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x4 \
-device driver=pcie-root-port,port=29,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x5 \
-device driver=qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 \
-device driver=virtio-serial-pci,id=virtio-serial0,bus=pci.3,addr=0x0 \
-blockdev driver=file,filename=/data/VM_images/VM_IMG_Win11VM_libvirt.img,node-name=libvirt-1-storage,cache.direct=true,cache.no-flush=false,auto-read-only=true,discard=unmap \
-blockdev node-name=libvirt-1-format,read-only=false,cache.direct=true,cache.no-flush=false,driver=qcow2,file=libvirt-1-storage \
-device driver=virtio-blk-pci,bus=pci.4,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=1,write-cache=on \
-netdev tap,fd=23,vhost=on,vhostfd=31,id=hostnet0 \
-device driver=virtio-net-pci,netdev=hostnet0,id=net0,mac=00:00:00:00:00:01,bus=pci.1,addr=0x0 \
-chardev pty,id=charserial0 \
-device driver=isa-serial,chardev=charserial0,id=serial0,index=0 \
-chardev spicevmc,id=charchannel0,name=vdagent \
-device driver=virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0 \
-chardev null,id=chrtpm \
-tpmdev emulator,id=tpm-tpm0,chardev=chrtpm \
-device driver=tpm-tis,tpmdev=tpm-tpm0,id=tpm0 \
-device driver=usb-tablet,id=input0,bus=usb.0,port=1 \
-audiodev id=audio1,driver=spice \
-spice port=5920,addr=0.0.0.0,disable-ticketing=on,plaintext-channel=default,image-compression=auto_glz,streaming-video=filter,seamless-migration=on \
-device driver=qxl-vga,id=video0,max_outputs=1,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,bus=pcie.0,addr=0x1 \
-device driver=ich9-intel-hda,id=sound0,bus=pcie.0,addr=0x1b \
-device driver=hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0,audiodev=audio1 \
-chardev spicevmc,id=charredir0,name=usbredir \
-device driver=usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 \
-chardev spicevmc,id=charredir1,name=usbredir \
-device driver=usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 \
-device driver=virtio-balloon-pci,id=balloon0,bus=pci.5,addr=0x0 \
-object qom-type=rng-random,id=objrng0,filename=/dev/urandom \
-device driver=virtio-rng-pci,iommu_platform=true,rng=objrng0,id=rng0,bus=pci.6,addr=0x0 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on
作成時は、これをもとのQemuオプションと比較しながら、似たようなオプションになるように対応づけていった。下記では行番号ごとに対比している(間違っているかも)。相方がない行は、対応する設定がないもの。Qemuの設定でAHCIを読み込ませているが、そのあとahci.busを使っていないので、実際には使っていなかったと思われる。
Qemuのオプション | libvirtのオプション |
---|---|
|
|
0 件のコメント:
コメントを投稿