/* test commands that return an error due to invalid parameters */ static void test_dispatch_cmd_failure(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QObject *resp; qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2"))); resp = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp != NULL); assert(qdict_haskey(qobject_to_qdict(resp), "error")); qobject_decref(resp); QDECREF(req); /* check that with extra arguments it throws an error */ req = qdict_new(); qdict_put(args, "a", qint_from_int(66)); qdict_put(req, "arguments", args); qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd"))); resp = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp != NULL); assert(qdict_haskey(qobject_to_qdict(resp), "error")); qobject_decref(resp); QDECREF(req); }
static void qdict_crumple_test_recursive(void) { QDict *src, *dst, *rule, *vnc, *acl, *listen; QList *rules; src = qdict_new(); qdict_put(src, "vnc.listen.addr", qstring_from_str("127.0.0.1")); qdict_put(src, "vnc.listen.port", qstring_from_str("5901")); qdict_put(src, "vnc.acl.rules.0.match", qstring_from_str("fred")); qdict_put(src, "vnc.acl.rules.0.policy", qstring_from_str("allow")); qdict_put(src, "vnc.acl.rules.1.match", qstring_from_str("bob")); qdict_put(src, "vnc.acl.rules.1.policy", qstring_from_str("deny")); qdict_put(src, "vnc.acl.default", qstring_from_str("deny")); qdict_put(src, "vnc.acl..name", qstring_from_str("acl0")); qdict_put(src, "vnc.acl.rule..name", qstring_from_str("acl0")); dst = qobject_to_qdict(qdict_crumple(src, &error_abort)); g_assert(dst); g_assert_cmpint(qdict_size(dst), ==, 1); vnc = qdict_get_qdict(dst, "vnc"); g_assert(vnc); g_assert_cmpint(qdict_size(vnc), ==, 3); listen = qdict_get_qdict(vnc, "listen"); g_assert(listen); g_assert_cmpint(qdict_size(listen), ==, 2); g_assert_cmpstr("127.0.0.1", ==, qdict_get_str(listen, "addr")); g_assert_cmpstr("5901", ==, qdict_get_str(listen, "port")); acl = qdict_get_qdict(vnc, "acl"); g_assert(acl); g_assert_cmpint(qdict_size(acl), ==, 3); rules = qdict_get_qlist(acl, "rules"); g_assert(rules); g_assert_cmpint(qlist_size(rules), ==, 2); rule = qobject_to_qdict(qlist_pop(rules)); g_assert(rule); g_assert_cmpint(qdict_size(rule), ==, 2); g_assert_cmpstr("fred", ==, qdict_get_str(rule, "match")); g_assert_cmpstr("allow", ==, qdict_get_str(rule, "policy")); QDECREF(rule); rule = qobject_to_qdict(qlist_pop(rules)); g_assert(rule); g_assert_cmpint(qdict_size(rule), ==, 2); g_assert_cmpstr("bob", ==, qdict_get_str(rule, "match")); g_assert_cmpstr("deny", ==, qdict_get_str(rule, "policy")); QDECREF(rule); /* With recursive crumpling, we should see all names unescaped */ g_assert_cmpstr("acl0", ==, qdict_get_str(vnc, "acl.name")); g_assert_cmpstr("acl0", ==, qdict_get_str(acl, "rule.name")); QDECREF(src); QDECREF(dst); }
static void qerror_set_data(QError *qerr, const char *fmt, va_list *va) { QObject *obj; obj = qobject_from_jsonv(fmt, va); if (!obj) { qerror_abort(qerr, "invalid format '%s'", fmt); } if (qobject_type(obj) != QTYPE_QDICT) { qerror_abort(qerr, "error format is not a QDict '%s'", fmt); } qerr->error = qobject_to_qdict(obj); obj = qdict_get(qerr->error, "class"); if (!obj) { qerror_abort(qerr, "missing 'class' key in '%s'", fmt); } if (qobject_type(obj) != QTYPE_QSTRING) { qerror_abort(qerr, "'class' key value should be a QString"); } obj = qdict_get(qerr->error, "data"); if (!obj) { qerror_abort(qerr, "missing 'data' key in '%s'", fmt); } if (qobject_type(obj) != QTYPE_QDICT) { qerror_abort(qerr, "'data' key value should be a QDICT"); } }
/* This function is hooked as final emit function, which can verify the correctness. */ static void event_test_emit(test_QAPIEvent event, QDict *d, Error **errp) { QObject *obj; QDict *t; int64_t s, ms; /* Verify that we have timestamp, then remove it to compare other fields */ obj = qdict_get(d, "timestamp"); g_assert(obj); t = qobject_to_qdict(obj); g_assert(t); obj = qdict_get(t, "seconds"); g_assert(obj && qobject_type(obj) == QTYPE_QINT); s = qint_get_int(qobject_to_qint(obj)); obj = qdict_get(t, "microseconds"); g_assert(obj && qobject_type(obj) == QTYPE_QINT); ms = qint_get_int(qobject_to_qint(obj)); if (s == -1) { g_assert(ms == -1); } else { g_assert(ms >= 0 && ms <= 999999); } g_assert(qdict_size(t) == 2); qdict_del(d, "timestamp"); g_assert(qdict_cmp_simple(d, test_event_data->expect)); }
/* test commands that involve both input parameters and return values */ static void test_dispatch_cmd_io(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QDict *ud1a = qdict_new(); QDict *ud1b = qdict_new(); QObject *resp; qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42))); qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello"))); qdict_put_obj(ud1b, "integer", QOBJECT(qint_from_int(422))); qdict_put_obj(ud1b, "string", QOBJECT(qstring_from_str("hello2"))); qdict_put_obj(args, "ud1a", QOBJECT(ud1a)); qdict_put_obj(args, "ud1b", QOBJECT(ud1b)); qdict_put_obj(req, "arguments", QOBJECT(args)); qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2"))); /* TODO: put in full payload and check for errors */ resp = qmp_dispatch(QOBJECT(req)); assert(resp != NULL); assert(!qdict_haskey(qobject_to_qdict(resp), "error")); g_print("\nresp: %s\n", qstring_get_str(qobject_to_json_pretty(resp))); qobject_decref(resp); QDECREF(req); }
static void qobject_to_qdict_test(void) { QDict *tests_dict = qdict_new(); g_assert(qobject_to_qdict(QOBJECT(tests_dict)) == tests_dict); QDECREF(tests_dict); }
static void add_pc_test_cases(void) { QDict *response, *minfo; QList *list; const QListEntry *p; QObject *qobj; QString *qstr; const char *mname, *path; PCTestData *data; qtest_start("-machine none"); response = qmp("{ 'execute': 'query-machines' }"); g_assert(response); list = qdict_get_qlist(response, "return"); g_assert(list); for (p = qlist_first(list); p; p = qlist_next(p)) { minfo = qobject_to_qdict(qlist_entry_obj(p)); g_assert(minfo); qobj = qdict_get(minfo, "name"); g_assert(qobj); qstr = qobject_to_qstring(qobj); g_assert(qstr); mname = qstring_get_str(qstr); if (!g_str_has_prefix(mname, "pc-")) { continue; } data = g_malloc(sizeof(PCTestData)); data->machine = mname; data->cpu_model = "Haswell"; /* 1.3+ theoretically */ data->sockets = 1; data->cores = 3; data->threads = 2; data->maxcpus = data->sockets * data->cores * data->threads * 2; if (g_str_has_suffix(mname, "-1.4") || (strcmp(mname, "pc-1.3") == 0) || (strcmp(mname, "pc-1.2") == 0) || (strcmp(mname, "pc-1.1") == 0) || (strcmp(mname, "pc-1.0") == 0) || (strcmp(mname, "pc-0.15") == 0) || (strcmp(mname, "pc-0.14") == 0) || (strcmp(mname, "pc-0.13") == 0) || (strcmp(mname, "pc-0.12") == 0) || (strcmp(mname, "pc-0.11") == 0) || (strcmp(mname, "pc-0.10") == 0)) { path = g_strdup_printf("cpu/%s/init/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); qtest_add_data_func(path, data, test_pc_without_cpu_add); } else { path = g_strdup_printf("cpu/%s/add/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, data->threads, data->maxcpus); qtest_add_data_func(path, data, test_pc_with_cpu_add); } } qtest_end(); }
static int process_cpu_info(QemuHttpConnection *conn) { CPUState *env; QList *cpu_list; int i; cpu_list = qlist_new(); for (env = first_cpu; env != NULL; env = env->next_cpu) { QDict *cpu; QObject *obj; obj = qobject_from_jsonf("{ 'CPU': %d }", env->cpu_index); cpu = qobject_to_qdict(obj); qdict_put(cpu, "eip", qint_from_int(env->eip + env->segs[R_CS].base)); qdict_put(cpu, "eax", qint_from_int(EAX)); qdict_put(cpu, "ebx", qint_from_int(EBX)); qdict_put(cpu, "ecx", qint_from_int(ECX)); qdict_put(cpu, "edx", qint_from_int(EDX)); qdict_put(cpu, "esp", qint_from_int(ESP)); qdict_put(cpu, "ebp", qint_from_int(EBP)); qdict_put(cpu, "esi", qint_from_int(ESI)); qdict_put(cpu, "edi", qint_from_int(EDI)); qdict_put(cpu, "dt", qint_from_int(dev_time)); qdict_put(cpu, "qt", qint_from_int(qemu_time)); #ifdef CONFIG_PROFILER qdict_put(cpu, "tb_count", qint_from_int(tcg_ctx.tb_count)); qdict_put(cpu, "tb_count1", qint_from_int(tcg_ctx.tb_count1)); qdict_put(cpu, "op_count", qint_from_int(tcg_ctx.op_count)); qdict_put(cpu, "op_count_max", qint_from_int(tcg_ctx.op_count_max)); qdict_put(cpu, "temp_count", qint_from_int(tcg_ctx.temp_count)); qdict_put(cpu, "temp_count_max", qint_from_int(tcg_ctx.temp_count_max)); qdict_put(cpu, "del_op_count", qint_from_int(tcg_ctx.del_op_count)); qdict_put(cpu, "code_in_len", qint_from_int(tcg_ctx.code_in_len)); qdict_put(cpu, "code_out_len", qint_from_int(tcg_ctx.code_out_len)); qdict_put(cpu, "interm_time", qint_from_int(tcg_ctx.interm_time)); qdict_put(cpu, "code_time", qint_from_int(tcg_ctx.code_time)); qdict_put(cpu, "la_time", qint_from_int(tcg_ctx.la_time)); qdict_put(cpu, "restore_count", qint_from_int(tcg_ctx.restore_count)); qdict_put(cpu, "restore_time", qint_from_int(tcg_ctx.restore_time)); for (i = INDEX_op_end; i < NB_OPS; i++) { qdict_put(cpu, tcg_op_defs[i].name, qint_from_int(tcg_table_op_count[i])); } #endif qlist_append(cpu_list, cpu); } int st = 0; st = respond_with_json(conn, QOBJECT(cpu_list)); qobject_decref(QOBJECT(cpu_list)); return st; }
/* Only compares bool, int, string */ static void qdict_cmp_do_simple(const char *key, QObject *obj1, void *opaque) { QObject *obj2; QDictCmpData d_new, *d = opaque; if (!d->result) { return; } obj2 = qdict_get(d->expect, key); if (!obj2) { d->result = false; return; } if (qobject_type(obj1) != qobject_type(obj2)) { d->result = false; return; } switch (qobject_type(obj1)) { case QTYPE_QBOOL: d->result = (qbool_get_bool(qobject_to_qbool(obj1)) == qbool_get_bool(qobject_to_qbool(obj2))); return; case QTYPE_QINT: d->result = (qint_get_int(qobject_to_qint(obj1)) == qint_get_int(qobject_to_qint(obj2))); return; case QTYPE_QSTRING: d->result = g_strcmp0(qstring_get_str(qobject_to_qstring(obj1)), qstring_get_str(qobject_to_qstring(obj2))) == 0; return; case QTYPE_QDICT: d_new.expect = qobject_to_qdict(obj2); d_new.result = true; qdict_iter(qobject_to_qdict(obj1), qdict_cmp_do_simple, &d_new); d->result = d_new.result; return; default: abort(); } }
static void test_qga_get_vcpus(gconstpointer fix) { const TestFixture *fixture = fix; QDict *ret; QList *list; const QListEntry *entry; ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-vcpus'}"); g_assert_nonnull(ret); qmp_assert_no_error(ret); /* check there is at least a cpu */ list = qdict_get_qlist(ret, "return"); entry = qlist_first(list); g_assert(qdict_haskey(qobject_to_qdict(entry->value), "online")); g_assert(qdict_haskey(qobject_to_qdict(entry->value), "logical-id")); QDECREF(ret); }
static void test_qga_get_fsinfo(gconstpointer fix) { const TestFixture *fixture = fix; QDict *ret; QList *list; const QListEntry *entry; ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-fsinfo'}"); g_assert_nonnull(ret); qmp_assert_no_error(ret); /* check there is at least a fs */ list = qdict_get_qlist(ret, "return"); entry = qlist_first(list); g_assert(qdict_haskey(qobject_to_qdict(entry->value), "name")); g_assert(qdict_haskey(qobject_to_qdict(entry->value), "mountpoint")); g_assert(qdict_haskey(qobject_to_qdict(entry->value), "type")); g_assert(qdict_haskey(qobject_to_qdict(entry->value), "disk")); QDECREF(ret); }
void error_set_qobject(Error **errp, QObject *obj) { Error *err; if (errp == NULL) { return; } err = g_malloc0(sizeof(*err)); err->obj = qobject_to_qdict(obj); qobject_incref(obj); *errp = err; }
void monitor_print_balloon(Monitor *mon, const QObject *data) { QDict *qdict; qdict = qobject_to_qdict(data); if (!qdict_haskey(qdict, "actual")) { return; } monitor_printf(mon, "balloon: actual=%" PRId64, qdict_get_int(qdict, "actual") >> 20); qdict_iter(qdict, print_balloon_stat, mon); monitor_printf(mon, "\n"); }
static void migrate_print_status(Monitor *mon, const char *name, const QDict *status_dict) { QDict *qdict; qdict = qobject_to_qdict(qdict_get(status_dict, name)); monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name, qdict_get_int(qdict, "transferred") >> 10); monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name, qdict_get_int(qdict, "remaining") >> 10); monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name, qdict_get_int(qdict, "total") >> 10); }
/* test commands with no input and no return value */ static void test_dispatch_cmd(void) { QDict *req = qdict_new(); QObject *resp; qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd"))); resp = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp != NULL); assert(!qdict_haskey(qobject_to_qdict(resp), "error")); qobject_decref(resp); QDECREF(req); }
/* handle requests/control events coming in over the channel */ static void process_event(JSONMessageParser *parser, QList *tokens) { GAState *s = container_of(parser, GAState, parser); QObject *obj; QDict *qdict; Error *err = NULL; int ret; g_assert(s && parser); g_debug("process_event: called"); obj = json_parser_parse_err(tokens, NULL, &err); if (err || !obj || qobject_type(obj) != QTYPE_QDICT) { qobject_decref(obj); qdict = qdict_new(); if (!err) { g_warning("failed to parse event: unknown error"); error_set(&err, QERR_JSON_PARSING); } else { g_warning("failed to parse event: %s", error_get_pretty(err)); } qdict_put_obj(qdict, "error", error_get_qobject(err)); error_free(err); } else { qdict = qobject_to_qdict(obj); } g_assert(qdict); /* handle host->guest commands */ if (qdict_haskey(qdict, "execute")) { process_command(s, qdict); } else { if (!qdict_haskey(qdict, "error")) { QDECREF(qdict); qdict = qdict_new(); g_warning("unrecognized payload format"); error_set(&err, QERR_UNSUPPORTED); qdict_put_obj(qdict, "error", error_get_qobject(err)); error_free(err); } ret = conn_channel_send_payload(s->conn_channel, QOBJECT(qdict)); if (ret) { g_warning("error sending payload: %s", strerror(ret)); } } QDECREF(qdict); }
/* test commands that involve both input parameters and return values */ static void test_dispatch_cmd_io(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QDict *args3 = qdict_new(); QDict *ud1a = qdict_new(); QDict *ud1b = qdict_new(); QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef; QDict *ret_dict_dict2, *ret_dict_dict2_userdef; QNum *ret3; int64_t val; qdict_put_int(ud1a, "integer", 42); qdict_put_str(ud1a, "string", "hello"); qdict_put_int(ud1b, "integer", 422); qdict_put_str(ud1b, "string", "hello2"); qdict_put(args, "ud1a", ud1a); qdict_put(args, "ud1b", ud1b); qdict_put(req, "arguments", args); qdict_put_str(req, "execute", "user_def_cmd2"); ret = qobject_to_qdict(test_qmp_dispatch(req)); assert(!strcmp(qdict_get_str(ret, "string0"), "blah1")); ret_dict = qdict_get_qdict(ret, "dict1"); assert(!strcmp(qdict_get_str(ret_dict, "string1"), "blah2")); ret_dict_dict = qdict_get_qdict(ret_dict, "dict2"); ret_dict_dict_userdef = qdict_get_qdict(ret_dict_dict, "userdef"); assert(qdict_get_int(ret_dict_dict_userdef, "integer") == 42); assert(!strcmp(qdict_get_str(ret_dict_dict_userdef, "string"), "hello")); assert(!strcmp(qdict_get_str(ret_dict_dict, "string"), "blah3")); ret_dict_dict2 = qdict_get_qdict(ret_dict, "dict3"); ret_dict_dict2_userdef = qdict_get_qdict(ret_dict_dict2, "userdef"); assert(qdict_get_int(ret_dict_dict2_userdef, "integer") == 422); assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2")); assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4")); QDECREF(ret); qdict_put_int(args3, "a", 66); qdict_put(req, "arguments", args3); qdict_put_str(req, "execute", "guest-get-time"); ret3 = qobject_to_qnum(test_qmp_dispatch(req)); g_assert(qnum_get_try_int(ret3, &val)); g_assert_cmpint(val, ==, 66); QDECREF(ret3); QDECREF(req); }
/* test commands that return an error due to invalid parameters */ static void test_dispatch_cmd_error(void) { QDict *req = qdict_new(); QObject *resp; qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2"))); resp = qmp_dispatch(QOBJECT(req)); assert(resp != NULL); assert(qdict_haskey(qobject_to_qdict(resp), "error")); g_print("\nresp: %s\n", qstring_get_str(qobject_to_json_pretty(resp))); qobject_decref(resp); QDECREF(req); }
static void test_device_intro_concrete(void) { QList *types; QListEntry *entry; const char *type; qtest_start(common_args); types = device_type_list(false); QLIST_FOREACH_ENTRY(types, entry) { type = qdict_get_try_str(qobject_to_qdict(qlist_entry_obj(entry)), "name"); g_assert(type); test_one_device(type); }
static QObject *test_qmp_dispatch(QDict *req) { QObject *resp_obj; QDict *resp; QObject *ret; resp_obj = qmp_dispatch(&qmp_commands, QOBJECT(req)); assert(resp_obj); resp = qobject_to_qdict(resp_obj); assert(resp && !qdict_haskey(resp, "error")); ret = qdict_get(resp, "return"); assert(ret); qobject_incref(ret); qobject_decref(resp_obj); return ret; }
/* test commands that involve both input parameters and return values */ static void test_dispatch_cmd_io(void) { QDict *req = qdict_new(); QDict *args = qdict_new(); QDict *args3 = qdict_new(); QDict *ud1a = qdict_new(); QDict *ud1b = qdict_new(); QDict *ret, *ret_dict, *ret_dict_dict, *ret_dict_dict_userdef; QDict *ret_dict_dict2, *ret_dict_dict2_userdef; QInt *ret3; qdict_put_obj(ud1a, "integer", QOBJECT(qint_from_int(42))); qdict_put_obj(ud1a, "string", QOBJECT(qstring_from_str("hello"))); qdict_put_obj(ud1b, "integer", QOBJECT(qint_from_int(422))); qdict_put_obj(ud1b, "string", QOBJECT(qstring_from_str("hello2"))); qdict_put_obj(args, "ud1a", QOBJECT(ud1a)); qdict_put_obj(args, "ud1b", QOBJECT(ud1b)); qdict_put_obj(req, "arguments", QOBJECT(args)); qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2"))); ret = qobject_to_qdict(test_qmp_dispatch(req)); assert(!strcmp(qdict_get_str(ret, "string0"), "blah1")); ret_dict = qdict_get_qdict(ret, "dict1"); assert(!strcmp(qdict_get_str(ret_dict, "string1"), "blah2")); ret_dict_dict = qdict_get_qdict(ret_dict, "dict2"); ret_dict_dict_userdef = qdict_get_qdict(ret_dict_dict, "userdef"); assert(qdict_get_int(ret_dict_dict_userdef, "integer") == 42); assert(!strcmp(qdict_get_str(ret_dict_dict_userdef, "string"), "hello")); assert(!strcmp(qdict_get_str(ret_dict_dict, "string"), "blah3")); ret_dict_dict2 = qdict_get_qdict(ret_dict, "dict3"); ret_dict_dict2_userdef = qdict_get_qdict(ret_dict_dict2, "userdef"); assert(qdict_get_int(ret_dict_dict2_userdef, "integer") == 422); assert(!strcmp(qdict_get_str(ret_dict_dict2_userdef, "string"), "hello2")); assert(!strcmp(qdict_get_str(ret_dict_dict2, "string"), "blah4")); QDECREF(ret); qdict_put(args3, "a", qint_from_int(66)); qdict_put(req, "arguments", args3); qdict_put(req, "execute", qstring_from_str("guest-get-time")); ret3 = qobject_to_qint(test_qmp_dispatch(req)); assert(qint_get_int(ret3) == 66); QDECREF(ret3); QDECREF(req); }
void do_info_migrate_print(Monitor *mon, const QObject *data) { QDict *qdict; qdict = qobject_to_qdict(data); monitor_printf(mon, "Migration status: %s\n", qdict_get_str(qdict, "status")); if (qdict_haskey(qdict, "ram")) { migrate_print_status(mon, "ram", qdict); } if (qdict_haskey(qdict, "disk")) { migrate_print_status(mon, "disk", qdict); } }
void error_set(Error **errp, const char *fmt, ...) { Error *err; va_list ap; if (errp == NULL) { return; } err = g_malloc0(sizeof(*err)); va_start(ap, fmt); err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap)); va_end(ap); err->fmt = fmt; *errp = err; }
/* handle requests/control events coming in over the channel */ static void process_event(JSONMessageParser *parser, GQueue *tokens) { GAState *s = container_of(parser, GAState, parser); QDict *qdict; Error *err = NULL; int ret; g_assert(s && parser); g_debug("process_event: called"); qdict = qobject_to_qdict(json_parser_parse_err(tokens, NULL, &err)); if (err || !qdict) { QDECREF(qdict); qdict = qdict_new(); if (!err) { g_warning("failed to parse event: unknown error"); error_setg(&err, QERR_JSON_PARSING); } else { g_warning("failed to parse event: %s", error_get_pretty(err)); } qdict_put_obj(qdict, "error", qmp_build_error_object(err)); error_free(err); } /* handle host->guest commands */ if (qdict_haskey(qdict, "execute")) { process_command(s, qdict); } else { if (!qdict_haskey(qdict, "error")) { QDECREF(qdict); qdict = qdict_new(); g_warning("unrecognized payload format"); error_setg(&err, QERR_UNSUPPORTED); qdict_put_obj(qdict, "error", qmp_build_error_object(err)); error_free(err); } ret = send_response(s, QOBJECT(qdict)); if (ret < 0) { g_warning("error sending error response: %s", strerror(-ret)); } } QDECREF(qdict); }
static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) { const QObject *qobj; if (qiv->nb_stack == 0) { qobj = qiv->obj; } else { qobj = qiv->stack[qiv->nb_stack - 1].obj; } if (name && qobject_type(qobj) == QTYPE_QDICT) { return qdict_get(qobject_to_qdict(qobj), name); } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) { return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); } return qobj; }
static QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name, bool consume) { QObject *qobj = qiv->stack[qiv->nb_stack - 1].obj; if (qobj) { if (name && qobject_type(qobj) == QTYPE_QDICT) { if (qiv->stack[qiv->nb_stack - 1].h && consume) { g_hash_table_remove(qiv->stack[qiv->nb_stack - 1].h, name); } return qdict_get(qobject_to_qdict(qobj), name); } else if (qiv->stack[qiv->nb_stack - 1].entry) { return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry); } } return qobj; }
static const char *append_field(QDict *error, QString *outstr, const QErrorStringTable *entry, const char *start) { QObject *obj; QDict *qdict; QString *key_qs; const char *end, *key; if (*start != '%') parse_error(entry, '%'); start++; if (*start != '(') parse_error(entry, '('); start++; end = strchr(start, ')'); if (!end) parse_error(entry, ')'); key_qs = qstring_from_substr(start, 0, end - start - 1); key = qstring_get_str(key_qs); qdict = qobject_to_qdict(qdict_get(error, "data")); obj = qdict_get(qdict, key); if (!obj) { abort(); } switch (qobject_type(obj)) { case QTYPE_QSTRING: qstring_append(outstr, qdict_get_str(qdict, key)); break; case QTYPE_QINT: qstring_append_int(outstr, qdict_get_int(qdict, key)); break; default: abort(); } QDECREF(key_qs); return ++end; }
static const char *append_field(QString *outstr, const QError *qerror, const char *start) { QObject *obj; QDict *qdict; QString *key_qs; const char *end, *key; if (*start != '%') parse_error(qerror, '%'); start++; if (*start != '(') parse_error(qerror, '('); start++; end = strchr(start, ')'); if (!end) parse_error(qerror, ')'); key_qs = qstring_from_substr(start, 0, end - start - 1); key = qstring_get_str(key_qs); qdict = qobject_to_qdict(qdict_get(qerror->error, "data")); obj = qdict_get(qdict, key); if (!obj) { qerror_abort(qerror, "key '%s' not found in QDict", key); } switch (qobject_type(obj)) { case QTYPE_QSTRING: qstring_append(outstr, qdict_get_str(qdict, key)); break; case QTYPE_QINT: qstring_append_int(outstr, qdict_get_int(qdict, key)); break; default: qerror_abort(qerror, "invalid type '%c'", qobject_type(obj)); } QDECREF(key_qs); return ++end; }
static void qdict_destroy_obj(QObject *obj) { int i; QDict *qdict; assert(obj != NULL); qdict = qobject_to_qdict(obj); for (i = 0; i < QDICT_HASH_SIZE; i++) { QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); while (entry) { QDictEntry *tmp = QLIST_NEXT(entry, next); QLIST_REMOVE(entry, next); qentry_destroy(entry); entry = tmp; } } qemu_free(qdict); }
static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp) { const QDictEntry *ent; const char *arg_name; const QObject *arg_obj; bool has_exec_key = false; QDict *dict = NULL; if (qobject_type(request) != QTYPE_QDICT) { error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "request is not a dictionary"); return NULL; } dict = qobject_to_qdict(request); for (ent = qdict_first(dict); ent; ent = qdict_next(dict, ent)) { arg_name = qdict_entry_key(ent); arg_obj = qdict_entry_value(ent); if (!strcmp(arg_name, "execute")) { if (qobject_type(arg_obj) != QTYPE_QSTRING) { error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute", "string"); return NULL; } has_exec_key = true; } else if (strcmp(arg_name, "arguments")) { error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name); return NULL; } } if (!has_exec_key) { error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute"); return NULL; } return dict; }