The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6812
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) ===
From ed4e666d3c439551f3e890b7000c10865305ea34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 29 Jan 2020 22:59:11 -0500 Subject: [PATCH 1/3] lxd/vm: Record architecture name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/instance/drivers/driver_qemu.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index 556b1bc32a..82e541270f 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -103,6 +103,12 @@ func qemuInstantiate(s *state.State, args db.InstanceArgs, expandedDevices devic expiryDate: args.ExpiryDate, } + // Get the architecture name. + archName, err := osarch.ArchitectureName(vm.architecture) + if err == nil { + vm.architectureName = archName + } + // Cleanup the zero values. if vm.expiryDate.IsZero() { vm.expiryDate = time.Time{} @@ -147,6 +153,12 @@ func qemuCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error) expiryDate: args.ExpiryDate, } + // Get the architecture name. + archName, err := osarch.ArchitectureName(vm.architecture) + if err == nil { + vm.architectureName = archName + } + // Cleanup the zero values. if vm.expiryDate.IsZero() { vm.expiryDate = time.Time{} @@ -178,7 +190,7 @@ func qemuCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error) }() // Load the config. - err := vm.init() + err = vm.init() if err != nil { logger.Error("Failed creating instance", ctxMap) return nil, err @@ -288,8 +300,9 @@ type qemu struct { // Cached handles. // Do not use these variables directly, instead use their associated get functions so they // will be initialised on demand. - agentClient *http.Client - storagePool storagePools.Pool + agentClient *http.Client + storagePool storagePools.Pool + architectureName string } // getAgentClient returns the current agent client handle. To avoid TLS setup each time this @@ -2953,9 +2966,6 @@ func (vm *qemu) Exec(req api.InstanceExecPost, stdin *os.File, stdout *os.File, // Render returns info about the instance. func (vm *qemu) Render() (interface{}, interface{}, error) { - // Ignore err as the arch string on error is correct (unknown) - architectureName, _ := osarch.ArchitectureName(vm.architecture) - if vm.IsSnapshot() { // Prepare the ETag etag := []interface{}{vm.expiryDate} @@ -2968,7 +2978,7 @@ func (vm *qemu) Render() (interface{}, interface{}, error) { Name: strings.SplitN(vm.name, "/", 2)[1], Stateful: vm.stateful, } - vmSnap.Architecture = architectureName + vmSnap.Architecture = vm.architectureName vmSnap.Config = vm.localConfig vmSnap.Devices = vm.localDevices.CloneNative() vmSnap.Ephemeral = vm.ephemeral @@ -2992,7 +3002,7 @@ func (vm *qemu) Render() (interface{}, interface{}, error) { } vmState.Description = vm.description - vmState.Architecture = architectureName + vmState.Architecture = vm.architectureName vmState.Config = vm.localConfig vmState.CreatedAt = vm.creationDate vmState.Devices = vm.localDevices.CloneNative() From 4795633df6d1c5cb241c163373065de8c77fbcf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 29 Jan 2020 22:59:37 -0500 Subject: [PATCH 2/3] lxd/vm: Cleanup qemu config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/instance/drivers/driver_qemu_templates.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu_templates.go b/lxd/instance/drivers/driver_qemu_templates.go index a557dc127a..13c2ac6033 100644 --- a/lxd/instance/drivers/driver_qemu_templates.go +++ b/lxd/instance/drivers/driver_qemu_templates.go @@ -107,9 +107,6 @@ var qemuCPU = template.Must(template.New("qemuCPU").Parse(` # CPU [smp-opts] cpus = "{{.cpuCount}}" -#sockets = "1" -#cores = "1" -#threads = "1" `)) var qemuControlSocket = template.Must(template.New("qemuControlSocket").Parse(` From 89252be528a0a30925b512fe4a716f33118fa494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 29 Jan 2020 23:02:01 -0500 Subject: [PATCH 3/3] lxd/vm: Add ppc64el support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/instance/drivers/driver_qemu.go | 72 ++++++++++--------- lxd/instance/drivers/driver_qemu_templates.go | 60 +++++++++++++++- 2 files changed, 97 insertions(+), 35 deletions(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index 82e541270f..e956abf108 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -680,8 +680,8 @@ func (vm *qemu) Start(stateful bool) error { devConfs = append(devConfs, runConf) } - // Get qemu configuration - qemuBinary, qemuType, qemuConfig, err := vm.qemuArchConfig() + // Get qemu configuration. + qemuBinary, err := vm.qemuArchConfig() if err != nil { op.Done(err) return err @@ -690,7 +690,7 @@ func (vm *qemu) Start(stateful bool) error { // Define a set of files to open and pass their file descriptors to qemu command. fdFiles := make([]string, 0) - confFile, err := vm.generateQemuConfigFile(qemuType, qemuConfig, devConfs, &fdFiles) + confFile, err := vm.generateQemuConfigFile(devConfs, &fdFiles) if err != nil { op.Done(err) return err @@ -863,6 +863,11 @@ func (vm *qemu) Start(stateful bool) error { } func (vm *qemu) setupNvram() error { + // No UEFI nvram for ppc64le. + if vm.architecture == osarch.ARCH_64BIT_POWERPC_LITTLE_ENDIAN { + return nil + } + // Mount the instance's config volume. ourMount, err := vm.mount() if err != nil { @@ -891,25 +896,16 @@ func (vm *qemu) setupNvram() error { return nil } -func (vm *qemu) qemuArchConfig() (string, string, string, error) { +func (vm *qemu) qemuArchConfig() (string, error) { if vm.architecture == osarch.ARCH_64BIT_INTEL_X86 { - conf := ` -[global] -driver = "ICH9-LPC" -property = "disable_s3" -value = "1" - -[global] -driver = "ICH9-LPC" -property = "disable_s4" -value = "1" -` - return "qemu-system-x86_64", "q35", conf, nil + return "qemu-system-x86_64", nil } else if vm.architecture == osarch.ARCH_64BIT_ARMV8_LITTLE_ENDIAN { - return "qemu-system-aarch64", "virt", "", nil + return "qemu-system-aarch64", nil + } else if vm.architecture == osarch.ARCH_64BIT_POWERPC_LITTLE_ENDIAN { + return "qemu-system-ppc64", nil } - return "", "", "", fmt.Errorf("Architecture isn't supported for virtual machines") + return "", fmt.Errorf("Architecture isn't supported for virtual machines") } // deviceVolatileGetFunc returns a function that retrieves a named device's volatile config and @@ -1279,12 +1275,11 @@ func (vm *qemu) deviceBootPriorities() (map[string]int, error) { // generateQemuConfigFile writes the qemu config file and returns its location. // It writes the config file inside the VM's log path. -func (vm *qemu) generateQemuConfigFile(qemuType string, qemuConf string, devConfs []*deviceConfig.RunConfig, fdFiles *[]string) (string, error) { +func (vm *qemu) generateQemuConfigFile(devConfs []*deviceConfig.RunConfig, fdFiles *[]string) (string, error) { var sb *strings.Builder = &strings.Builder{} err := qemuBase.Execute(sb, map[string]interface{}{ - "qemuType": qemuType, - "qemuConf": qemuConf, + "architecture": vm.architectureName, "ringbufSizeBytes": qmp.RingbufSize, }) if err != nil { @@ -1372,6 +1367,7 @@ func (vm *qemu) addMemoryConfig(sb *strings.Builder) error { } return qemuMemory.Execute(sb, map[string]interface{}{ + "architecture": vm.architectureName, "memSizeBytes": memSizeBytes, }) } @@ -1379,7 +1375,8 @@ func (vm *qemu) addMemoryConfig(sb *strings.Builder) error { // addVsockConfig adds the qemu config required for setting up the host->VM vsock socket. func (vm *qemu) addVsockConfig(sb *strings.Builder) error { return qemuVsock.Execute(sb, map[string]interface{}{ - "vsockID": vm.vsockID(), + "architecture": vm.architectureName, + "vsockID": vm.vsockID(), }) } @@ -1397,29 +1394,38 @@ func (vm *qemu) addCPUConfig(sb *strings.Builder) error { } return qemuCPU.Execute(sb, map[string]interface{}{ - "cpuCount": cpuCount, + "architecture": vm.architectureName, + "cpuCount": cpuCount, }) } // addMonitorConfig adds the qemu config required for setting up the host side VM monitor device. func (vm *qemu) addMonitorConfig(sb *strings.Builder) error { return qemuControlSocket.Execute(sb, map[string]interface{}{ - "path": vm.getMonitorPath(), + "architecture": vm.architectureName, + "path": vm.getMonitorPath(), }) } // addFirmwareConfig adds the qemu config required for adding a secure boot compatible EFI firmware. func (vm *qemu) addFirmwareConfig(sb *strings.Builder) error { + // No UEFI nvram for ppc64le. + if vm.architecture == osarch.ARCH_64BIT_POWERPC_LITTLE_ENDIAN { + return nil + } + return qemuDriveFirmware.Execute(sb, map[string]interface{}{ - "roPath": filepath.Join(vm.ovmfPath(), "OVMF_CODE.fd"), - "nvramPath": vm.getNvramPath(), + "architecture": vm.architectureName, + "roPath": filepath.Join(vm.ovmfPath(), "OVMF_CODE.fd"), + "nvramPath": vm.getNvramPath(), }) } // addConfDriveConfig adds the qemu config required for adding the config drive. func (vm *qemu) addConfDriveConfig(sb *strings.Builder) error { return qemuDriveConfig.Execute(sb, map[string]interface{}{ - "path": filepath.Join(vm.Path(), "config"), + "architecture": vm.architectureName, + "path": filepath.Join(vm.Path(), "config"), }) } @@ -1483,11 +1489,12 @@ func (vm *qemu) addDriveConfig(sb *strings.Builder, bootIndexes map[string]int, } return qemuDrive.Execute(sb, map[string]interface{}{ - "devName": driveConf.DevName, - "devPath": driveConf.DevPath, - "bootIndex": bootIndexes[driveConf.DevName], - "cacheMode": cacheMode, - "aioMode": aioMode, + "architecture": vm.architectureName, + "devName": driveConf.DevName, + "devPath": driveConf.DevPath, + "bootIndex": bootIndexes[driveConf.DevName], + "cacheMode": cacheMode, + "aioMode": aioMode, }) } @@ -1508,6 +1515,7 @@ func (vm *qemu) addNetDevConfig(sb *strings.Builder, nicIndex int, bootIndexes m var tpl *template.Template tplFields := map[string]interface{}{ + "architecture": vm.architectureName, "devName": devName, "devHwaddr": devHwaddr, "bootIndex": bootIndexes[devName], diff --git a/lxd/instance/drivers/driver_qemu_templates.go b/lxd/instance/drivers/driver_qemu_templates.go index 13c2ac6033..030432c35c 100644 --- a/lxd/instance/drivers/driver_qemu_templates.go +++ b/lxd/instance/drivers/driver_qemu_templates.go @@ -9,11 +9,30 @@ var qemuBase = template.Must(template.New("qemuBase").Parse(` # Machine [machine] graphics = "off" -type = "{{.qemuType}}" +{{if eq .architecture "x86_64" -}} +type = "q35" +{{end -}} +{{if eq .architecture "aarch64" -}} +type = "virt" +{{end -}} +{{if eq .architecture "ppc64le" -}} +type = "pseries" +{{end -}} accel = "kvm" usb = "off" graphics = "off" -{{ .qemuConf -}} + +{{if eq .architecture "x86_64" -}} +[global] +driver = "ICH9-LPC" +property = "disable_s3" +value = "1" + +[global] +driver = "ICH9-LPC" +property = "disable_s4" +value = "1" +{{end -}} [boot-opts] strict = "on" @@ -31,7 +50,8 @@ chardev = "vserial" backend = "ringbuf" size = "{{.ringbufSizeBytes}}B" -# PCIe root +# SCSI controller +{{if ne .architecture "ppc64le" -}} [device "qemu_pcie1"] driver = "pcie-root-port" port = "0x10" @@ -39,42 +59,62 @@ chassis = "1" bus = "pcie.0" multifunction = "on" addr = "0x2" +{{- end }} [device "qemu_scsi"] driver = "virtio-scsi-pci" +{{if eq .architecture "ppc64le" -}} +bus = pci.0 +addr = "0x2" +{{else -}} bus = "qemu_pcie1" addr = "0x0" +{{end -}} # Balloon driver +{{if ne .architecture "ppc64le" -}} [device "qemu_pcie2"] driver = "pcie-root-port" port = "0x11" chassis = "2" bus = "pcie.0" addr = "0x2.0x1" +{{- end }} [device "qemu_ballon"] driver = "virtio-balloon-pci" +{{if eq .architecture "ppc64le" -}} +bus = pci.0 +addr = "0x2.0x1" +{{else -}} bus = "qemu_pcie2" addr = "0x0" +{{end -}} # Random number generator [object "qemu_rng"] qom-type = "rng-random" filename = "/dev/urandom" +{{if ne .architecture "ppc64le" -}} [device "qemu_pcie3"] driver = "pcie-root-port" port = "0x12" chassis = "3" bus = "pcie.0" addr = "0x2.0x2" +{{- end }} [device "dev-qemu_rng"] driver = "virtio-rng-pci" rng = "qemu_rng" +{{if eq .architecture "ppc64le" -}} +bus = "pci.0" +addr = "0x2.0x2" +{{else -}} bus = "qemu_pcie3" addr = "0x0" +{{end -}} # Console [chardev "console"] @@ -89,18 +129,25 @@ size = "{{.memSizeBytes}}B" var qemuVsock = template.Must(template.New("qemuVsock").Parse(` # Vsock +{{if ne .architecture "ppc64le" -}} [device "qemu_pcie4"] driver = "pcie-root-port" port = "0x13" chassis = "4" bus = "pcie.0" addr = "0x2.0x3" +{{- end }} [device] driver = "vhost-vsock-pci" guest-cid = "{{.vsockID}}" +{{if eq .architecture "ppc64le" -}} +bus = "pci.0" +addr = "0x2.0x3" +{{else -}} bus = "qemu_pcie4" addr = "0x0" +{{end -}} `)) var qemuCPU = template.Must(template.New("qemuCPU").Parse(` @@ -176,19 +223,26 @@ bootindex = "{{.bootIndex}}" // qemuDevTapCommon is common PCI device template for tap based netdevs. var qemuDevTapCommon = template.Must(template.New("qemuDevTapCommon").Parse(` +{{if ne .architecture "ppc64le" -}} [device "qemu_pcie{{.chassisIndex}}"] driver = "pcie-root-port" port = "0x{{.portIndex}}" chassis = "{{.chassisIndex}}" bus = "pcie.0" addr = "0x2.0x{{.pcieAddr}}" +{{- end }} [device "dev-lxd_{{.devName}}"] driver = "virtio-net-pci" netdev = "lxd_{{.devName}}" mac = "{{.devHwaddr}}" +{{if eq .architecture "ppc64le" -}} +bus = "pci.0" +addr = "0x2.0x{{.pcieAddr}}" +{{else -}} bus = "qemu_pcie{{.chassisIndex}}" addr = "0x0" +{{end -}} bootindex = "{{.bootIndex}}" `))
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel