<...> > + > +MemdevList *qmp_query_memdev(Error **errp) > +{ > + QmpOutputVisitor *ov = qmp_output_visitor_new(); > + QmpInputVisitor *iv; > + QObject *obj; > + MemdevList *list = NULL, *m; > + HostMemoryBackend *backend; > + Error *err = NULL; > + int i; > + > + for (i = 0; i < nb_numa_nodes; i++) { > + backend = numa_info[i].node_memdev; > + > + m = g_malloc0(sizeof(*m)); > + m->value = g_malloc0(sizeof(*m->value)); > + m->value->size = object_property_get_int(OBJECT(backend), "size", > + &err); > + if (err) { > + goto error; > + } > + m->value->policy = object_property_get_str(OBJECT(backend), "policy", > + &err); > + if (err) { > + goto error; > + } > + object_property_get(OBJECT(backend), qmp_output_get_visitor(ov), > + "host-nodes", &err); > + if (err) { > + goto error; > + } > + obj = qmp_output_get_qobject(ov);
Unlike string output visitor, the internal state of qmp output visitor retains, it should be cleaned up at the end of every loop. > + iv = qmp_input_visitor_new(obj); > + qobject_decref(obj); > + > + visit_type_uint16List(qmp_input_get_visitor(iv), > + &m->value->host_nodes, NULL, &err); > + if (err) { > + qmp_input_visitor_cleanup(iv); > + goto error; > + } > + > + m->next = list; > + list = m; > + qmp_input_visitor_cleanup(iv); > + } > + > + qmp_output_visitor_cleanup(ov); > + return list; > + > +error: > + while (list) { > + m = list; > + list = list->next; > + g_free(m->value); > + g_free(m); > + } > + qerror_report_err(err); > + qmp_output_visitor_cleanup(ov); > + return NULL; > +}