From: Jakob Klocker <j.klocker@proxmox.com>
To: pve-devel@lists.proxmox.com
Cc: Jakob Klocker <j.klocker@proxmox.com>
Subject: [PATCH qemu-server 4/6] fix #7213: qmeventd: pass `reset` to `qm cleanup`
Date: Thu, 13 Aug 2026 13:27:15 +0200 [thread overview]
Message-ID: <20260813112717.272254-5-j.klocker@proxmox.com> (raw)
In-Reply-To: <20260813112717.272254-1-j.klocker@proxmox.com>
With '-no-reboot', QEMU exits on a reset request instead of performing
it. The resulting SHUTDOWN event is indistinguishable from the one for
an ordinary shutdown except for its reason field. Evaluate that field
and pass the result on as a fourth argument, which `qm cleanup` needs to
decide whether the VM should be started again.
Both a reset initiated inside the guest (`guest-reset`) and one
requested through QMP (`host-qmp-system-reset`, used by `qm reset` and
the API) are reported: a VM with `powercycle` set is started with
'-no-reboot' either way, so both would otherwise leave it powered off.
Link: https://bugzilla.proxmox.com/show_bug.cgi?id=7213
Signed-off-by: Jakob Klocker <j.klocker@proxmox.com>
---
src/qmeventd/qmeventd.c | 36 ++++++++++++++++++++++++++++--------
src/qmeventd/qmeventd.h | 1 +
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/src/qmeventd/qmeventd.c b/src/qmeventd/qmeventd.c
index 84ee11a1..14b17667 100644
--- a/src/qmeventd/qmeventd.c
+++ b/src/qmeventd/qmeventd.c
@@ -10,12 +10,15 @@
qmeventd listens on a given socket, and waits for qemu processes to
connect. After accepting a connection qmeventd waits for shutdown events
followed by the closing of the socket. Once that happens `qm cleanup` will
- be executed with following three arguments:
- VMID <graceful> <guest>
+ be executed with following four arguments:
+ VMID <graceful> <guest> <reset>
Where `graceful` can be `1` or `0` depending if shutdown event was observed
before the socket got closed. The second parameter `guest` is also boolean
`1` or `0` depending if the shutdown was requested from the guest OS
- (i.e., the "inside").
+ (i.e., the "inside"). The third parameter `reset` is `1` if the shutdown
+ was caused by a reset request rather than an actual shutdown - either from
+ inside the guest or through QMP - which QEMU only reports as a shutdown
+ event when started with `-no-reboot`.
*/
#ifndef _GNU_SOURCE
@@ -207,9 +210,20 @@ void handle_qmp_event(struct Client *client, struct json_object *obj) {
client->qemu.graceful = 1;
struct json_object *data;
struct json_object *guest;
- if (json_object_object_get_ex(obj, "data", &data) &&
- json_object_object_get_ex(data, "guest", &guest)) {
- client->qemu.guest = (unsigned short)json_object_get_boolean(guest);
+ struct json_object *reason;
+
+ if (json_object_object_get_ex(obj, "data", &data) && data) {
+ if (json_object_object_get_ex(data, "guest", &guest)) {
+ client->qemu.guest = (unsigned short)json_object_get_boolean(guest);
+ }
+
+ if (json_object_object_get_ex(data, "reason", &reason)) {
+ const char *reason_str = json_object_get_string(reason);
+ if (reason_str && (!strcmp(reason_str, "guest-reset") ||
+ !strcmp(reason_str, "host-qmp-system-reset"))) {
+ client->qemu.reset = true;
+ }
+ }
}
// check if a backup is running and kill QEMU process if not
@@ -392,11 +406,14 @@ err:
static void cleanup_qemu_client(struct Client *client) {
unsigned short graceful = client->qemu.graceful;
unsigned short guest = client->qemu.guest;
+ bool reset = client->qemu.reset;
char vmid[sizeof(client->qemu.vmid)];
strncpy(vmid, client->qemu.vmid, sizeof(vmid));
vmid[sizeof(vmid) - 1] = '\0';
g_hash_table_remove(vm_clients, &vmid); // frees key, ignore errors
- VERBOSE_PRINT("%s: executing cleanup (graceful: %d, guest: %d)\n", vmid, graceful, guest);
+ VERBOSE_PRINT(
+ "%s: executing cleanup (graceful: %d, guest: %d, reset: %d)\n", vmid, graceful, guest, reset
+ );
int pid = fork();
if (pid < 0) {
@@ -406,7 +423,10 @@ static void cleanup_qemu_client(struct Client *client) {
if (pid == 0) {
char *script = "/usr/sbin/qm";
- char *args[] = {script, "cleanup", vmid, graceful ? "1" : "0", guest ? "1" : "0", NULL};
+ char *args[] = {
+ script, "cleanup", vmid, graceful ? "1" : "0", guest ? "1" : "0", reset ? "1" : "0",
+ NULL
+ };
execvp(script, args);
perror("execvp");
diff --git a/src/qmeventd/qmeventd.h b/src/qmeventd/qmeventd.h
index 6a293b84..36f8bdcc 100644
--- a/src/qmeventd/qmeventd.h
+++ b/src/qmeventd/qmeventd.h
@@ -78,6 +78,7 @@ struct Client {
unsigned short guest;
bool term_check_queued;
bool backup;
+ bool reset;
} qemu;
// only relevant for type=CLIENT_VZDUMP
--
2.47.3
next prev parent reply other threads:[~2026-08-13 11:27 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 11:27 [PATCH docs/manager/qemu-server 0/6] fix #7213: add `powercycle` reboot behavior Jakob Klocker
2026-08-13 11:27 ` [PATCH qemu-server 1/6] qm: do not restart VM when 'reboot' is disabled Jakob Klocker
2026-08-13 11:27 ` [PATCH qemu-server 2/6] fix #7213: config: add `powercycle` sub-property to `reboot` Jakob Klocker
2026-08-13 11:27 ` [PATCH qemu-server 3/6] fix #7213: qm: cleanup: add `reset` parameter to honor `powercycle` Jakob Klocker
2026-08-13 11:27 ` Jakob Klocker [this message]
2026-08-13 11:27 ` [PATCH pve-manager 5/6] ui: qemu: options: add editor for reboot behavior Jakob Klocker
2026-08-13 11:27 ` [PATCH pve-docs 6/6] qm: add reboot behavior information Jakob Klocker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260813112717.272254-5-j.klocker@proxmox.com \
--to=j.klocker@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.