Replace use of undocumented GVISOR_KVM_DEV environment variable with flags.

This allows overriding the path used to access the kernel's KVM device file,
typically at `/dev/kvm`, with a flag-controlled path instead.

PiperOrigin-RevId: 431073099
This commit is contained in:
Etienne Perot
2022-02-25 18:29:23 -08:00
committed by gVisor bot
parent 65d8057067
commit 488841f73a
9 changed files with 31 additions and 19 deletions
+3 -2
View File
@@ -44,7 +44,8 @@ import (
)
var (
platformFlag = flag.String("platform", "ptrace", "specify which platform to use")
platformFlag = flag.String("platform", "ptrace", "specify which platform to use")
platformDevicePathFlag = flag.String("platform_device_path", "", "path to a platform-specific device file (e.g. /dev/kvm for KVM platform). If unset, will use a sane platform-specific default.")
)
// Boot initializes a new bare bones kernel for test.
@@ -53,7 +54,7 @@ func Boot() (*kernel.Kernel, error) {
if err != nil {
return nil, fmt.Errorf("platform not found: %v", err)
}
deviceFile, err := platformCtr.OpenDevice()
deviceFile, err := platformCtr.OpenDevice(*platformDevicePathFlag)
if err != nil {
return nil, fmt.Errorf("creating platform: %v", err)
}
+9 -9
View File
@@ -76,15 +76,15 @@ var (
globalErr error
)
// OpenDevice opens the KVM device at /dev/kvm and returns the File.
func OpenDevice() (*os.File, error) {
dev, ok := os.LookupEnv("GVISOR_KVM_DEV")
if !ok {
dev = "/dev/kvm"
// OpenDevice opens the KVM device and returns the File.
// If the devicePath is empty, it will default to /dev/kvm.
func OpenDevice(devicePath string) (*os.File, error) {
if devicePath == "" {
devicePath = "/dev/kvm"
}
f, err := os.OpenFile(dev, unix.O_RDWR, 0)
f, err := os.OpenFile(devicePath, unix.O_RDWR, 0)
if err != nil {
return nil, fmt.Errorf("error opening KVM device file (%s): %v", dev, err)
return nil, fmt.Errorf("error opening KVM device file (%s): %v", devicePath, err)
}
return f, nil
}
@@ -186,8 +186,8 @@ func (*constructor) New(f *os.File) (platform.Platform, error) {
return New(f)
}
func (*constructor) OpenDevice() (*os.File, error) {
return OpenDevice()
func (*constructor) OpenDevice(devicePath string) (*os.File, error) {
return OpenDevice(devicePath)
}
// Flags implements platform.Constructor.Flags().
+1 -1
View File
@@ -42,7 +42,7 @@ type testHarness interface {
func kvmTest(t testHarness, setup func(*KVM), fn func(*vCPU) bool) {
// Create the machine.
deviceFile, err := OpenDevice()
deviceFile, err := OpenDevice("")
if err != nil {
t.Fatalf("error opening device file: %v", err)
}
+5 -1
View File
@@ -426,7 +426,11 @@ type Constructor interface {
//
// * deviceFile - the device file (e.g. /dev/kvm for the KVM platform).
New(deviceFile *os.File) (Platform, error)
OpenDevice() (*os.File, error)
// OpenDevice opens the path to the device used by the platform.
// Passing in an empty string will use the default path for the device,
// e.g. "/dev/kvm" for the KVM platform.
OpenDevice(devicePath string) (*os.File, error)
// Requirements returns platform specific requirements.
Requirements() Requirements
+1 -1
View File
@@ -262,7 +262,7 @@ func (*constructor) New(*os.File) (platform.Platform, error) {
return New()
}
func (*constructor) OpenDevice() (*os.File, error) {
func (*constructor) OpenDevice(_ string) (*os.File, error) {
return nil, nil
}
+1 -1
View File
@@ -78,7 +78,7 @@ func (i *Install) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
if err != nil {
log.Fatalf("invalid platform: %v", err)
}
deviceFile, err := p.OpenDevice()
deviceFile, err := p.OpenDevice(conf.PlatformDevicePath)
if err != nil {
log.Printf("WARNING: unable to open platform, runsc may fail to start: %v", err)
}
+5
View File
@@ -114,6 +114,11 @@ type Config struct {
// Platform is the platform to run on.
Platform string `flag:"platform"`
// PlatformDevicePath is the path to the device file used by the platform.
// e.g. "/dev/kvm" for the KVM platform.
// If unset, a sane platform-specific default will be used.
PlatformDevicePath string `flag:"platform_device_path"`
// Strace indicates that strace should be enabled.
Strace bool `flag:"strace"`
+1
View File
@@ -56,6 +56,7 @@ func RegisterFlags(flagSet *flag.FlagSet) {
// Flags that control sandbox runtime behavior.
flagSet.String("platform", "ptrace", "specifies which platform to use: ptrace (default), kvm.")
flagSet.String("platform_device_path", "", "path to a platform-specific device file (e.g. /dev/kvm for KVM platform). If unset, will use a sane platform-specific default.")
flagSet.Var(watchdogActionPtr(watchdog.LogWarning), "watchdog-action", "sets what action the watchdog takes when triggered: log (default), panic.")
flagSet.Int("panic-signal", -1, "register signal handling that panics. Usually set to SIGUSR2(12) to troubleshoot hangs. -1 disables it.")
flagSet.Bool("profile", false, "prepares the sandbox to use Golang profiler. Note that enabling profiler loosens the seccomp protection added to the sandbox (DO NOT USE IN PRODUCTION).")
+5 -4
View File
@@ -322,7 +322,7 @@ func (s *Sandbox) Restore(cid string, spec *specs.Spec, conf *config.Config, fil
}
// If the platform needs a device FD we must pass it in.
if deviceFile, err := deviceFileForPlatform(conf.Platform); err != nil {
if deviceFile, err := deviceFileForPlatform(conf.Platform, conf.PlatformDevicePath); err != nil {
return err
} else if deviceFile != nil {
defer deviceFile.Close()
@@ -596,7 +596,7 @@ func (s *Sandbox) createSandboxProcess(conf *config.Config, args *Args, startSyn
return err
}
if deviceFile, err := gPlatform.OpenDevice(); err != nil {
if deviceFile, err := gPlatform.OpenDevice(conf.PlatformDevicePath); err != nil {
return fmt.Errorf("opening device file for platform %q: %v", conf.Platform, err)
} else if deviceFile != nil {
defer deviceFile.Close()
@@ -1407,13 +1407,14 @@ func (s *Sandbox) configureStdios(conf *config.Config, stdios []*os.File) error
// deviceFileForPlatform opens the device file for the given platform. If the
// platform does not need a device file, then nil is returned.
func deviceFileForPlatform(name string) (*os.File, error) {
// devicePath may be empty to use a sane platform-specific default.
func deviceFileForPlatform(name, devicePath string) (*os.File, error) {
p, err := platform.Lookup(name)
if err != nil {
return nil, err
}
f, err := p.OpenDevice()
f, err := p.OpenDevice(devicePath)
if err != nil {
return nil, fmt.Errorf("opening device file for platform %q: %w", name, err)
}