From dfb889122e03f0ef6468123d14185ddea9fa1726 Mon Sep 17 00:00:00 2001 From: jedrw Date: Sun, 12 Jan 2025 13:34:47 +0000 Subject: [PATCH] feat: support duplicate device IDs in initramfs-tools and mkinitcpio --- go.mod | 4 -- go.sum | 30 +------------ internal/configs/config_initramfstools.go | 30 +++++++++++++ internal/configs/config_mkinitcpio.go | 54 +++++++++++++++++++++-- internal/configs/configs.go | 38 ++++++++-------- internal/pages/02_select_gpu.go | 8 ++-- internal/pages/06_finalize.go | 22 ++++++++- 7 files changed, 126 insertions(+), 60 deletions(-) diff --git a/go.mod b/go.mod index b722624..daa3906 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,7 @@ require ( github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5 github.com/akamensky/argparse v1.4.0 github.com/cavaliergopher/grab/v3 v3.0.1 - github.com/charmbracelet/bubbles v0.17.1 github.com/charmbracelet/bubbletea v0.25.0 - github.com/charmbracelet/lipgloss v0.9.1 github.com/gookit/color v1.5.4 github.com/klauspost/cpuid/v2 v2.2.6 github.com/nexidian/gocliselect v1.0.0 @@ -16,7 +14,6 @@ require ( ) require ( - github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/buger/goterm v1.0.4 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect @@ -30,7 +27,6 @@ require ( github.com/muesli/termenv v0.15.2 // indirect github.com/pkg/term v1.1.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.15.0 // indirect diff --git a/go.sum b/go.sum index e8026e2..6fe9f0b 100644 --- a/go.sum +++ b/go.sum @@ -2,36 +2,21 @@ github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5 h1:IEH+I+phC github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5/go.mod h1:+yX6+uXNeERvwFtP/gH/dOW/MA+K10Wi6asYcRtDXd8= github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc= github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA= -github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= -github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/buger/goterm v1.0.3 h1:7V/HeAQHrzPk/U4BvyH2g9u+xbUW9nr4yRPyG59W4fM= -github.com/buger/goterm v1.0.3/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY= github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE= github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4= github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4= -github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= -github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= -github.com/charmbracelet/bubbles v0.17.1 h1:0SIyjOnkrsfDo88YvPgAWvZMwXe26TP6drRvmkjyUu4= -github.com/charmbracelet/bubbles v0.17.1/go.mod h1:9HxZWlkCqz2PRwsCbYl7a3KXvGzFaDHpYbSYMJ+nE3o= -github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= -github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= -github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= -github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -58,17 +43,10 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= -github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= -github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= -github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,16 +54,10 @@ golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/configs/config_initramfstools.go b/internal/configs/config_initramfstools.go index d3a7bd5..77f073d 100644 --- a/internal/configs/config_initramfstools.go +++ b/internal/configs/config_initramfstools.go @@ -4,10 +4,12 @@ import ( "bufio" "fmt" "os" + "path" "regexp" "strings" "github.com/HikariKnight/quickpassthrough/internal/common" + "github.com/HikariKnight/quickpassthrough/internal/logger" "github.com/HikariKnight/quickpassthrough/pkg/fileio" ) @@ -82,3 +84,31 @@ func initramfs_addModules(conffile string) { } } } + +func SetInitramfsToolsEarlyBinds(config *Config) { + confToSystemPathRe := regexp.MustCompile(`^config`) + + earlyBindScriptConfigPath := path.Join(config.Path.INITRAMFS, "/scripts/init-top/early-vfio-bind.sh") + earlyBindScriptSysPath := confToSystemPathRe.ReplaceAllString(earlyBindScriptConfigPath, "") + config.EarlyBindFilePaths[earlyBindScriptConfigPath] = earlyBindScriptSysPath + if exists, _ := fileio.FileExist(earlyBindScriptConfigPath); exists { + _ = os.Remove(earlyBindScriptConfigPath) + } + + logger.Printf("Writing to early bind script to %s", earlyBindScriptConfigPath) + vfioBindScript := fmt.Sprintf(`#!/bin/bash +PREREQS="" +DEVS="%s" + +for DEV in $DEVS; do + echo "vfio-pci" > /sys/bus/pci/devices/$DEV/driver_override +done + +# Load the vfio-pci module +modprobe -i vfio-pci`, strings.Join(config.Gpu_Addresses, " ")) + + fileio.AppendContent(vfioBindScript, earlyBindScriptConfigPath) + err := os.Chmod(earlyBindScriptConfigPath, 0755) + common.ErrorCheck(err, fmt.Sprintf("Error, could not chmod %s", earlyBindScriptConfigPath)) + +} diff --git a/internal/configs/config_mkinitcpio.go b/internal/configs/config_mkinitcpio.go index 6c95f8f..744819a 100644 --- a/internal/configs/config_mkinitcpio.go +++ b/internal/configs/config_mkinitcpio.go @@ -3,18 +3,18 @@ package configs import ( "fmt" "os" + "path" "regexp" + "slices" "strings" + "github.com/HikariKnight/quickpassthrough/internal/common" "github.com/HikariKnight/quickpassthrough/internal/logger" "github.com/HikariKnight/quickpassthrough/pkg/fileio" ) // Set_Mkinitcpio copies the content of /etc/mkinitcpio.conf to the config folder and does an inline replace/insert on the MODULES=() line -func Set_Mkinitcpio() { - // Get the config struct - config := GetConfig() - +func Set_Mkinitcpio(config *Config) { // Make sure we start from scratch by deleting any old file if exists, _ := fileio.FileExist(config.Path.MKINITCPIO); exists { _ = os.Remove(config.Path.MKINITCPIO) @@ -26,6 +26,7 @@ func Set_Mkinitcpio() { // Make a regex to find the modules line module_line_re := regexp.MustCompile(`^MODULES=`) + hooks_line_re := regexp.MustCompile(`^HOOKS=`) modules_re := regexp.MustCompile(`MODULES=\((.*)\)`) vfio_modules_re := regexp.MustCompile(`(vfio_iommu_type1|vfio_pci|vfio_virqfd|vfio|vendor-reset)`) @@ -67,9 +68,54 @@ func Set_Mkinitcpio() { // Write the modules line we generated fileio.AppendContent(fmt.Sprintf("MODULES=(%s)\n", strings.Join(modules, " ")), config.Path.MKINITCPIO) + } else if config.HasDuplicateDeviceIds && hooks_line_re.MatchString(line) { + setMkinitcpioEarlyBinds(config, line) } else { // Else just write the line to the config fileio.AppendContent(fmt.Sprintf("%s\n", line), config.Path.MKINITCPIO) } } } + +func setMkinitcpioEarlyBinds(config *Config, hooksLine string) { + err := os.MkdirAll(config.Path.MKINITCPIOHOOKS, os.ModePerm) + common.ErrorCheck(err, "Error, could not create mkinitcpio hook config directory") + confToSystemPathRe := regexp.MustCompile(`^config`) + + earlyBindHookConfigPath := path.Join(config.Path.MKINITCPIOHOOKS, "early-vfio-bind") + earlyBindHookSysPath := confToSystemPathRe.ReplaceAllString(earlyBindHookConfigPath, "") + config.EarlyBindFilePaths[earlyBindHookConfigPath] = earlyBindHookSysPath + if exists, _ := fileio.FileExist(earlyBindHookConfigPath); exists { + _ = os.Remove(earlyBindHookConfigPath) + } + + logger.Printf("Writing to early bind hook to %s", earlyBindHookConfigPath) + vfioBindHook := fmt.Sprintf(`#!/bin/bash +run_hook() { + DEVS="%s" + + for DEV in $DEVS; do + echo "vfio-pci" > /sys/bus/pci/devices/$DEV/driver_override + done + + # Load the vfio-pci module + modprobe -i vfio-pci +}`, strings.Join(config.Gpu_Addresses, " ")) + + fileio.AppendContent(vfioBindHook, earlyBindHookConfigPath) + err = os.Chmod(earlyBindHookConfigPath, 0755) + common.ErrorCheck(err, fmt.Sprintf("Error, could not chmod %s", earlyBindHookConfigPath)) + + hooksString := strings.Trim(strings.Split(hooksLine, "=")[1], "()") + hooks := strings.Split(hooksString, " ") + customHook := "early-vfio-bind" + if !slices.Contains(hooks, customHook) { + hooks = append(hooks, customHook) + } + + // Write to logger + logger.Printf("Replacing line in %s:\n%s\nWith:\nHOOKS=(%s)\n", config.Path.MKINITCPIO, hooksLine, strings.Join(hooks, " ")) + + // Write the modules line we generated + fileio.AppendContent(fmt.Sprintf("HOOKS=(%s)\n", strings.Join(hooks, " ")), config.Path.MKINITCPIO) +} diff --git a/internal/configs/configs.go b/internal/configs/configs.go index cd9b0b7..6299bed 100644 --- a/internal/configs/configs.go +++ b/internal/configs/configs.go @@ -17,15 +17,16 @@ import ( ) type Path struct { - CMDLINE string - MODPROBE string - INITRAMFS string - ETCMODULES string - DEFAULT string - QEMU string - DRACUT string - DRACUTMODULE string - MKINITCPIO string + CMDLINE string + MODPROBE string + INITRAMFS string + ETCMODULES string + DEFAULT string + QEMU string + DRACUT string + DRACUTMODULE string + MKINITCPIO string + MKINITCPIOHOOKS string } type Config struct { @@ -43,15 +44,16 @@ type Config struct { // GetConfigPaths retrieves the path to all the config files. func GetConfigPaths() *Path { Paths := &Path{ - CMDLINE: "config/kernel_args", - MODPROBE: "config/etc/modprobe.d", - INITRAMFS: "config/etc/initramfs-tools", - ETCMODULES: "config/etc/modules", - DEFAULT: "config/etc/default", - QEMU: "config/qemu", - DRACUT: "config/etc/dracut.conf.d", - DRACUTMODULE: "config/usr/lib/dracut/modules.d/90early-vfio-bind", - MKINITCPIO: "config/etc/mkinitcpio.conf", + CMDLINE: "config/kernel_args", + MODPROBE: "config/etc/modprobe.d", + INITRAMFS: "config/etc/initramfs-tools", + ETCMODULES: "config/etc/modules", + DEFAULT: "config/etc/default", + QEMU: "config/qemu", + DRACUT: "config/etc/dracut.conf.d", + DRACUTMODULE: "config/usr/lib/dracut/modules.d/90early-vfio-bind", + MKINITCPIO: "config/etc/mkinitcpio.conf", + MKINITCPIOHOOKS: "config/etc/initcpio/hooks", } return Paths diff --git a/internal/pages/02_select_gpu.go b/internal/pages/02_select_gpu.go index e4be1bb..84bcc68 100644 --- a/internal/pages/02_select_gpu.go +++ b/internal/pages/02_select_gpu.go @@ -105,10 +105,12 @@ func viewGPU(config *configs.Config, ext ...int) { } logger.Printf("Checking for duplicate device Ids") - hasDuplicateDeviceIds := detectDuplicateDeviceIds(config.Gpu_Group, config.Gpu_IDs) + config.HasDuplicateDeviceIds = detectDuplicateDeviceIds(config.Gpu_Group, config.Gpu_IDs) - if hasDuplicateDeviceIds { - config.HasDuplicateDeviceIds = true + // TODO remove this + config.HasDuplicateDeviceIds = true + + if config.HasDuplicateDeviceIds { config.Gpu_Addresses = lsiommu.GetIOMMU("-g", mode, "-i", config.Gpu_Group, "--pciaddr") } diff --git a/internal/pages/06_finalize.go b/internal/pages/06_finalize.go index 1817764..1c0542f 100644 --- a/internal/pages/06_finalize.go +++ b/internal/pages/06_finalize.go @@ -27,6 +27,11 @@ func prepModules(config *configs.Config) { configs.Set_Modprobe(config.Gpu_IDs) } + if exists, _ := fileio.FileExist(config.Path.INITRAMFS); exists && config.HasDuplicateDeviceIds { + // Configure initramfs early binds + configs.SetInitramfsToolsEarlyBinds(config) + } + // If we have a folder for dracut if exists, _ := fileio.FileExist(config.Path.DRACUT); exists { // Configure dracut @@ -35,7 +40,7 @@ func prepModules(config *configs.Config) { // If we have a mkinitcpio.conf file if exists, _ := fileio.FileExist(config.Path.MKINITCPIO); exists { - configs.Set_Mkinitcpio() + configs.Set_Mkinitcpio(config) } // Configure grub2 here as we can make the config without sudo @@ -112,7 +117,7 @@ func installPassthrough(config *configs.Config) { // Get the user data currentUser, err := user.Current() if err != nil { - log.Fatalf(err.Error()) + log.Fatal(err) } if !config.IsRoot { @@ -202,6 +207,12 @@ func installPassthrough(config *configs.Config) { // Copy the modules file to /etc/modules configs.CopyToSystem(config.IsRoot, config.Path.ETCMODULES, "/etc/modules") + if config.HasDuplicateDeviceIds { + for configPath, sysPath := range config.EarlyBindFilePaths { + configs.CopyToSystem(config.IsRoot, configPath, sysPath) + } + } + if err = command.ExecAndLogSudo(config.IsRoot, true, "update-initramfs", "-u"); err != nil { log.Fatalf("Failed to update initramfs: %s", err) } @@ -232,9 +243,16 @@ func installPassthrough(config *configs.Config) { // Copy dracut config to /etc/dracut.conf.d/vfio configs.CopyToSystem(config.IsRoot, config.Path.MKINITCPIO, "/etc/mkinitcpio.conf") + if config.HasDuplicateDeviceIds { + for configPath, sysPath := range config.EarlyBindFilePaths { + configs.CopyToSystem(config.IsRoot, configPath, sysPath) + } + } + if err = command.ExecAndLogSudo(config.IsRoot, true, "mkinitcpio", "-P"); err != nil { log.Fatalf("Failed to update initramfs: %s", err) } + } // Make sure prompt end up on next line