On Thu, Aug 20, 2026 at 4:17 PM Markus Armbruster <[email protected]> wrote:
>
> Zhang Chen <[email protected]> writes:
>
> > Display holder information in info iothreads to aid manual debugging.
> > Omit the holders line when an IOThread has no holders.
> >
> > Signed-off-by: Zhang Chen <[email protected]>
> > ---
> >  monitor/hmp-cmds.c | 21 +++++++++++++++++++++
> >  1 file changed, 21 insertions(+)
> >
> > diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> > index e9fb8d827a..41a813e79f 100644
> > --- a/monitor/hmp-cmds.c
> > +++ b/monitor/hmp-cmds.c
> > @@ -240,11 +240,32 @@ void hmp_info_iothreads(Monitor *mon, const QDict 
> > *qdict)
> >      IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
> >      IOThreadInfoList *info;
> >      IOThreadInfo *value;
> > +    IOThreadHolderList *h;
> >
> >      for (info = info_list; info; info = info->next) {
> >          value = info->value;
> >          monitor_printf(mon, "%s:\n", value->id);
> >          monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
> > +        monitor_printf(mon, "  holders=");
> > +        for (h = value->holders; h; h = h->next) {
> > +            IOThreadHolder *holder = h->value;
> > +
> > +            switch (holder->type) {
> > +            case IO_THREAD_HOLDER_KIND_BLOCK_EXPORT:
> > +                monitor_printf(mon, "[block-export: %s]",
> > +                               holder->u.block_export.export_id);
> > +                break;
> > +            case IO_THREAD_HOLDER_KIND_QOM_OBJECT:
> > +                monitor_printf(mon, "[qom-path: %s]",
> > +                               holder->u.qom_object.qom_path);
> > +                break;
> > +            default:
> > +                monitor_printf(mon, "[unknown]");
> > +                break;
>
> This is unreachable.  Please use
>
>                default:
>                    g_assert_not_reached();
>
> to make it obvious.
>
> > +            }
> > +        }
> > +        monitor_printf(mon, "\n");
> > +
> >          monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", 
> > value->poll_max_ns);
> >          monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
> >          monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", 
> > value->poll_shrink);
>
> Quick test:
>
>     $ qemu-system-x86_64 -S -nodefaults -display none -chardev 
> socket,id=chr-qmp,path=test-qmp,server=on,wait=off -object 
> monitor-qmp,id=qmp,chardev=chr-qmp -monitor stdio
>     QEMU 11.1.50 monitor - type 'help' for more information
>     (qemu) info iothreads
>     (qemu) q
>
> Hmm, no output?  The QMP monitor should be holding the monitor I/O
> thread.  To confirm that, I made monitor_complete() print things (patch
> appended), and got
>
>     ### monitor qmp holding iothread mon_iothread
>     ### monitor compat_monitor0 without iothread
>
> What's going on here?
>

This is expected with the existing query-iothreads behavior.
mon_iothread is created under the internal object root, while
qmp_query_iothreads() only walks /objects, so internal IOThreads are
intentionally not exposed through QMP/HMP.

I prefer to preserve that behavior in this series, since exposing internal
IOThreads would require additional API decisions, including handling ID
collisions with user-created IOThreads.

I’ll also change the unreachable default case to
g_assert_not_reached().

Thanks
Chen



>
> diff --git a/monitor/monitor.c b/monitor/monitor.c
> index 26e7ef4d35..57672dbe0e 100644
> --- a/monitor/monitor.c
> +++ b/monitor/monitor.c
> @@ -751,8 +751,13 @@ static void monitor_complete(UserCreatable *uc, Error 
> **errp)
>          };
>
>          mon->ctx = iothread_ref_and_get_aio_context(mon_iothread, 
> &io_holder);
> +        printf("### monitor %s holding iothread %s\n",
> +               object_get_canonical_path_component(OBJECT(mon)),
> +               iothread_get_id(mon_iothread));
>      } else {
>          mon->ctx = qemu_get_aio_context();
> +        printf("### monitor %s without iothread\n",
> +               object_get_canonical_path_component(OBJECT(mon)));
>      }
>      mon->accept_input_bh = aio_bh_new(mon->ctx, monitor_accept_input, mon);
>  }
>

Reply via email to