From ad9cb0ba58a57c7a75a672cdf845f64c4a97adc6 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Wed, 23 Nov 2022 14:22:28 +0100 Subject: [PATCH] govmm: Optionally pass QMP listener to QEMU QEMU's -qmp option can be passed the file descriptor of a socket that is already in listening mode. This is done with by passing `fd=XXX` to `-qmp` instead of a path. Note that these two options are mutually exclusive : QEMU errors out if both are passed, so we check that as well in the validation function. While here add the `path=` stanza in the path based case for clarity. Signed-off-by: Greg Kurz (cherry picked from commit 8a4f08cb0f7c5471cb4fe274eca0d79ba8539c27) Signed-off-by: Greg Kurz --- src/runtime/pkg/govmm/qemu/qemu.go | 14 +++++++++++-- src/runtime/pkg/govmm/qemu/qemu_test.go | 26 ++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/runtime/pkg/govmm/qemu/qemu.go b/src/runtime/pkg/govmm/qemu/qemu.go index 4b36df2ea3..b47a8fb175 100644 --- a/src/runtime/pkg/govmm/qemu/qemu.go +++ b/src/runtime/pkg/govmm/qemu/qemu.go @@ -2327,6 +2327,9 @@ type QMPSocket struct { // Type is the socket type (e.g. "unix"). Type QMPSocketType + // QMP listener file descriptor to be passed to qemu + FD *os.File + // Name is the socket name. Name string @@ -2339,7 +2342,8 @@ type QMPSocket struct { // Valid returns true if the QMPSocket structure is valid and complete. func (qmp QMPSocket) Valid() bool { - if qmp.Type == "" || qmp.Name == "" { + // Exactly one of Name of FD must be set. + if qmp.Type == "" || (qmp.Name == "") == (qmp.FD == nil) { return false } @@ -2679,7 +2683,13 @@ func (config *Config) appendQMPSockets() { continue } - qmpParams := append([]string{}, fmt.Sprintf("%s:%s", q.Type, q.Name)) + var qmpParams []string + if q.FD != nil { + qemuFDs := config.appendFDs([]*os.File{q.FD}) + qmpParams = append([]string{}, fmt.Sprintf("%s:fd=%d", q.Type, qemuFDs[0])) + } else { + qmpParams = append([]string{}, fmt.Sprintf("%s:path=%s", q.Type, q.Name)) + } if q.Server { qmpParams = append(qmpParams, "server=on") if q.NoWait { diff --git a/src/runtime/pkg/govmm/qemu/qemu_test.go b/src/runtime/pkg/govmm/qemu/qemu_test.go index 501c07fdf1..563a9f7fb1 100644 --- a/src/runtime/pkg/govmm/qemu/qemu_test.go +++ b/src/runtime/pkg/govmm/qemu/qemu_test.go @@ -698,8 +698,8 @@ func TestFailToAppendCPUs(t *testing.T) { } } -var qmpSingleSocketServerString = "-qmp unix:cc-qmp,server=on,wait=off" -var qmpSingleSocketString = "-qmp unix:cc-qmp" +var qmpSingleSocketServerString = "-qmp unix:path=cc-qmp,server=on,wait=off" +var qmpSingleSocketString = "-qmp unix:path=cc-qmp" func TestAppendSingleQMPSocketServer(t *testing.T) { qmp := QMPSocket{ @@ -722,7 +722,27 @@ func TestAppendSingleQMPSocket(t *testing.T) { testAppend(qmp, qmpSingleSocketString, t) } -var qmpSocketServerString = "-qmp unix:cc-qmp-1,server=on,wait=off -qmp unix:cc-qmp-2,server=on,wait=off" +var qmpSocketServerFdString = "-qmp unix:fd=3,server=on,wait=off" + +func TestAppendQMPSocketServerFd(t *testing.T) { + foo, _ := os.CreateTemp(os.TempDir(), "govmm-qemu-test") + + defer func() { + _ = foo.Close() + _ = os.Remove(foo.Name()) + }() + + qmp := QMPSocket{ + Type: "unix", + FD: foo, + Server: true, + NoWait: true, + } + + testAppend(qmp, qmpSocketServerFdString, t) +} + +var qmpSocketServerString = "-qmp unix:path=cc-qmp-1,server=on,wait=off -qmp unix:path=cc-qmp-2,server=on,wait=off" func TestAppendQMPSocketServer(t *testing.T) { qmp := []QMPSocket{