[lxc-devel] [lxd/master] Add ppc64le support

stgraber on Github lxc-bot at linuxcontainers.org
Thu Jan 30 04:20:17 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200129/c25450cd/attachment.bin>
-------------- next part --------------
From ed4e666d3c439551f3e890b7000c10865305ea34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at 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 <stgraber at 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?= <stgraber at 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 <stgraber at 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?= <stgraber at 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 <stgraber at 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}}"
 `))
 


More information about the lxc-devel mailing list