From 1ed52714c02205fec2e432470e0880f5519ee5cb Mon Sep 17 00:00:00 2001 From: Manohar Castelino Date: Thu, 2 Sep 2021 15:42:22 -0700 Subject: [PATCH 1/2] qmp: wait for POWERDOWN event in ExecuteSystemPowerdown() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ExecuteSystemPowerdown issues `system_powerdown` and waits for `SHUTDOWN`. The event emitted is `POWERDOWN` per spec. Without this we get an error even though the VM has shutdown gracefully. Per QEMU spec: ``` POWERDOWN (Event) Emitted when the virtual machine is powered down through the power control system, such as via ACPI. Since 0.12 Example <- { "event": "POWERDOWN", "timestamp": { "seconds": 1267040730, "microseconds": 682951 } } SHUTDOWN (Event) Emitted when the virtual machine has shut down, indicating that qemu is about to exit. Arguments guest: boolean If true, the shutdown was triggered by a guest request (such as a guest-initiated ACPI shutdown request or other hardware-specific action) rather than a host request (such as sending qemu a SIGINT). (since 2.10) reason: ShutdownCause The ShutdownCause which resulted in the SHUTDOWN. (since 4.0) Note If the command-line option “-no-shutdown” has been specified, qemu will not exit, and a STOP event will eventually follow the SHUTDOWN event Since 0.12 Example <- { "event": "SHUTDOWN", "data": { "guest": true }, "timestamp": { "seconds": 1267040730, "microseconds": 682951 } } ``` Signed-off-by: Manohar Castelino --- qemu/qmp.go | 2 +- qemu/qmp_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qemu/qmp.go b/qemu/qmp.go index f8a33334c2..a7afc6dcd1 100644 --- a/qemu/qmp.go +++ b/qemu/qmp.go @@ -761,7 +761,7 @@ func (q *QMP) ExecuteCont(ctx context.Context) error { // This function will block until the SHUTDOWN event is received. func (q *QMP) ExecuteSystemPowerdown(ctx context.Context) error { filter := &qmpEventFilter{ - eventName: "SHUTDOWN", + eventName: "POWERDOWN", } return q.executeCommand(ctx, "system_powerdown", nil, filter) } diff --git a/qemu/qmp_test.go b/qemu/qmp_test.go index 38153f914e..d541b284ab 100644 --- a/qemu/qmp_test.go +++ b/qemu/qmp_test.go @@ -802,7 +802,7 @@ func TestQMPSystemPowerdown(t *testing.T) { disconnectedCh := make(chan struct{}) buf := newQMPTestCommandBuffer(t) buf.AddCommand("system_powerdown", nil, "return", nil) - buf.AddEvent("SHUTDOWN", time.Millisecond*100, + buf.AddEvent("POWERDOWN", time.Millisecond*100, nil, map[string]interface{}{ "seconds": seconds, From fe83c208dceef6f9206db43abb5d6c7340df9a1f Mon Sep 17 00:00:00 2001 From: Manohar Castelino Date: Thu, 2 Sep 2021 16:05:06 -0700 Subject: [PATCH 2/2] qemu: Add support for --no-shutdown Knob Add support for --no-shutdown Knob. This allows us to shutdown the VM without quitting QEMU. Note: Also fix the comment around --no-reboot to be more accurate. Signed-off-by: Manohar Castelino --- qemu/qemu.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/qemu/qemu.go b/qemu/qemu.go index ee814a9c6b..13d8ab33a4 100644 --- a/qemu/qemu.go +++ b/qemu/qemu.go @@ -2402,8 +2402,12 @@ type Knobs struct { Realtime bool // Exit instead of rebooting + // Prevents QEMU from rebooting in the event of a Triple Fault. NoReboot bool + // Don’t exit QEMU on guest shutdown, but instead only stop the emulation. + NoShutdown bool + // IOMMUPlatform will enable IOMMU for supported devices IOMMUPlatform bool } @@ -2776,6 +2780,10 @@ func (config *Config) appendKnobs() { config.qemuParams = append(config.qemuParams, "--no-reboot") } + if config.Knobs.NoShutdown { + config.qemuParams = append(config.qemuParams, "--no-shutdown") + } + if config.Knobs.Daemonize { config.qemuParams = append(config.qemuParams, "-daemonize") }