Add another launch option compatible with multiple vms.
This commit is contained in:
parent
76419c8eaf
commit
1927a6597a
13 changed files with 282 additions and 0 deletions
26
.editorconfig
Normal file
26
.editorconfig
Normal file
|
@ -0,0 +1,26 @@
|
|||
root = true
|
||||
|
||||
[**]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 72
|
||||
|
||||
[{**.c}]
|
||||
indent_size = 8
|
||||
|
||||
[{Makefile,makefile,**.mk,makefile**,Makefile**}]
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
|
||||
[{**.py,**.rb,**.bash,**.sh,**.ksh}]
|
||||
indent_size = 4
|
||||
|
||||
[{**.css}]
|
||||
indent_size = 2
|
||||
|
||||
[{**.json,**.yaml,**.Dockerfile}]
|
||||
indent_size = 2
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,2 +1,6 @@
|
|||
*.iso
|
||||
*.rom
|
||||
default.conf
|
||||
base.conf
|
||||
hardware.conf
|
||||
win10.conf
|
||||
|
|
12
base.conf.tmpl
Normal file
12
base.conf.tmpl
Normal file
|
@ -0,0 +1,12 @@
|
|||
-boot order=dc
|
||||
-machine type=q35,accel=kvm,kernel_irqchip=on
|
||||
-smp 10,sockets=1,cores=5,threads=2
|
||||
-enable-kvm
|
||||
-cpu host,kvm=on,topoext,tsc_deadline,tsc_adjust,l3-cache,hv_vendor_id=null,hv_vpindex,hv_runtime,hv_synic,hv_stimer,hv_reset,hv_frequencies,hv_tlbflush,hv_reenlightenment,hv_ipi,hv_time,hv_relaxed,hv_vapic,hv_spinlocks=0x1fff
|
||||
-m 12G
|
||||
-mem-prealloc -mem-path /dev/hugepages
|
||||
-vga none -nographic
|
||||
-parallel none
|
||||
-serial none
|
||||
-rtc clock=host,base=localtime,driftfix=none
|
||||
-usb
|
4
default.conf.tmpl
Normal file
4
default.conf.tmpl
Normal file
|
@ -0,0 +1,4 @@
|
|||
-netdev tap,id=net0,br=$BR_NAME,ifname=$TAP_NAME,script=no,downscript=no
|
||||
-device e1000,netdev=net0
|
||||
-audiodev pa,id=snd0,server=unix:/run/user/$MYUID/pulse/native
|
||||
-device intel-hda -device hda-duplex,audiodev=snd0
|
6
default.sh
Executable file
6
default.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source <(sudo cat "$NET_CONF_FILE")
|
||||
export BR_NAME="$bridge_name"
|
||||
export TAP_NAME="$tap_name"
|
||||
export MYUID="$(id -u)"
|
6
hardware.conf.tmpl
Normal file
6
hardware.conf.tmpl
Normal file
|
@ -0,0 +1,6 @@
|
|||
-device usb-host,hostbus=1,hostport=6.1
|
||||
-device usb-host,hostbus=1,hostport=6.2
|
||||
-device usb-host,hostbus=1,hostport=6.3
|
||||
-device usb-host,hostbus=1,hostport=6.4
|
||||
-device vfio-pci,host=$GPU_ID,multifunction=on,id=gpu,romfile=$GPU_ROM
|
||||
-device vfio-pci,host=$AUDIO_ID,id=audio
|
6
hardware.sh
Executable file
6
hardware.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
export GPU_ROM=/opt/vm/1080ti_asus.rom
|
||||
export GPU_ID='0000:65:00.0'
|
||||
export AUDIO_ID='0000:65:00.1'
|
||||
|
101
net
Executable file
101
net
Executable file
|
@ -0,0 +1,101 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE_BRIDGE_NAME=br-q
|
||||
BASE_TAP_NAME=tap-q
|
||||
|
||||
randstr() {
|
||||
dd if=/dev/urandom count=1 bs=4 | xxd -p -g 0
|
||||
}
|
||||
|
||||
default_route() {
|
||||
ip route | grep '^default' | sed -n 's/.*dev \([^ ]*\).*/\1/p'
|
||||
}
|
||||
|
||||
find_next_subnet() {
|
||||
local i
|
||||
for i in {20..254}; do
|
||||
if ip route | grep -q "^172\.$i\."; then
|
||||
true
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo "172.$i"
|
||||
}
|
||||
|
||||
create() {
|
||||
local next_subnet
|
||||
|
||||
local bridge_name
|
||||
local dhcp_subnet
|
||||
local dhcp_range
|
||||
local tap_name
|
||||
local dnsmasq_pid
|
||||
|
||||
next_subnet="$(find_next_subnet)"
|
||||
dhcp_subnet="$next_subnet.0.1/16"
|
||||
dhcp_range="$next_subnet.0.2,$next_subnet.255.254"
|
||||
|
||||
bridge_name="$BASE_BRIDGE_NAME-$(randstr)"
|
||||
tap_name="$BASE_TAP_NAME-$(randstr)"
|
||||
|
||||
echo > "$NET_CONF_FILE"
|
||||
|
||||
ip link add name "$bridge_name" type bridge
|
||||
echo "bridge_name='$bridge_name'" >> "$NET_CONF_FILE"
|
||||
ip addr add "$dhcp_subnet" dev "$bridge_name"
|
||||
ip link set dev "$bridge_name" up
|
||||
ip tuntap add "$tap_name" mode tap
|
||||
echo "tap_name='$tap_name'" >> "$NET_CONF_FILE"
|
||||
ip link set "$tap_name" up
|
||||
ip link set dev "$tap_name" master "$bridge_name"
|
||||
dnsmasq -k --interface="$bridge_name" --bind-interface \
|
||||
--dhcp-range="$dhcp_range" &
|
||||
dnsmasq_pid="$!"
|
||||
echo "dnsmasq_pid='$dnsmasq_pid'" >> "$NET_CONF_FILE"
|
||||
disown -h "$dnsmasq_pid"
|
||||
|
||||
echo "nft_ruleset='$(nft -s list ruleset)'" >> "$NET_CONF_FILE"
|
||||
|
||||
# dhcp
|
||||
nft add rule ip filter INPUT udp dport 67 accept
|
||||
nft add rule ip filter INPUT tcp dport 67 accept
|
||||
# dns
|
||||
nft add rule ip filter INPUT udp dport 53 accept
|
||||
nft add rule ip filter INPUT tcp dport 53 accept
|
||||
|
||||
# forward bridge
|
||||
nft add rule ip filter FORWARD iifname "$bridge_name" \
|
||||
counter packets 0 bytes 0 accept
|
||||
nft add rule ip filter FORWARD oifname "$bridge_name" \
|
||||
counter packets 0 bytes 0 accept
|
||||
nft add rule ip nat POSTROUTING oifname "$(default_route)" \
|
||||
counter masquerade
|
||||
}
|
||||
|
||||
delete() {
|
||||
source "$NET_CONF_FILE"
|
||||
|
||||
kill "$dnsmasq_pid"
|
||||
ip link del "$tap_name"
|
||||
ip link del "$bridge_name"
|
||||
nft flush ruleset
|
||||
nft -f - <<< "$nft_ruleset"
|
||||
rm "$NET_CONF_FILE"
|
||||
}
|
||||
|
||||
if [[ -z "$NET_CONF_FILE" ]]; then
|
||||
echo Please specify the configuration file path \
|
||||
with NET_CONF_FILE >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "EUID" -ne 0 ]]; then
|
||||
echo "Please run as root" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
"$@"
|
6
pre-start.sh
Executable file
6
pre-start.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [[ -z "$DEBUG" ]]; then
|
||||
echo efi-framebuffer.0 | sudo tee \
|
||||
'/sys/bus/platform/devices/efi-framebuffer.0/driver/unbind' || true
|
||||
fi
|
98
start
Executable file
98
start
Executable file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -eo pipefail
|
||||
|
||||
if [[ -z "$VMNAME" ]]; then
|
||||
echo "VMNAME not specified, aborting" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$DEBUG" ]]; then
|
||||
DEBUG=
|
||||
fi
|
||||
|
||||
set -u
|
||||
|
||||
SUDO=sudo
|
||||
|
||||
$SUDO true
|
||||
|
||||
NET_CONF_FILE="$(sudo mktemp)"
|
||||
|
||||
# create bridge
|
||||
NET_CONF_FILE="$NET_CONF_FILE" $DEBUG $SUDO --preserve-env=NET_CONF_FILE \
|
||||
./net create
|
||||
|
||||
# rebind devices
|
||||
for device in $(< vfio_devices.txt); do
|
||||
$DEBUG $SUDO ./pci vfio_rebind_device "$device"
|
||||
done
|
||||
|
||||
# efi variables
|
||||
EFI_VARS="$(mktemp)"
|
||||
cp /usr/share/ovmf/x64/OVMF_VARS.fd "$EFI_VARS"
|
||||
EFI_FIRMWARE=/usr/share/ovmf/x64/OVMF_CODE.fd
|
||||
|
||||
base_path=base
|
||||
default_path=default
|
||||
hardware_path=hardware
|
||||
specific_path="$VMNAME"
|
||||
if [[ -e "$base_path.conf.tmpl" ]]; then
|
||||
(
|
||||
# shellcheck disable=SC1090
|
||||
[[ -e "$base_path.sh" ]] && source "$base_path.sh"
|
||||
envsubst < "$base_path.conf.tmpl" > "$base_path.conf"
|
||||
)
|
||||
fi
|
||||
if [[ -e "$default_path.conf.tmpl" ]]; then
|
||||
(
|
||||
# shellcheck disable=SC1090
|
||||
[[ -e "$default_path.sh" ]] && source "$default_path.sh"
|
||||
envsubst < "$default_path.conf.tmpl" > "$default_path.conf"
|
||||
)
|
||||
fi
|
||||
if [[ -e "$hardware_path.conf.tmpl" ]]; then
|
||||
(
|
||||
# shellcheck disable=SC1090
|
||||
[[ -e "$hardware_path.sh" ]] && source "$hardware_path.sh"
|
||||
envsubst < "$hardware_path.conf.tmpl" > "$hardware_path.conf"
|
||||
)
|
||||
fi
|
||||
if [[ -e "$specific_path.conf.tmpl" ]]; then
|
||||
(
|
||||
# shellcheck disable=SC1090
|
||||
[[ -e "$specific_path.sh" ]] && source "$specific_path.sh"
|
||||
envsubst < "$specific_path.conf.tmpl" > "$specific_path.conf"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ -e "pre-start.sh" ]]; then
|
||||
./pre-start.sh
|
||||
fi
|
||||
|
||||
if [[ -e "pre-start-$VMNAME.sh" ]]; then
|
||||
./"pre-start-$VMNAME.sh"
|
||||
fi
|
||||
|
||||
# run qemu
|
||||
base_arguments=()
|
||||
default_arguments=()
|
||||
hardware_arguments=()
|
||||
specific_arguments=()
|
||||
# mask EOF
|
||||
read -ra base_arguments -d '' < "$base_path.conf" || true
|
||||
read -ra default_arguments -d '' < "$default_path.conf" || true
|
||||
read -ra hardware_arguments -d '' < "$hardware_path.conf" || true
|
||||
read -ra specific_arguments -d '' < "$specific_path.conf" || true
|
||||
$DEBUG $SUDO nice --adjustment=-20 taskset --cpu-list '1-5,7-11' \
|
||||
qemu-system-x86_64 \
|
||||
-name "$VMNAME,process=VMNAME" \
|
||||
-drive if=pflash,format=raw,readonly=on,file="$EFI_FIRMWARE" \
|
||||
-drive if=pflash,format=raw,file="$EFI_VARS" \
|
||||
"${base_arguments[@]}" \
|
||||
"${default_arguments[@]}" \
|
||||
"${hardware_arguments[@]}" \
|
||||
"${specific_arguments[@]}"
|
||||
|
||||
NET_CONF_FILE="$NET_CONF_FILE" $DEBUG $SUDO --preserve-env=NET_CONF_FILE \
|
||||
./net delete
|
4
vfio_devices.txt
Normal file
4
vfio_devices.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
0000:02:00.0
|
||||
0000:07:00.0
|
||||
0000:65:00.0
|
||||
0000:65:00.1
|
5
win10.conf.tmpl
Normal file
5
win10.conf.tmpl
Normal file
|
@ -0,0 +1,5 @@
|
|||
-drive file=virtio-win-0.1.185.iso,media=cdrom
|
||||
-drive file=Win10_21H1_EnglishInternational_x64.iso,media=cdrom
|
||||
-device vfio-pci,host=$SSD_ID,id=sdd
|
||||
-device vfio-pci,host=$SATA_ID,id=sata
|
||||
|
4
win10.sh
Executable file
4
win10.sh
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
export SSD_ID='0000:02:00.0'
|
||||
export SATA_ID='0000:07:00.0'
|
Loading…
Add table
Reference in a new issue