Initial commit.
This commit is contained in:
commit
260f0a3cb4
7 changed files with 524 additions and 0 deletions
7
Makefile
Normal file
7
Makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
SRCS := qemu-vm qemu-vm-*
|
||||||
|
TARGET ?= /usr/local
|
||||||
|
|
||||||
|
install: $(SRCS)
|
||||||
|
install -Dm 0755 --owner=root --group=root -t $(TARGET)/bin $(SRCS)
|
||||||
|
|
||||||
|
.PHONY: install
|
118
qemu-vm
Executable file
118
qemu-vm
Executable file
|
@ -0,0 +1,118 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
SUDO=sudo
|
||||||
|
$SUDO true
|
||||||
|
|
||||||
|
if [[ -z "$VMNAME" ]]; then
|
||||||
|
echo "VMNAME not specified, aborting" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
# create config directory
|
||||||
|
_="${XDG_CONFIG_HOME:=$HOME/.config}"
|
||||||
|
CONFIG_PATH="$XDG_CONFIG_HOME/qemu-vm"
|
||||||
|
CONFIG_PATH_ARGUMENTS="$CONFIG_PATH/arguments.d"
|
||||||
|
CONFIG_PATH_ARGUMENTS_SPECIFIC="$CONFIG_PATH/$VMNAME/arguments.d"
|
||||||
|
|
||||||
|
# load config
|
||||||
|
[[ -e "$CONFIG_PATH/config.conf" ]] && source "$CONFIG_PATH/config.conf"
|
||||||
|
[[ -e "$CONFIG_PATH/config-$VMNAME.conf" ]] && source "$CONFIG_PATH/config-$VMNAME.conf"
|
||||||
|
|
||||||
|
[[ -e "$CONFIG_PATH/pre-config" ]] && SUDO="$SUDO" "$CONFIG_PATH/pre-config"
|
||||||
|
[[ -e "$CONFIG_PATH/pre-config-$VMNAME" ]] && SUDO="$SUDO" "$CONFIG_PATH/pre-config-$VMNAME"
|
||||||
|
|
||||||
|
# efi variables
|
||||||
|
EFI_FIRMWARE=/usr/share/ovmf/x64/OVMF_CODE.secboot.fd
|
||||||
|
EFI_VARS="$($SUDO mktemp)"
|
||||||
|
$SUDO cp /usr/share/ovmf/x64/OVMF_VARS.fd "$EFI_VARS"
|
||||||
|
|
||||||
|
# setup network
|
||||||
|
NET_CONF_FILE="$($SUDO mktemp)"
|
||||||
|
NET_CONF_FILE="$NET_CONF_FILE" "$SUDO" --preserve-env=PATH,NET_CONF_FILE qemu-vm-net create || true
|
||||||
|
|
||||||
|
# rebind devices
|
||||||
|
old_IFS="$IFS"
|
||||||
|
IFS=$'\n'
|
||||||
|
for device_override in $(< "$CONFIG_PATH/vfio-devices.txt") $(< "$CONFIG_PATH/vfio-devices-$VMNAME.txt"); do
|
||||||
|
device="$(echo "$device_override" | awk '{print $1}')"
|
||||||
|
override="$(echo "$device_override" | awk '{print $2}')"
|
||||||
|
[[ "$override" != 'true' ]] && continue
|
||||||
|
$SUDO --preserve-env=SUDO,PATH qemu-vm-pci vfio_override_device "$device"
|
||||||
|
done
|
||||||
|
$SUDO modprobe vfio-pci
|
||||||
|
for device_override in $(< "$CONFIG_PATH/vfio-devices.txt") $(< "$CONFIG_PATH/vfio-devices-$VMNAME.txt"); do
|
||||||
|
device="$(echo "$device_override" | awk '{print $1}')"
|
||||||
|
override="$(echo "$device_override" | awk '{print $2}')"
|
||||||
|
$SUDO --preserve-env=SUDO,PATH qemu-vm-pci vfio_rebind_device "$device" "$override"
|
||||||
|
done
|
||||||
|
IFS="$old_IFS"
|
||||||
|
|
||||||
|
# memory backend
|
||||||
|
MEM_PATH="$(SUDO="$SUDO" qemu-vm-mem init "$NUM_MEM")"
|
||||||
|
|
||||||
|
# generate arguments
|
||||||
|
t="$(mktemp -d)"
|
||||||
|
for f in "$CONFIG_PATH_ARGUMENTS/"*.sh "$CONFIG_PATH_ARGUMENTS_SPECIFIC/"*.sh; do
|
||||||
|
(
|
||||||
|
export SUDO="$SUDO"
|
||||||
|
export MEM_PATH="$MEM_PATH"
|
||||||
|
source "$f"
|
||||||
|
newfile="$(basename "$f" .sh)"
|
||||||
|
envsubst < "${f%.sh}" > "$t/$newfile"
|
||||||
|
)
|
||||||
|
done
|
||||||
|
for f in "$CONFIG_PATH_ARGUMENTS/"*.conf "$CONFIG_PATH_ARGUMENTS_SPECIFIC/"*.conf; do
|
||||||
|
[[ -e "$f.sh" ]] && continue
|
||||||
|
cp "$f" "$t/"
|
||||||
|
done
|
||||||
|
|
||||||
|
qemu_arguments=()
|
||||||
|
for f in "$t/"*.conf; do
|
||||||
|
read -ra _qemu_arguments -d '' < "$f" || true
|
||||||
|
qemu_arguments+=("${_qemu_arguments[@]}")
|
||||||
|
done
|
||||||
|
unset _qemu_arguments
|
||||||
|
|
||||||
|
|
||||||
|
# pre-run callbacks
|
||||||
|
[[ -e "$CONFIG_PATH/pre-run" ]] && SUDO="$SUDO" "$CONFIG_PATH/pre-run"
|
||||||
|
[[ -e "$CONFIG_PATH/pre-run-$VMNAME" ]] && SUDO="$SUDO" "$CONFIG_PATH/pre-run-$VMNAME"
|
||||||
|
|
||||||
|
# run and set affinity
|
||||||
|
set -x
|
||||||
|
$SUDO qemu-system-$(uname -m) \
|
||||||
|
-name "$VMNAME,process=$VMNAME,debug-threads=on" \
|
||||||
|
-monitor unix:"$MONITOR",server,nowait \
|
||||||
|
-drive if=pflash,format=raw,readonly=on,file="$EFI_FIRMWARE" \
|
||||||
|
-drive if=pflash,format=raw,file="$EFI_VARS" \
|
||||||
|
"${qemu_arguments[@]}" &
|
||||||
|
qemu_pid="$!"
|
||||||
|
set +x
|
||||||
|
while :; do
|
||||||
|
_l="$(ps --ppid "$qemu_pid" | tail -n+2 || true)"
|
||||||
|
if [ "$_l" = '' ]; then
|
||||||
|
echo waiting
|
||||||
|
sleep .1
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
qemu_pid="$(awk '{print $1}' <<< "$_l")"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
$SUDO qemu-affinity \
|
||||||
|
-k $(qemu-vm-cpus decompress_seq "$(qemu-vm-cpus compute_vm $NUM_PROCESSORS)") \
|
||||||
|
-i *:$(qemu-vm-cpus compute_vm $NUM_PROCESSORS) \
|
||||||
|
-- $qemu_pid
|
||||||
|
|
||||||
|
echo 'Startup complete'
|
||||||
|
tail --pid="$qemu_pid" -f /dev/null
|
||||||
|
echo 'Stop stopped'
|
||||||
|
|
||||||
|
SUDO="$SUDO" qemu-vm-mem restore "$MEM_PATH"
|
||||||
|
NET_CONF_FILE="$NET_CONF_FILE" $SUDO --preserve-env=PATH,NET_CONF_FILE qemu-vm-net delete
|
||||||
|
|
||||||
|
[[ -e "$CONFIG_PATH/post-run" ]] && SUDO="$SUDO" "$CONFIG_PATH/post-run"
|
||||||
|
[[ -e "$CONFIG_PATH/post-run-$VMNAME" ]] && SUDO="$SUDO" "$CONFIG_PATH/post-run-$VMNAME"
|
117
qemu-vm-cpus
Executable file
117
qemu-vm-cpus
Executable file
|
@ -0,0 +1,117 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
all_processors() {
|
||||||
|
grep -E '(processor|core id)' /proc/cpuinfo | while : ; do
|
||||||
|
read -r line0 || break
|
||||||
|
read -r line1 || break
|
||||||
|
if echo "$line0" | grep -q 'processor'; then
|
||||||
|
processor="$(echo "$line0" | sed -En 's/^[^0-9]*([0-9]+)$/\1/p')"
|
||||||
|
core="$(echo "$line1" | sed -En 's/^[^0-9]*([0-9]+)$/\1/p')"
|
||||||
|
elif echo "$line1" | grep -q 'processor'; then
|
||||||
|
processor="$(echo "$line1" | sed -En 's/^[^0-9]*([0-9]+)$/\1/p')"
|
||||||
|
core="$(echo "$line0" | sed -En 's/^[^0-9]*([0-9]+)$/\1/p')"
|
||||||
|
fi
|
||||||
|
echo "$processor $core"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
take_host_processors() {
|
||||||
|
all_processors | sort -hk2 | head -n$1
|
||||||
|
}
|
||||||
|
|
||||||
|
take_vm_processors() {
|
||||||
|
all_processors | sort -hk2 | tail -n+$(($1+1))
|
||||||
|
}
|
||||||
|
|
||||||
|
_compress_seq_sub() {
|
||||||
|
first="$(echo "$@" | awk '{print $1}')"
|
||||||
|
last="$(echo "$@" | awk '{print $NF}')"
|
||||||
|
if [ $first = $last ]; then
|
||||||
|
printf '%s,' "$first"
|
||||||
|
else
|
||||||
|
printf '%s-%s,' "$first" "$last"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_compress_seq() {
|
||||||
|
buffer=
|
||||||
|
while read -r item; do
|
||||||
|
if [ -z "$buffer" ]; then
|
||||||
|
buffer=$item
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [ $(($(echo "$buffer" | awk '{print $NF}')+1)) -eq $item ]; then
|
||||||
|
buffer="$buffer $item"
|
||||||
|
else
|
||||||
|
_compress_seq_sub $buffer
|
||||||
|
buffer=$item
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
_compress_seq_sub $buffer
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
compress_seq() {
|
||||||
|
_compress_seq | rev | cut -c2- | rev
|
||||||
|
}
|
||||||
|
|
||||||
|
_decompress_seq() {
|
||||||
|
(
|
||||||
|
IFS=,
|
||||||
|
for item in $@; do
|
||||||
|
if echo "$item" | grep -q '-'; then
|
||||||
|
num0="$(echo "$item" | awk -F- '{print $1}')"
|
||||||
|
num1="$(echo "$item" | awk -F- '{print $2}')"
|
||||||
|
printf '%s ' "$(seq $num0 $num1 | xargs echo)"
|
||||||
|
else
|
||||||
|
printf '%s ' $item
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
decompress_seq() {
|
||||||
|
_decompress_seq "$1" | rev | cut -c2- | rev
|
||||||
|
}
|
||||||
|
|
||||||
|
check_argument_is_number() {
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "Error: must specify number of processors" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ "$1" -eq "$1" ] 2>/dev/null; then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
echo "Error: provided argument '$1' is not a number" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
compute_all() {
|
||||||
|
all_processors | sort -hk1 | awk '{print $1}' | compress_seq
|
||||||
|
}
|
||||||
|
|
||||||
|
compute_host() {
|
||||||
|
if ! check_argument_is_number $1; then
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
take_host_processors $1 | sort -hk1 | awk '{print $1}' | \
|
||||||
|
compress_seq
|
||||||
|
}
|
||||||
|
|
||||||
|
compute_vm() {
|
||||||
|
if ! check_argument_is_number $1; then
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
take_vm_processors $1 | sort -hk1 | awk '{print $1}' | \
|
||||||
|
compress_seq
|
||||||
|
}
|
||||||
|
|
||||||
|
processors_per_core() {
|
||||||
|
processor_count=$(all_processors | awk '{print $1}' | sort -h | uniq | wc -l)
|
||||||
|
core_count=$(all_processors | awk '{print $2}' | sort -h | uniq | wc -l)
|
||||||
|
echo $((processor_count/core_count))
|
||||||
|
}
|
||||||
|
|
||||||
|
"$@"
|
19
qemu-vm-mem
Executable file
19
qemu-vm-mem
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
HUGEPAGES_PATH=/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
|
||||||
|
|
||||||
|
init() {
|
||||||
|
echo "$1" | $SUDO tee "$HUGEPAGES_PATH" >/dev/null
|
||||||
|
d="$($SUDO mktemp -d)"
|
||||||
|
$SUDO mount -t hugetlbfs -o pagesize=1024M hugetlbfs "$d"
|
||||||
|
echo "$d"
|
||||||
|
}
|
||||||
|
|
||||||
|
restore() {
|
||||||
|
$SUDO umount "$1"
|
||||||
|
echo 0 | $SUDO tee "$HUGEPAGES_PATH" >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
"$@"
|
225
qemu-vm-net
Executable file
225
qemu-vm-net
Executable file
|
@ -0,0 +1,225 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE_BRIDGE_NAME=br-q
|
||||||
|
BASE_TAP_NAME=tap-q
|
||||||
|
|
||||||
|
randstr() {
|
||||||
|
dd if=/dev/urandom count=1 bs=3 2>/dev/null | xxd -p -g 0
|
||||||
|
}
|
||||||
|
|
||||||
|
default_route() {
|
||||||
|
ip route | awk '/^default/ && (NR==1) {print $5}'
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
nft_rev() {
|
||||||
|
local family
|
||||||
|
local table
|
||||||
|
local chain
|
||||||
|
local protocol
|
||||||
|
local field
|
||||||
|
local port
|
||||||
|
local policy
|
||||||
|
|
||||||
|
local filter
|
||||||
|
local remove
|
||||||
|
|
||||||
|
source "$NET_CONF_FILE"
|
||||||
|
|
||||||
|
family="$3"
|
||||||
|
table="$4"
|
||||||
|
chain="$5"
|
||||||
|
if [[ "$chain" = 'input' ]]; then
|
||||||
|
protocol="$6"
|
||||||
|
field="$7"
|
||||||
|
port="$8"
|
||||||
|
policy="$9"
|
||||||
|
|
||||||
|
filter="
|
||||||
|
.nftables[] | select(.rule) | .rule
|
||||||
|
| select(.family|test(\"$family\"))
|
||||||
|
| select(.table|test(\"$table\"))
|
||||||
|
| select(.chain|test(\"$chain\"))
|
||||||
|
| select(.expr[0]?.match?.op)
|
||||||
|
| select(.expr[0]?.match?.left?.payload?.protocol)
|
||||||
|
| select(.expr[0]?.match?.left?.payload?.field)
|
||||||
|
| select(.expr[0]?.match?.right)
|
||||||
|
| select(.expr[1]?.$policy == null)
|
||||||
|
| select(.expr[0].match.op == \"==\")
|
||||||
|
| select(.expr[0].match.left.payload.protocol == \"$protocol\")
|
||||||
|
| select(.expr[0].match.left.payload.field == \"$field\")
|
||||||
|
| select(.expr[0].match.right == $port)
|
||||||
|
| .handle
|
||||||
|
"
|
||||||
|
remove="
|
||||||
|
echo nft delete rule $table $chain handle \$handle
|
||||||
|
nft delete rule $table $chain handle \$handle
|
||||||
|
"
|
||||||
|
elif [[ "$chain" = 'forward' ]]; then
|
||||||
|
key="$6"
|
||||||
|
ifname="$7"
|
||||||
|
policy="${13}"
|
||||||
|
|
||||||
|
filter="
|
||||||
|
.nftables[] | select(.rule) | .rule
|
||||||
|
| select(.family|test(\"$family\"))
|
||||||
|
| select(.table|test(\"$table\"))
|
||||||
|
| select(.chain|test(\"$chain\"))
|
||||||
|
| select(.expr[0]?.match?.op)
|
||||||
|
| select(.expr[0]?.match?.left?.meta?.key)
|
||||||
|
| select(.expr[0]?.match?.right)
|
||||||
|
| select(.expr[2]?.$policy == null)
|
||||||
|
| select(.expr[0].match.op == \"==\")
|
||||||
|
| select(.expr[0].match.left.meta.key == \"$key\")
|
||||||
|
| select(.expr[0].match.right == \"$ifname\")
|
||||||
|
| .handle
|
||||||
|
"
|
||||||
|
remove="
|
||||||
|
echo nft delete rule $table $chain handle \$handle
|
||||||
|
nft delete rule $table $chain handle \$handle
|
||||||
|
"
|
||||||
|
else
|
||||||
|
echo "Warning: Don't know how to reverse 'nft $@'" 1>&2
|
||||||
|
nft "$@"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
set +u
|
||||||
|
if [[ -z "$restore_nft_file" ]]; then
|
||||||
|
restore_nft_file="$(mktemp)"
|
||||||
|
echo "#!/usr/bin/env sh" > "$restore_nft_file"
|
||||||
|
chmod 700 "$restore_nft_file"
|
||||||
|
chown root:root "$restore_nft_file"
|
||||||
|
echo "restore_nft_file=$restore_nft_file" >> "$NET_CONF_FILE"
|
||||||
|
fi
|
||||||
|
set -u
|
||||||
|
|
||||||
|
echo "handle=\"\$(nft --json list ruleset | jq '$filter')\"" >> "$restore_nft_file"
|
||||||
|
echo "$remove" >> "$restore_nft_file"
|
||||||
|
cat "$restore_nft_file"
|
||||||
|
|
||||||
|
nft "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get_bridge_name() {
|
||||||
|
for i in {1..255}; do
|
||||||
|
br_name="br$i"
|
||||||
|
link_names="$(ip link list | awk -F:\ '/^[0-9]+: br.*/ {print $2}')"
|
||||||
|
if [[ -z "$link_names" ]] || echo "$link_names" | grep -vq "$br_name"; then
|
||||||
|
echo "$br_name"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get_tap_name() {
|
||||||
|
for i in {1..255}; do
|
||||||
|
tap_name="tap$i"
|
||||||
|
link_names="$(ip link list | awk -F:\ '/^[0-9]+: tap.*/ {print $2}')"
|
||||||
|
if [[ -z "$link_names" ]] || echo "$link_names" | grep -vq "$tap_name"; then
|
||||||
|
echo "$tap_name"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
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/24"
|
||||||
|
dhcp_range="$next_subnet.0.100,$next_subnet.0.200"
|
||||||
|
|
||||||
|
bridge_name="$(get_bridge_name)"
|
||||||
|
tap_name="$(get_tap_name)"
|
||||||
|
echo "$bridge_name"
|
||||||
|
echo "$tap_name"
|
||||||
|
|
||||||
|
echo > "$NET_CONF_FILE"
|
||||||
|
|
||||||
|
set -x
|
||||||
|
modprobe tun tap
|
||||||
|
ip link add "$bridge_name" type bridge && sleep .1
|
||||||
|
ip tuntap add dev "$tap_name" mode tap && sleep .1
|
||||||
|
ip link set dev "$tap_name" master "$bridge_name" && sleep .1
|
||||||
|
ip link set dev "$bridge_name" up && sleep .1
|
||||||
|
ip link set dev "$tap_name" up && sleep .1
|
||||||
|
ip addr add "$dhcp_subnet" dev "$bridge_name" && sleep .1
|
||||||
|
ip link set dev "$bridge_name" up && sleep .1
|
||||||
|
ip link set dev "$tap_name" up && sleep .1
|
||||||
|
set +x
|
||||||
|
ip addr
|
||||||
|
dnsmasq -d --interface="$bridge_name" --bind-interface --dhcp-range="$dhcp_range" &
|
||||||
|
dnsmasq_pid="$!"
|
||||||
|
echo "bridge_name='$bridge_name'" >> "$NET_CONF_FILE"
|
||||||
|
echo "tap_name='$tap_name'" >> "$NET_CONF_FILE"
|
||||||
|
echo "dnsmasq_pid='$dnsmasq_pid'" >> "$NET_CONF_FILE"
|
||||||
|
disown -h "$dnsmasq_pid"
|
||||||
|
|
||||||
|
echo "nft_ruleset='$(nft -s list ruleset)'" >> "$NET_CONF_FILE"
|
||||||
|
|
||||||
|
# dhcp
|
||||||
|
nft_rev add rule ip filter input udp dport 67 accept
|
||||||
|
nft_rev add rule ip filter input tcp dport 67 accept
|
||||||
|
# dns
|
||||||
|
nft_rev add rule ip filter input udp dport 53 accept
|
||||||
|
nft_rev add rule ip filter input tcp dport 53 accept
|
||||||
|
# scream
|
||||||
|
nft_rev add rule ip filter input udp dport 4010 accept
|
||||||
|
nft_rev add rule ip filter input tcp dport 4010 accept
|
||||||
|
|
||||||
|
# forward bridge
|
||||||
|
nft_rev add rule ip filter forward iifname "$bridge_name" \
|
||||||
|
counter packets 0 bytes 0 accept
|
||||||
|
nft_rev add rule ip filter forward oifname "$bridge_name" \
|
||||||
|
counter packets 0 bytes 0 accept
|
||||||
|
nft_rev 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"
|
||||||
|
"$restore_nft_file"
|
||||||
|
rm "$restore_nft_file"
|
||||||
|
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
|
||||||
|
|
||||||
|
"$@"
|
34
qemu-vm-pci
Executable file
34
qemu-vm-pci
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE_PATH=/sys/bus/pci/
|
||||||
|
|
||||||
|
# sanitize variables
|
||||||
|
if [[ "${BASE_PATH: -1}" = '/' ]]; then
|
||||||
|
BASE_PATH="${BASE_PATH::${#BASE_PATH}-1}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
_="${SUDO:=sudo}"
|
||||||
|
|
||||||
|
vfio_override_device() {
|
||||||
|
local pci_id
|
||||||
|
pci_id="$1"
|
||||||
|
if [[ -e "$BASE_PATH/devices/$pci_id" ]]; then
|
||||||
|
echo "vfio-pci" | $SUDO tee \
|
||||||
|
"$BASE_PATH/devices/$pci_id/driver_override" > /dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
vfio_rebind_device() {
|
||||||
|
local pci_id
|
||||||
|
pci_id="$1"
|
||||||
|
if [[ -e "$BASE_PATH/devices/$pci_id" ]]; then
|
||||||
|
[[ -e "$BASE_PATH/devices/$pci_id/driver/unbind" ]] \
|
||||||
|
&& echo "$pci_id" | $SUDO tee \
|
||||||
|
"$BASE_PATH/devices/$pci_id/driver/unbind" >/dev/null
|
||||||
|
echo "$pci_id" | $SUDO tee \
|
||||||
|
"$BASE_PATH/drivers/vfio-pci/bind" > /dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
"$@"
|
4
requirements.txt
Normal file
4
requirements.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
qemu-full
|
||||||
|
qemu-affinity
|
||||||
|
swtpm
|
||||||
|
dnsmasq
|
Loading…
Add table
Reference in a new issue