On Wed, Jul 01, 2026 at 08:32:06AM +0200, Markus Armbruster wrote:
> [email protected] 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 <[email protected]>
> >> Signed-off-by: Daniel P. Berrangé <[email protected]>
> >> Message-ID: <[email protected]>
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 :|