[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