Merge pull request #2899 from rn/qemu

Allow choice of qemu binary and acceleration
This commit is contained in:
Rolf Neugebauer 2018-02-05 10:20:26 +00:00 committed by GitHub
commit 46b20a2d0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -38,7 +38,7 @@ type QemuConfig struct {
Arch string Arch string
CPUs string CPUs string
Memory string Memory string
KVM bool Accel string
Containerized bool Containerized bool
QemuBinPath string QemuBinPath string
QemuImgPath string QemuImgPath string
@ -56,7 +56,8 @@ const (
) )
var ( var (
defaultArch string defaultArch string
defaultAccel string
) )
func init() { func init() {
@ -66,6 +67,12 @@ func init() {
case "amd64": case "amd64":
defaultArch = "x86_64" defaultArch = "x86_64"
} }
switch {
case haveKVM():
defaultAccel = "kvm:tcg"
case runtime.GOOS == "darwin":
defaultAccel = "hvf:tcg"
}
} }
func haveKVM() bool { func haveKVM() bool {
@ -73,19 +80,6 @@ func haveKVM() bool {
return !os.IsNotExist(err) return !os.IsNotExist(err)
} }
func envOverrideBool(env string, b *bool) {
val := os.Getenv(env)
if val == "" {
return
}
var err error
*b, err = strconv.ParseBool(val)
if err != nil {
log.Fatal("Unable to parse %q=%q as a boolean", env, val)
}
}
func retrieveMAC(statePath string) net.HardwareAddr { func retrieveMAC(statePath string) net.HardwareAddr {
var mac net.HardwareAddr var mac net.HardwareAddr
fileName := filepath.Join(statePath, "mac-addr") fileName := filepath.Join(statePath, "mac-addr")
@ -160,13 +154,14 @@ func runQemu(args []string) {
fw := flags.String("fw", "", "Path to OVMF firmware for UEFI boot") fw := flags.String("fw", "", "Path to OVMF firmware for UEFI boot")
// VM configuration // VM configuration
enableKVM := flags.Bool("kvm", haveKVM(), "Enable KVM acceleration") accel := flags.String("accel", defaultAccel, "Choose acceleration mode. Use 'tcg' to disable it.")
arch := flags.String("arch", defaultArch, "Type of architecture to use, e.g. x86_64, aarch64") arch := flags.String("arch", defaultArch, "Type of architecture to use, e.g. x86_64, aarch64")
cpus := flags.String("cpus", "1", "Number of CPUs") cpus := flags.String("cpus", "1", "Number of CPUs")
mem := flags.String("mem", "1024", "Amount of memory in MB") mem := flags.String("mem", "1024", "Amount of memory in MB")
// Backend configuration // Backend configuration
qemuContainerized := flags.Bool("containerized", false, "Run qemu in a container") qemuContainerized := flags.Bool("containerized", false, "Run qemu in a container")
qemuCmd := flags.String("qemu", "", "Path to the qemu binary (otherwise look in $PATH)")
// Generate UUID, so that /sys/class/dmi/id/product_uuid is populated // Generate UUID, so that /sys/class/dmi/id/product_uuid is populated
vmUUID := uuid.New() vmUUID := uuid.New()
@ -184,8 +179,8 @@ func runQemu(args []string) {
// These envvars override the corresponding command line // These envvars override the corresponding command line
// options. So this must remain after the `flags.Parse` above. // options. So this must remain after the `flags.Parse` above.
envOverrideBool("LINUXKIT_QEMU_KVM", enableKVM) *accel = getStringValue("LINUXKIT_QEMU_ACCEL", *accel, "")
envOverrideBool("LINUXKIT_QEMU_CONTAINERIZED", qemuContainerized) *qemuContainerized = getBoolValue("LINUXKIT_QEMU_CONTAINERIZED", *qemuContainerized)
if len(remArgs) == 0 { if len(remArgs) == 0 {
fmt.Println("Please specify the path to the image to boot") fmt.Println("Please specify the path to the image to boot")
@ -309,8 +304,9 @@ func runQemu(args []string) {
Arch: *arch, Arch: *arch,
CPUs: *cpus, CPUs: *cpus,
Memory: *mem, Memory: *mem,
KVM: *enableKVM, Accel: *accel,
Containerized: *qemuContainerized, Containerized: *qemuContainerized,
QemuBinPath: *qemuCmd,
PublishedPorts: publishFlags, PublishedPorts: publishFlags,
NetdevConfig: netdevConfig, NetdevConfig: netdevConfig,
UUID: vmUUID, UUID: vmUUID,
@ -427,7 +423,7 @@ func runQemuContainer(config QemuConfig) error {
dockerArgs = append(dockerArgs, "--tty") dockerArgs = append(dockerArgs, "--tty")
} }
if config.KVM { if strings.Contains(config.Accel, "kvm") {
dockerArgs = append(dockerArgs, "--device", "/dev/kvm") dockerArgs = append(dockerArgs, "--device", "/dev/kvm")
} }
@ -489,6 +485,7 @@ func buildQemuCmdline(config QemuConfig) (QemuConfig, []string) {
qemuArgs = append(qemuArgs, "-m", config.Memory) qemuArgs = append(qemuArgs, "-m", config.Memory)
qemuArgs = append(qemuArgs, "-uuid", config.UUID.String()) qemuArgs = append(qemuArgs, "-uuid", config.UUID.String())
qemuArgs = append(qemuArgs, "-pidfile", filepath.Join(config.StatePath, "qemu.pid")) qemuArgs = append(qemuArgs, "-pidfile", filepath.Join(config.StatePath, "qemu.pid"))
// Need to specify the vcpu type when running qemu on arm64 platform, for security reason, // Need to specify the vcpu type when running qemu on arm64 platform, for security reason,
// the vcpu should be "host" instead of other names such as "cortex-a53"... // the vcpu should be "host" instead of other names such as "cortex-a53"...
if config.Arch == "aarch64" { if config.Arch == "aarch64" {
@ -499,12 +496,27 @@ func buildQemuCmdline(config QemuConfig) (QemuConfig, []string) {
} }
} }
if config.KVM { // goArch is the GOARCH equivalent of config.Arch
qemuArgs = append(qemuArgs, "-enable-kvm") var goArch string
switch config.Arch {
case "aarch64":
goArch = "arm64"
case "x86_64":
goArch = "amd64"
default:
log.Fatalf("%s is an unsupported architecture.")
}
if goArch != runtime.GOARCH {
log.Infof("Disable acceleration as %s != %s", config.Arch, runtime.GOARCH)
config.Accel = ""
}
if config.Accel != "" {
if config.Arch == "aarch64" { if config.Arch == "aarch64" {
qemuArgs = append(qemuArgs, "-machine", "virt,gic_version=host") qemuArgs = append(qemuArgs, "-machine", fmt.Sprintf("virt,gic_version=host,accel=%s", config.Accel))
} else { } else {
qemuArgs = append(qemuArgs, "-machine", "q35,accel=kvm:tcg") qemuArgs = append(qemuArgs, "-machine", fmt.Sprintf("q35,accel=%s", config.Accel))
} }
} else { } else {
if config.Arch == "aarch64" { if config.Arch == "aarch64" {
@ -591,6 +603,13 @@ func buildQemuCmdline(config QemuConfig) (QemuConfig, []string) {
} }
func discoverBackend(config QemuConfig) QemuConfig { func discoverBackend(config QemuConfig) QemuConfig {
if config.QemuImgPath != "" && config.Containerized {
log.Fatal("-qemu and -containerized can't be used together.")
}
if config.QemuImgPath != "" {
return config
}
qemuBinPath := "qemu-system-" + config.Arch qemuBinPath := "qemu-system-" + config.Arch
qemuImgPath := "qemu-img" qemuImgPath := "qemu-img"