From d6dd99e98681920eb26b9d16eaa3924ae1ac11a4 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Thu, 24 Nov 2022 18:43:40 +0100 Subject: [PATCH] govmm: Optionally start QMP with a pre-configured connection When QEMU is launched daemonized, we have the guarantee that the QMP socket is available. In order to launch a non-daemonized QEMU, the QMP connection should be created before QEMU is started in order to avoid a race. Introduce a variant of QMPStart() that can use such an existing connection. Signed-off-by: Greg Kurz (cherry picked from commit 219bb8e7d02fdcf54853e4ce2f926d9add1f16ec) Signed-off-by: Greg Kurz --- src/runtime/pkg/govmm/qemu/qmp.go | 10 ++++++++++ src/runtime/pkg/govmm/qemu/qmp_test.go | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/runtime/pkg/govmm/qemu/qmp.go b/src/runtime/pkg/govmm/qemu/qmp.go index 24c92b9b20..2103b7f79b 100644 --- a/src/runtime/pkg/govmm/qemu/qmp.go +++ b/src/runtime/pkg/govmm/qemu/qmp.go @@ -702,6 +702,16 @@ func QMPStart(ctx context.Context, socket string, cfg QMPConfig, disconnectedCh return nil, nil, err } + return QMPStartWithConn(ctx, conn, cfg, disconnectedCh) +} + +// Same as QMPStart but with a pre-established connection +func QMPStartWithConn(ctx context.Context, conn net.Conn, cfg QMPConfig, disconnectedCh chan struct{}) (*QMP, *QMPVersion, error) { + if conn == nil { + close(disconnectedCh) + return nil, nil, fmt.Errorf("invalid connection") + } + connectedCh := make(chan *QMPVersion) q := startQMPLoop(conn, cfg, connectedCh, disconnectedCh) diff --git a/src/runtime/pkg/govmm/qemu/qmp_test.go b/src/runtime/pkg/govmm/qemu/qmp_test.go index 3f82fa54f9..c6bee11e7d 100644 --- a/src/runtime/pkg/govmm/qemu/qmp_test.go +++ b/src/runtime/pkg/govmm/qemu/qmp_test.go @@ -273,6 +273,22 @@ func TestQMPStartBadPath(t *testing.T) { <-disconnectedCh } +// Checks that a call to QMPStartWithConn with a nil connection exits gracefully. +// +// We call QMPStartWithConn with a nil connection. +// +// An error should be returned and the disconnected channel should be closed. +func TestQMPStartWithConnNil(t *testing.T) { + cfg := QMPConfig{Logger: qmpTestLogger{}} + disconnectedCh := make(chan struct{}) + q, _, err := QMPStartWithConn(context.Background(), nil, cfg, disconnectedCh) + if err == nil { + t.Errorf("Expected error") + q.Shutdown() + } + <-disconnectedCh +} + // Checks that the qmp_capabilities command is correctly sent. // // We start a QMPLoop, send the qmp_capabilities command and stop the