Automated setup

pull/15/head
qaidvoid 4 years ago
parent 03284e6ad7
commit 720f4b468f

@ -1,9 +1,13 @@
## Automated Setup
#### Install required tools
###### Not well-tested. Only supports systemd init system. Installs packages, enables iommu and creates libvirt hooks for now.
```sh
sudo pacman -S qemu libvirt edk2-ovmf virt-manager dnsmasq ebtables iptables
```
make
sudo ./passthrough
OR
sudo make run
```
## Manual Setup
<b>Note</b>: Replace win10 with your virtual machine's name on libvirt hooks and virsh commands.

@ -11,6 +11,7 @@ std::string begin_script();
std::string end_script();
inline const char *hooks_path = "/etc/libvirt/hooks";
inline const char *qemu_dir = "/etc/libvirt/hooks/qemu.d";
inline const char *qemu_hook = "/etc/libvirt/hooks/qemu";
inline const char *vm_path = "/etc/libvirt/hooks/qemu.d/win10";

@ -1,4 +1,5 @@
#include <iostream>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <shell.h>

Binary file not shown.

@ -2,18 +2,28 @@
void libvirt_hook()
{
char cnf;
std::cout << "\033[1;34mSetting up libvirt hooks. If you have already setup libvirt hooks, they'll be replaced. Continue? (y/n) \033[0m";
std::cin >> cnf;
if (tolower(cnf) != 'y')
throw std::runtime_error("\033[1;31mEXITING!\033[0m");
struct stat buf;
if (stat(hooks_path, &buf) != 0)
if (mkdir(hooks_path, 0755) == -1)
throw std::runtime_error(strerror(errno));
if (stat(qemu_hook, &buf) != 0)
{
std::ofstream file(qemu_hook);
file << qemu_script;
file.close();
if (chmod(qemu_hook, 0755) == -1)
if (stat(qemu_dir, &buf) != 0)
if (mkdir(qemu_dir, 0755) == -1)
throw std::runtime_error(strerror(errno));
}
std::ofstream file(qemu_hook);
file << qemu_script;
file.close();
if (chmod(qemu_hook, 0755) == -1)
throw std::runtime_error(strerror(errno));
std::cout << "\033[1;32m/etc/libvirt/hooks/qemu \033[1;32m\u2714\033[0m \033[0m" << std::endl;
hook_begin();
hook_release();
system("systemctl restart libvirtd");
}
void hook_begin()
@ -28,14 +38,12 @@ void hook_begin()
if (stat(vm_begin, &buf) != 0)
if (mkdir(vm_begin, 0755) == -1)
throw std::runtime_error(strerror(errno));
if (stat(begin_sh, &buf) != 0)
{
std::ofstream file(begin_sh);
file << "#BEGIN";
file.close();
if (chmod(begin_sh, 0755) == -1)
throw std::runtime_error(strerror(errno));
}
std::ofstream file(begin_sh);
file << begin_script();
file.close();
if (chmod(begin_sh, 0755) == -1)
throw std::runtime_error(strerror(errno));
std::cout << "\033[1;32m/etc/libvirt/hooks/qemu.d/win10/prepare/begin/begin.sh \033[1;32m\u2714\033[0m \033[0m" << std::endl;
}
void hook_release()
@ -44,28 +52,58 @@ void hook_release()
if (stat(vm_path, &buf) != 0)
if (mkdir(vm_path, 0755) == -1)
throw std::runtime_error(strerror(errno));
if (stat(vm_prepare, &buf) != 0)
if (mkdir(vm_prepare, 0755) == -1)
throw std::runtime_error(strerror(errno));
if (stat(vm_begin, &buf) != 0)
if (mkdir(vm_begin, 0755) == -1)
if (stat(vm_release, &buf) != 0)
if (mkdir(vm_release, 0755) == -1)
throw std::runtime_error(strerror(errno));
if (stat(end_sh, &buf) != 0)
{
std::ofstream file(end_sh);
file << "#END";
file.close();
if (chmod(end_sh, 0755) == -1)
if (stat(vm_end, &buf) != 0)
if (mkdir(vm_end, 0755) == -1)
throw std::runtime_error(strerror(errno));
}
std::ofstream file(end_sh);
file << end_script();
file.close();
if (chmod(end_sh, 0755) == -1)
throw std::runtime_error(strerror(errno));
std::cout << "\033[1;32m/etc/libvirt/hooks/qemu.d/win10/release/end/end.sh \033[1;32m\u2714\033[0m \033[0m" << std::endl;
}
std::string begin_script()
{
return "";
std::string gpu = get_gpu_vendor();
std::string modules;
modules = gpu == "nvidia" ? modules = "nvidia_drm nvidia_modeset nvidia_uvm nvidia" : modules = "amdgpu";
std::string cont = R"(#!/bin/bash
set -x
# Stop display manager
systemctl stop display-manager
# Unbind EFI Framebuffer
echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind)";
cont += "\n\nmodprobe -r " + modules;
cont += "\nvirsh nodedev-detach " + get_vga_slot();
cont += "\nvirsh nodedev-detach " + get_audio_slot();
cont += "\n\n#Load vfio module\nmodprobe vfio-pci";
return cont;
}
std::string end_script()
{
return "";
std::string gpu = get_gpu_vendor();
std::string modules = "amdgpu";
if (gpu == "nvidia")
modules = "nvidia_drm nvidia_modeset nvidia_uvm nvidia";
std::string cont = R"(#!/bin/bash
set -x
# Unload vfio module
modprobe -r vfio-pci
)";
cont += "\nvirsh nodedev-reattach " + get_vga_slot();
cont += "\nvirsh nodedev-reattach " + get_audio_slot();
cont += "\n\n#Unbind EFI Framebuffer\necho \"efi-framebuffer.0\" > /sys/bus/platform/drivers/efi-framebuffer/bind";
cont += gpu == "nvidia" ? "\n\n# Load NVIDIA kernel modules\nmodprobe nvidia_drm\nmodprobe nvidia_modeset\nmodprobe nvidia_uvm\nmodprobe nvidia" : "\n\n# Load AMD kernel module\nmodprobe amdgpu";
cont += "\n\n# Restart Display Manager\nsystemctl start display-manager";
return cont;
}

@ -20,6 +20,5 @@ int main()
catch (const std::runtime_error &err)
{
std::cerr << err.what() << std::endl;
return -1;
}
}

@ -23,19 +23,21 @@ std::string get_gpu_vendor()
std::string get_vga_slot()
{
std::string c = "lspci | grep -i vga.*" + get_gpu_vendor();
std::string res = shell_cmd((char *)&c);
std::string res = shell_cmd(c.c_str());
if (res.empty())
throw std::runtime_error("\n\033[1;31mCouldn't fetch VGA PCI slot!\033[0m");
return "0000:" + res.substr(0, res.find(" "));
std::replace(res.begin(), res.end(), ':', '_');
return "pci_0000_" + res.substr(0, res.find(" "));
}
std::string get_audio_slot()
{
std::string c = "lspci | grep -i audio.*" + get_gpu_vendor();
std::string res = shell_cmd((char *)&c);
std::string res = shell_cmd(c.c_str());
if (res.empty())
throw std::runtime_error("\n\033[1;31mCouldn't fetch Audio PCI slot!\033[0m");
return "0000:" + res.substr(0, res.find(" "));
std::replace(res.begin(), res.end(), ':', '_');
return "pci_0000_" + res.substr(0, res.find(" "));
}

@ -18,6 +18,10 @@ void install_tools()
void enable_services()
{
std::string init_sys = get_init();
std::cout << "\033[1;36mDetected " + init_sys + " init system. \033[0m";
if (init_sys != "systemd")
throw std::runtime_error("\033[1;36mOnly systemd is supported at the moment. \033[0m");
// TODO
if (init_sys == "systemd")
system("systemctl enable --now libvirtd");
else // Other init systems?
@ -49,10 +53,13 @@ std::string get_init()
void user_mod()
{
std::cout << "\n\033[1;36mAdding user to kvm, input & libvirt group \033[0m";
std::string res = shell_cmd("usermod -aG kvm,input,libvirt $(logname)");
if (!res.empty())
{
std::cout << "\033[1;31m\u2718\033[0m" << std::endl;
std::string emsg = "\n\033[1;31m" + res + "\033[0m";
throw std::runtime_error(emsg);
}
std::cout << "\033[1;32m\u2714\033[0m" << std::endl;
}
Loading…
Cancel
Save