You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
3.7 KiB
Bash
152 lines
3.7 KiB
Bash
#!/bin/sh
|
|
|
|
INIT_SYSTEM="runit" # systemd, openrc, runit
|
|
GPU="nvidia" # nvidia, amd
|
|
DISPLAY_MANAGER="yes" # yes, no
|
|
WINDOW_MANAGER="niri" # required if not using display manager
|
|
START_WINDOW_MANAGER="dbus-run-session niri --session" # not sure if this works
|
|
GPU_PCI="pci_0000_01_00_0"
|
|
GPU_AUDIO_PCI="pci_0000_01_00_1"
|
|
VM_NAME="win10" # name of VM set during creation
|
|
|
|
mkdir -pv tmp
|
|
|
|
sudo_cmd="sudo"
|
|
if command -v doas >/dev/null; then
|
|
sudo_cmd="doas"
|
|
fi
|
|
|
|
start_service() {
|
|
case $INIT_SYSTEM in
|
|
"systemd") echo "systemctl start $1";;
|
|
"openrc") echo "rc-service $1 start";;
|
|
"runit") echo "sv up $1";;
|
|
esac
|
|
}
|
|
|
|
stop_service() {
|
|
case $INIT_SYSTEM in
|
|
"systemd") echo "systemctl stop $1";;
|
|
"openrc") echo "openrc $1 stop";;
|
|
"runit") echo "sv down $1";;
|
|
esac
|
|
}
|
|
|
|
cat > ./tmp/qemu_hook<< "EOF"
|
|
#!/bin/bash
|
|
|
|
GUEST_NAME="$1"
|
|
HOOK_NAME="$2"
|
|
STATE_NAME="$3"
|
|
MISC="${@:4}"
|
|
|
|
BASEDIR="$(dirname $0)"
|
|
|
|
HOOKPATH="$BASEDIR/qemu.d/$GUEST_NAME/$HOOK_NAME/$STATE_NAME"
|
|
set -e # If a script exits with an error, we should as well.
|
|
|
|
if [ -f "$HOOKPATH" ]; then
|
|
eval \""$HOOKPATH"\" "$@"
|
|
elif [ -d "$HOOKPATH" ]; then
|
|
while read file; do
|
|
eval \""$file"\" "$@"
|
|
done <<< "$(find -L "$HOOKPATH" -maxdepth 1 -type f -executable -print;)"
|
|
fi
|
|
EOF
|
|
|
|
if [ "$DISPLAY_MANAGER" = "yes" ]; then
|
|
# TODO: use service provided by package if display-manager is not valid service
|
|
dm_start=$(start_service "display-manager")
|
|
dm_stop=$(stop_service "display-manager")
|
|
|
|
if [ "$INIT_SYSTEM" = "systemd" ]; then
|
|
plasma_stop="systemctl --user -M $USER@ stop plasma"
|
|
fi
|
|
else
|
|
dm_stop="pkill -x $WINDOW_MANAGER"
|
|
dm_start="su -l $USER -c $START_WINDOW_MANAGER"
|
|
fi
|
|
|
|
if [ "$GPU" = "amd" ]; then
|
|
gpu_modules="amdgpu"
|
|
elif [ "$GPU" = "nvidia" ]; then
|
|
gpu_modules="nvidia_drm nvidia_modeset nvidia_uvm nvidia"
|
|
fi
|
|
|
|
cat > ./tmp/libvirt_hook_start.sh<< EOF
|
|
#!/bin/bash
|
|
set -x
|
|
|
|
$dm_stop
|
|
$plasma_stop
|
|
|
|
# Unbind VTconsoles
|
|
echo 0 > /sys/class/vtconsole/vtcon0/bind
|
|
echo 0 > /sys/class/vtconsole/vtcon1/bind
|
|
|
|
# Unbind EFI Framebuffer
|
|
echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind
|
|
|
|
modprobe -r $gpu_modules
|
|
|
|
virsh nodedev-detach $GPU_PCI
|
|
virsh nodedev-detach $GPU_AUDIO_PCI
|
|
|
|
modprobe vfio-pci
|
|
EOF
|
|
|
|
cat > ./tmp/libvirt_hook_stop.sh<< EOF
|
|
#!/bin/bash
|
|
set -x
|
|
|
|
# Attach GPU devices to host
|
|
virsh nodedev-reattach $GPU_PCI
|
|
virsh nodedev-reattach $GPU_AUDIO_PCI
|
|
|
|
# Unload vfio module
|
|
modprobe -r vfio-pci
|
|
|
|
# Rebind framebuffer to host
|
|
echo "efi-framebuffer.0" > /sys/bus/platform/drivers/efi-framebuffer/bind
|
|
|
|
# Load NVIDIA kernel modules
|
|
$(for module in $gpu_modules; do
|
|
echo "modprobe $module"
|
|
done)
|
|
|
|
# Bind VTconsoles
|
|
echo 1 > /sys/class/vtconsole/vtcon0/bind
|
|
echo 1 > /sys/class/vtconsole/vtcon1/bind
|
|
|
|
$dm_start
|
|
EOF
|
|
|
|
get_yes_no_input() {
|
|
while true; do
|
|
echo -n "$1 (yes/no): "
|
|
read yn
|
|
case $yn in
|
|
[Yy]* ) return 0;;
|
|
[Nn]* ) return 1;;
|
|
* ) echo "Please answer yes or no.";;
|
|
esac
|
|
done
|
|
}
|
|
|
|
chmod +x -v tmp/qemu_hook
|
|
chmod +x -v tmp/libvirt_hook_start.sh
|
|
chmod +x -v tmp/libvirt_hook_stop.sh
|
|
|
|
if get_yes_no_input "Want me to copy hooks files?"; then
|
|
$sudo_cmd mkdir -pv /etc/libvirt/hooks
|
|
$sudo_cmd mkdir -pv /etc/libvirt/hooks/qemu.d/$VM_NAME/prepare/begin
|
|
$sudo_cmd mkdir -pv /etc/libvirt/hooks/qemu.d/$VM_NAME/release/end
|
|
|
|
$sudo_cmd cp -v --preserve ./tmp/qemu_hook /etc/libvirt/hooks/qemu
|
|
$sudo_cmd cp -v --preserve ./tmp/libvirt_hook_start.sh /etc/libvirt/hooks/qemu.d/$VM_NAME/prepare/begin/start.sh
|
|
$sudo_cmd cp -v --preserve ./tmp/libvirt_hook_stop.sh /etc/libvirt/hooks/qemu.d/$VM_NAME/release/end/stop.sh
|
|
echo "\033[1;32m✓ DONE \033[0m"
|
|
else
|
|
echo "\033[1;32m✓ You can manually copy hooks from tmp directory.\033[0m"
|
|
fi
|