On Wed, Jul 01, 2026 at 08:32:06AM +0200, Markus Armbruster wrote:
marcandre.lureau@redhat.com writes:
The default monitor is usually a long lived object that will exist for the entire lifetime of the VM. A monitor can only service a single client at a time though, and so it might be desirable to hotplug additional monitors at runtime for specific tasks. If doing that, however, there is a need to remove the monitor when it is no longer needed.
Whatever adds the additional monitor can also delete it. The fact that you propose other means suggests you believe this would be cumbersome in practice. Why?
Allowing a client to run "object-del" against its own monitor adds complex edge cases, as it would be desirable to send the QMP response despite the monitor sending it being deleted. Doing "object-del" alone will also result in orphaning a character device backend instance, as there is no opportunity to run the companion "chardev-del" command.
A simpler way to ensure cleanup is to add the concept of auto-deleting monitor objects. Specifically when the "CHR_EVENT_CLOSED" event is emitted, the equivalent of "object-del" + "chardev-del" can be run internally. Since the transient client has already droppped its monitor connection, there is no synchronization to be concerned about.
If object-del or chardev-del fail, there's no way to report the error. Can they fail?
Do we always want to delete both monitor and character device?
This is implemented via a new "close-action=none|delete" property on the 'monitor-qmp' object. This concept could be extended with further actions in future, for example:
* close-action=shutdown - graceful guest shutdown * close-action=terminate - immediate guest poweroff * close-action=stop - pause guest CPUs while the monitor is not connected to any client
I'm not sure these would be useful and safe. Mentioning them here is okay regardless.
This is left as an exercise for future interested contributors.
Tested-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-ID: <20260624173752.2928717-33-berrange@redhat.com>
snip
diff --git a/monitor/monitor-internal.h b/monitor/monitor-internal.h index 5522e05464b..23829f32f9a 100644 --- a/monitor/monitor-internal.h +++ b/monitor/monitor-internal.h
snip
+static void monitor_qmp_self_delete_bh(void *opaque) +{ + MonitorQMP *mon = opaque; + g_autofree char *mon_id = object_property_get_child_name( + object_get_objects_root(), OBJECT(mon)); + g_autofree char *chardev_id = g_strdup(mon->parent_obj.chardev_id); + Error *local_error = NULL; + + if (!mon_id) { + /* Another monitor raced & ran 'object-del' on 'mon' + * before this BH got scheduled, so we have a ref on + * mon but it is already unparented. + */ + object_unref(mon); + return; + } + + user_creatable_del(mon_id, &local_error); + object_unref(mon);
This object_unref() and the one above pair with the object_ref() in monitor_qmp_event() case MONITOR_QMP_CLOSE_ACTION_DELETE. Correct?
Is this worth a comment?
+ if (local_error != NULL) { + error_report_err(local_error); + } else { + qmp_chardev_remove(chardev_id, NULL); + } +} + static void monitor_qmp_event(void *opaque, QEMUChrEvent event) { QDict *data; MonitorQMP *mon = opaque;
+ /* Protect against race if a client drops & quickly + * reconnects - we'll have the delete BH scheduled + * so must not honour a new open request + */ + if (mon->delete_pending) { + return; + }
Consider "something happens between setting @delete_pending and monitor destruction that triggers the event" and "same thing happens after destruction". Any observable differences in behavior?
Are there any other monitor interactions that might need similar special-casing when @delete_pending?
When the BH deletes the monitor object, it will disconnect the chardev handlers. So there is no possibility of monitor_qmp_event being called after the monitor QOM destruction is complete. The only race is between this method and the start of the BH. With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|