diff --git a/bindata/scripts/load-kmod.sh b/bindata/scripts/load-kmod.sh index 7f3d4dc58..17364d735 100755 --- a/bindata/scripts/load-kmod.sh +++ b/bindata/scripts/load-kmod.sh @@ -1,11 +1,16 @@ #!/bin/sh # chroot /host/ modprobe $1 kmod_name=$(tr "-" "_" <<< $1) +kmod_args="${@:2}" chroot /host/ lsmod | grep "^$1" >& /dev/null if [ $? -eq 0 ] then + # NOTE: We do not check if the module is loaded with specific options + # so a manual reload is required if the module is loaded with + # new or different options. + echo "Module $kmod_name already loaded; no change will be applied..." exit 0 else - chroot /host/ modprobe $kmod_name + chroot /host/ modprobe $kmod_name $kmod_args fi diff --git a/pkg/plugins/virtual/virtual_plugin.go b/pkg/plugins/virtual/virtual_plugin.go index e14a2c8e4..dbae02e63 100644 --- a/pkg/plugins/virtual/virtual_plugin.go +++ b/pkg/plugins/virtual/virtual_plugin.go @@ -84,6 +84,16 @@ func (p *VirtualPlugin) Apply() error { glog.Infof("virtual-plugin Apply(): desiredState=%v", p.DesireState.Spec) if p.LoadVfioDriver == loading { + // In virtual deployments of Kubernetes where the underlying virtualization platform does not support a virtualized iommu + // the VFIO PCI driver needs to be loaded with a special flag. + // This is the case for OpenStack deployments where the underlying virtualization platform is KVM. + // NOTE: if VFIO was already loaded for some reason, we will not try to load it again with the new options. + kernelArgs := "enable_unsafe_noiommu_mode=1" + if err := utils.LoadKernelModule("vfio", kernelArgs); err != nil { + glog.Errorf("virtual-plugin Apply(): fail to load vfio kmod: %v", err) + return err + } + if err := utils.LoadKernelModule("vfio_pci"); err != nil { glog.Errorf("virtual-plugin Apply(): fail to load vfio_pci kmod: %v", err) return err diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index af7a9c267..79d809e35 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -534,12 +534,13 @@ func getVfInfo(pciAddr string, devices []*ghw.PCIDevice) sriovnetworkv1.VirtualF return vf } -func LoadKernelModule(name string) error { - glog.Infof("LoadKernelModule(): try to load kernel module %s", name) - cmd := exec.Command("/bin/sh", scriptsPath, name) +func LoadKernelModule(name string, args ...string) error { + glog.Infof("LoadKernelModule(): try to load kernel module %s with arguments '%s'", name, args) + cmdArgs := strings.Join(args, " ") + cmd := exec.Command("/bin/sh", scriptsPath, name, cmdArgs) err := cmd.Run() if err != nil { - glog.Errorf("LoadKernelModule(): fail to load kernel module %s: %v", name, err) + glog.Errorf("LoadKernelModule(): fail to load kernel module %s with arguments '%s': %v", name, args, err) return err } return nil