[lxc-devel] [lxd/master] Add GPU & spice socket

stgraber on Github lxc-bot at linuxcontainers.org
Sun Jun 7 01:52:21 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 349 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200606/f58288a4/attachment.bin>
-------------- next part --------------
From 02cf2eee9267cbdfe60a720c46f08316657e1a01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 6 Jun 2020 21:30:32 -0400
Subject: [PATCH 1/3] lxd/vm: Rename some functions
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 | 32 ++++++++++++++---------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index a90e65fd5a..5079f9e7be 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -468,7 +468,7 @@ func (vm *qemu) generateAgentCert() (string, string, string, string, error) {
 // Freeze freezes the instance.
 func (vm *qemu) Freeze() error {
 	// Connect to the monitor.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		return err
 	}
@@ -493,7 +493,7 @@ func (vm *qemu) onStop(target string) error {
 	// Cleanup.
 	vm.cleanupDevices()
 	os.Remove(vm.pidFilePath())
-	os.Remove(vm.getMonitorPath())
+	os.Remove(vm.monitorPath())
 	vm.unmount()
 
 	// Record power state.
@@ -530,7 +530,7 @@ func (vm *qemu) Shutdown(timeout time.Duration) error {
 	}
 
 	// Connect to the monitor.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		op.Done(err)
 		return err
@@ -656,7 +656,7 @@ func (vm *qemu) Start(stateful bool) error {
 
 	// Copy OVMF settings firmware to nvram file.
 	// This firmware file can be modified by the VM so it must be copied from the defaults.
-	if !shared.PathExists(vm.getNvramPath()) {
+	if !shared.PathExists(vm.nvramPath()) {
 		err = vm.setupNvram()
 		if err != nil {
 			op.Done(err)
@@ -868,7 +868,7 @@ func (vm *qemu) Start(stateful bool) error {
 	})
 
 	// Start QMP monitoring.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		op.Done(err)
 		return err
@@ -989,8 +989,8 @@ func (vm *qemu) setupNvram() error {
 		return fmt.Errorf("Required EFI firmware settings file missing: %s", srcOvmfFile)
 	}
 
-	os.Remove(vm.getNvramPath())
-	err = shared.FileCopy(srcOvmfFile, vm.getNvramPath())
+	os.Remove(vm.nvramPath())
+	err = shared.FileCopy(srcOvmfFile, vm.nvramPath())
 	if err != nil {
 		return err
 	}
@@ -1159,11 +1159,11 @@ func (vm *qemu) runHooks(hooks []func() error) error {
 	return nil
 }
 
-func (vm *qemu) getMonitorPath() string {
+func (vm *qemu) monitorPath() string {
 	return filepath.Join(vm.LogPath(), "qemu.monitor")
 }
 
-func (vm *qemu) getNvramPath() string {
+func (vm *qemu) nvramPath() string {
 	return filepath.Join(vm.Path(), "qemu.nvram")
 }
 
@@ -1753,7 +1753,7 @@ func (vm *qemu) addCPUConfig(sb *strings.Builder) error {
 func (vm *qemu) addMonitorConfig(sb *strings.Builder) error {
 	return qemuControlSocket.Execute(sb, map[string]interface{}{
 		"architecture": vm.architectureName,
-		"path":         vm.getMonitorPath(),
+		"path":         vm.monitorPath(),
 	})
 }
 
@@ -1767,7 +1767,7 @@ func (vm *qemu) addFirmwareConfig(sb *strings.Builder) error {
 	return qemuDriveFirmware.Execute(sb, map[string]interface{}{
 		"architecture": vm.architectureName,
 		"roPath":       filepath.Join(vm.ovmfPath(), "OVMF_CODE.fd"),
-		"nvramPath":    vm.getNvramPath(),
+		"nvramPath":    vm.nvramPath(),
 	})
 }
 
@@ -2003,7 +2003,7 @@ func (vm *qemu) Stop(stateful bool) error {
 	}
 
 	// Connect to the monitor.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		// If we fail to connect, it's most likely because the VM is already off.
 		op.Done(nil)
@@ -2050,7 +2050,7 @@ func (vm *qemu) Stop(stateful bool) error {
 // Unfreeze restores the instance to running.
 func (vm *qemu) Unfreeze() error {
 	// Connect to the monitor.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		return err
 	}
@@ -3421,7 +3421,7 @@ func (vm *qemu) Console() (*os.File, chan error, error) {
 	vmConsoleLock.Unlock()
 
 	// Connect to the monitor.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		return nil, nil, err // The VM isn't running as no monitor socket available.
 	}
@@ -3792,7 +3792,7 @@ func (vm *qemu) diskState() (map[string]api.InstanceStateDisk, error) {
 // an API call to get the current state.
 func (vm *qemu) agentGetState() (*api.InstanceState, error) {
 	// Check if the agent is running.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		return nil, err
 	}
@@ -3909,7 +3909,7 @@ func (vm *qemu) InitPID() int {
 
 func (vm *qemu) statusCode() api.StatusCode {
 	// Connect to the monitor.
-	monitor, err := qmp.Connect(vm.getMonitorPath(), vm.getMonitorEventHandler())
+	monitor, err := qmp.Connect(vm.monitorPath(), vm.getMonitorEventHandler())
 	if err != nil {
 		// If we fail to connect, chances are the VM isn't running.
 		return api.Stopped

From a49642c88632d11124555cf73ffb9ae74aa3b7bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 6 Jun 2020 21:01:05 -0400
Subject: [PATCH 2/3] lxd/vm: Add virtio-vga card
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           | 15 +++++++++++
 lxd/instance/drivers/driver_qemu_templates.go | 25 +++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 5079f9e7be..5b17f09b30 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -1633,6 +1633,13 @@ func (vm *qemu) generateQemuConfigFile(devConfs []*deviceConfig.RunConfig, fdFil
 		}
 	}
 
+	// GPU for console.
+	err = vm.addVGAConfig(sb, chassisIndex)
+	if err != nil {
+		return "", err
+	}
+	chassisIndex++
+
 	// Write the agent mount config.
 	agentMountJSON, err := json.Marshal(agentMounts)
 	if err != nil {
@@ -1677,6 +1684,14 @@ func (vm *qemu) addVsockConfig(sb *strings.Builder) error {
 	})
 }
 
+// addVGAConfig adds the qemu config required for setting up the host->VM vsock socket.
+func (vm *qemu) addVGAConfig(sb *strings.Builder, chassisIndex int) error {
+	return qemuVGA.Execute(sb, map[string]interface{}{
+		"architecture": vm.architectureName,
+		"chassisIndex": chassisIndex,
+	})
+}
+
 // addCPUConfig adds the qemu config required for setting the number of virtualised CPUs.
 func (vm *qemu) addCPUConfig(sb *strings.Builder) error {
 	// Default to a single core.
diff --git a/lxd/instance/drivers/driver_qemu_templates.go b/lxd/instance/drivers/driver_qemu_templates.go
index a32a777e9d..357cfe1d37 100644
--- a/lxd/instance/drivers/driver_qemu_templates.go
+++ b/lxd/instance/drivers/driver_qemu_templates.go
@@ -166,6 +166,31 @@ driver = "vhost-vsock-ccw"
 {{- end}}
 `))
 
+var qemuVGA = template.Must(template.New("qemuVGA").Parse(`
+# VGA
+{{if eq .architecture "x86_64" "aarch64" -}}
+[device "qemu_pcie{{.chassisIndex}}"]
+driver = "pcie-root-port"
+port = "0x4"
+chassis = "{{.chassisIndex}}"
+bus = "pcie.0"
+addr = "0x4.0x1"
+{{- end }}
+
+[device "dev-qemu_vga"]
+{{if ne .architecture "s390x" -}}
+driver = "virtio-vga"
+{{- if eq .architecture "ppc64le"}}
+bus = "pci.0"
+{{- else}}
+bus = "qemu_pcie{{.chassisIndex}}"
+addr = "0x0"
+{{- end}}
+{{- else}}
+driver = "virtio-gpu-ccw"
+{{- end}}
+`))
+
 var qemuCPU = template.Must(template.New("qemuCPU").Parse(`
 # CPU
 [smp-opts]

From 8e85aeb0d7c7b8439bb2ef5d7c018ff88c9483fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 6 Jun 2020 21:31:12 -0400
Subject: [PATCH 3/3] lxd/vm: Add spice channel
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           | 5 +++++
 lxd/instance/drivers/driver_qemu_templates.go | 6 ++++++
 2 files changed, 11 insertions(+)

diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 5b17f09b30..8510086bd8 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -1167,6 +1167,10 @@ func (vm *qemu) nvramPath() string {
 	return filepath.Join(vm.Path(), "qemu.nvram")
 }
 
+func (vm *qemu) spicePath() string {
+	return filepath.Join(vm.LogPath(), "qemu.spice")
+}
+
 // generateConfigShare generates the config share directory that will be exported to the VM via
 // a 9P share. Due to the unknown size of templates inside the images this directory is created
 // inside the VM's config volume so that it can be restricted by quota.
@@ -1550,6 +1554,7 @@ func (vm *qemu) generateQemuConfigFile(devConfs []*deviceConfig.RunConfig, fdFil
 	err := qemuBase.Execute(sb, map[string]interface{}{
 		"architecture":     vm.architectureName,
 		"ringbufSizeBytes": qmp.RingbufSize,
+		"spicePath":        vm.spicePath(),
 	})
 	if err != nil {
 		return "", err
diff --git a/lxd/instance/drivers/driver_qemu_templates.go b/lxd/instance/drivers/driver_qemu_templates.go
index 357cfe1d37..beccc89c66 100644
--- a/lxd/instance/drivers/driver_qemu_templates.go
+++ b/lxd/instance/drivers/driver_qemu_templates.go
@@ -132,6 +132,12 @@ driver = "virtio-rng-ccw"
 # Console
 [chardev "console"]
 backend = "pty"
+
+# Graphical console
+[spice]
+unix = "on"
+addr = "{{.spicePath}}"
+disable-ticketing = "on"
 `))
 
 var qemuMemory = template.Must(template.New("qemuMemory").Parse(`


More information about the lxc-devel mailing list