static void qdict_iterapi_test(void) { int count; const QDictEntry *ent; QDict *tests_dict = qdict_new(); g_assert(qdict_first(tests_dict) == NULL); qdict_put(tests_dict, "key1", qint_from_int(1)); qdict_put(tests_dict, "key2", qint_from_int(2)); qdict_put(tests_dict, "key3", qint_from_int(3)); count = 0; for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){ g_assert(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1); count++; } g_assert(count == qdict_size(tests_dict)); /* Do it again to test restarting */ count = 0; for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){ g_assert(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1); count++; } g_assert(count == qdict_size(tests_dict)); QDECREF(tests_dict); }
static QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob, Error **errp) { const char *exec_key = NULL; const QDictEntry *ent; const char *arg_name; const QObject *arg_obj; QDict *dict; dict = qobject_to(QDict, request); if (!dict) { error_setg(errp, "QMP input must be a JSON object"); return NULL; } 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") || (!strcmp(arg_name, "exec-oob") && allow_oob)) { if (qobject_type(arg_obj) != QTYPE_QSTRING) { error_setg(errp, "QMP input member '%s' must be a string", arg_name); return NULL; } if (exec_key) { error_setg(errp, "QMP input member '%s' clashes with '%s'", arg_name, exec_key); return NULL; } exec_key = arg_name; } else if (!strcmp(arg_name, "arguments")) { if (qobject_type(arg_obj) != QTYPE_QDICT) { error_setg(errp, "QMP input member 'arguments' must be an object"); return NULL; } } else if (!strcmp(arg_name, "id")) { continue; } else { error_setg(errp, "QMP input member '%s' is unexpected", arg_name); return NULL; } } if (!exec_key) { error_setg(errp, "QMP input lacks member 'execute'"); return NULL; } return dict; }
static int qdict_count_entries(QDict *dict) { const QDictEntry *e; int count = 0; for (e = qdict_first(dict); e; e = qdict_next(dict, e)) { count++; } return count; }
static bool ssh_has_filename_options_conflict(QDict *options, Error **errp) { const QDictEntry *qe; for (qe = qdict_first(options); qe; qe = qdict_next(options, qe)) { if (!strcmp(qe->key, "host") || !strcmp(qe->key, "port") || !strcmp(qe->key, "path") || !strcmp(qe->key, "user") || !strcmp(qe->key, "host_key_check") || strstart(qe->key, "server.", NULL)) { error_setg(errp, "Option '%s' cannot be used with a file name", qe->key); return true; } } return false; }
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; }
void update_insn_class_info(const char* class_idx, const char* insn) { // Assuming class indexes are positive const QDictEntry* pentry; int64_t idx= -1; assert(class_info != NULL); pentry = qdict_first(class_info); do { QObject* temp = qdict_entry_value(pentry); QDict* pdict = qobject_to_qdict(temp); idx = qdict_get_int(pdict, "idx"); const char * str = qdict_get_str(pdict, "class_name"); if(strcmp(str, class_idx) == 0) break; idx = -1; pentry = qdict_next(class_info, pentry); } while(pentry != NULL); assert(insn_map != NULL); if(idx != -1) get_map_entry(insn)->instruction_type = idx; }
static bool nfs_has_filename_options_conflict(QDict *options, Error **errp) { const QDictEntry *qe; for (qe = qdict_first(options); qe; qe = qdict_next(options, qe)) { if (!strcmp(qe->key, "host") || !strcmp(qe->key, "path") || !strcmp(qe->key, "user") || !strcmp(qe->key, "group") || !strcmp(qe->key, "tcp-syn-count") || !strcmp(qe->key, "readahead-size") || !strcmp(qe->key, "page-cache-size") || !strcmp(qe->key, "debug") || strstart(qe->key, "server.", NULL)) { error_setg(errp, "Option %s cannot be used with a filename", qe->key); return true; } } return false; }
Object *user_creatable_add_type(const char *type, const char *id, const QDict *qdict, Visitor *v, Error **errp) { Object *obj; ObjectClass *klass; const QDictEntry *e; Error *local_err = NULL; klass = object_class_by_name(type); if (!klass) { error_setg(errp, "invalid object type: %s", type); return NULL; } if (!object_class_dynamic_cast(klass, TYPE_USER_CREATABLE)) { error_setg(errp, "object type '%s' isn't supported by object-add", type); return NULL; } if (object_class_is_abstract(klass)) { error_setg(errp, "object type '%s' is abstract", type); return NULL; } assert(qdict); obj = object_new(type); visit_start_struct(v, NULL, NULL, 0, &local_err); if (local_err) { goto out; } for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { object_property_set(obj, v, e->key, &local_err); if (local_err) { break; } } if (!local_err) { visit_check_struct(v, &local_err); } visit_end_struct(v, NULL); if (local_err) { goto out; } if (id != NULL) { object_property_add_child(object_get_objects_root(), id, obj, &local_err); if (local_err) { goto out; } } user_creatable_complete(USER_CREATABLE(obj), &local_err); if (local_err) { if (id != NULL) { object_property_del(object_get_objects_root(), id, &error_abort); } goto out; } out: if (local_err) { error_propagate(errp, local_err); object_unref(obj); return NULL; } return obj; }
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVRBDState *s = bs->opaque; BlockdevOptionsRbd *opts = NULL; const QDictEntry *e; Error *local_err = NULL; char *keypairs, *secretid; int r; keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs")); if (keypairs) { qdict_del(options, "=keyvalue-pairs"); } secretid = g_strdup(qdict_get_try_str(options, "password-secret")); if (secretid) { qdict_del(options, "password-secret"); } r = qemu_rbd_convert_options(options, &opts, &local_err); if (local_err) { /* If keypairs are present, that means some options are present in * the modern option format. Don't attempt to parse legacy option * formats, as we won't support mixed usage. */ if (keypairs) { error_propagate(errp, local_err); goto out; } /* If the initial attempt to convert and process the options failed, * we may be attempting to open an image file that has the rbd options * specified in the older format consisting of all key/value pairs * encoded in the filename. Go ahead and attempt to parse the * filename, and see if we can pull out the required options. */ r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs); if (r < 0) { /* Propagate the original error, not the legacy parsing fallback * error, as the latter was just a best-effort attempt. */ error_propagate(errp, local_err); goto out; } /* Take care whenever deciding to actually deprecate; once this ability * is removed, we will not be able to open any images with legacy-styled * backing image strings. */ warn_report("RBD options encoded in the filename as keyvalue pairs " "is deprecated"); } /* Remove the processed options from the QDict (the visitor processes * _all_ options in the QDict) */ while ((e = qdict_first(options))) { qdict_del(options, e->key); } r = qemu_rbd_connect(&s->cluster, &s->io_ctx, opts, !(flags & BDRV_O_NOCACHE), keypairs, secretid, errp); if (r < 0) { goto out; } s->snap = g_strdup(opts->snapshot); s->image_name = g_strdup(opts->image); /* rbd_open is always r/w */ r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap); if (r < 0) { error_setg_errno(errp, -r, "error reading header from %s", s->image_name); goto failed_open; } /* If we are using an rbd snapshot, we must be r/o, otherwise * leave as-is */ if (s->snap != NULL) { r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp); if (r < 0) { rbd_close(s->image); goto failed_open; } } r = 0; goto out; failed_open: rados_ioctx_destroy(s->io_ctx); g_free(s->snap); g_free(s->image_name); rados_shutdown(s->cluster); out: qapi_free_BlockdevOptionsRbd(opts); g_free(keypairs); g_free(secretid); return r; }
static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, Error **errp) { const QDict *qdict = NULL; const QDictEntry *e; Visitor *visitor; ObjectClass *oc; S390CPU *cpu; Object *obj; if (info->props) { qdict = qobject_to_qdict(info->props); if (!qdict) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "props", "dict"); return; } } oc = cpu_class_by_name(TYPE_S390_CPU, info->name); if (!oc) { error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name); return; } if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) { error_setg(errp, "The CPU definition '%s' requires KVM", info->name); return; } obj = object_new(object_class_get_name(oc)); cpu = S390_CPU(obj); if (!cpu->model) { error_setg(errp, "Details about the host CPU model are not available, " "it cannot be used."); object_unref(obj); return; } if (qdict) { visitor = qobject_input_visitor_new(info->props); visit_start_struct(visitor, NULL, NULL, 0, errp); if (*errp) { object_unref(obj); return; } for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) { object_property_set(obj, visitor, e->key, errp); if (*errp) { break; } } if (!*errp) { visit_check_struct(visitor, errp); } visit_end_struct(visitor, NULL); visit_free(visitor); if (*errp) { object_unref(obj); return; } } /* copy the model and throw the cpu away */ memcpy(model, cpu->model, sizeof(*model)); object_unref(obj); }
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVRBDState *s = bs->opaque; BlockdevOptionsRbd *opts = NULL; Visitor *v; QObject *crumpled = NULL; const QDictEntry *e; Error *local_err = NULL; const char *filename; char *keypairs, *secretid; int r; /* If we are given a filename, parse the filename, with precedence given to * filename encoded options */ filename = qdict_get_try_str(options, "filename"); if (filename) { warn_report("'filename' option specified. " "This is an unsupported option, and may be deprecated " "in the future"); qemu_rbd_parse_filename(filename, options, &local_err); qdict_del(options, "filename"); if (local_err) { error_propagate(errp, local_err); return -EINVAL; } } keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs")); if (keypairs) { qdict_del(options, "=keyvalue-pairs"); } secretid = g_strdup(qdict_get_try_str(options, "password-secret")); if (secretid) { qdict_del(options, "password-secret"); } /* Convert the remaining options into a QAPI object */ crumpled = qdict_crumple(options, errp); if (crumpled == NULL) { r = -EINVAL; goto out; } v = qobject_input_visitor_new_keyval(crumpled); visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err); visit_free(v); qobject_unref(crumpled); if (local_err) { error_propagate(errp, local_err); r = -EINVAL; goto out; } /* Remove the processed options from the QDict (the visitor processes * _all_ options in the QDict) */ while ((e = qdict_first(options))) { qdict_del(options, e->key); } r = qemu_rbd_connect(&s->cluster, &s->io_ctx, opts, !(flags & BDRV_O_NOCACHE), keypairs, secretid, errp); if (r < 0) { goto out; } s->snap = g_strdup(opts->snapshot); s->image_name = g_strdup(opts->image); /* rbd_open is always r/w */ r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap); if (r < 0) { error_setg_errno(errp, -r, "error reading header from %s", s->image_name); goto failed_open; } /* If we are using an rbd snapshot, we must be r/o, otherwise * leave as-is */ if (s->snap != NULL) { if (!bdrv_is_read_only(bs)) { error_report("Opening rbd snapshots without an explicit " "read-only=on option is deprecated. Future versions " "will refuse to open the image instead of " "automatically marking the image read-only."); r = bdrv_set_read_only(bs, true, &local_err); if (r < 0) { error_propagate(errp, local_err); goto failed_open; } } } r = 0; goto out; failed_open: rados_ioctx_destroy(s->io_ctx); g_free(s->snap); g_free(s->image_name); rados_shutdown(s->cluster); out: qapi_free_BlockdevOptionsRbd(opts); g_free(keypairs); g_free(secretid); return r; }
static void qdict_rename_keys_test(void) { QDict *dict = qdict_new(); QDict *copy; QDictRenames *renames; Error *local_err = NULL; qdict_put_str(dict, "abc", "foo"); qdict_put_str(dict, "abcdef", "bar"); qdict_put_int(dict, "number", 42); qdict_put_bool(dict, "flag", true); qdict_put_null(dict, "nothing"); /* Empty rename list */ renames = (QDictRenames[]) { { NULL, "this can be anything" } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &error_abort); g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true); g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Simple rename of all entries */ renames = (QDictRenames[]) { { "abc", "str1" }, { "abcdef", "str2" }, { "number", "int" }, { "flag", "bool" }, { "nothing", "null" }, { NULL , NULL } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &error_abort); g_assert(!qdict_haskey(copy, "abc")); g_assert(!qdict_haskey(copy, "abcdef")); g_assert(!qdict_haskey(copy, "number")); g_assert(!qdict_haskey(copy, "flag")); g_assert(!qdict_haskey(copy, "nothing")); g_assert_cmpstr(qdict_get_str(copy, "str1"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "str2"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "int"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "bool"), ==, true); g_assert(qobject_type(qdict_get(copy, "null")) == QTYPE_QNULL); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Renames are processed top to bottom */ renames = (QDictRenames[]) { { "abc", "tmp" }, { "abcdef", "abc" }, { "number", "abcdef" }, { "flag", "number" }, { "nothing", "flag" }, { "tmp", "nothing" }, { NULL , NULL } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &error_abort); g_assert_cmpstr(qdict_get_str(copy, "nothing"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "abcdef"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "number"), ==, true); g_assert(qobject_type(qdict_get(copy, "flag")) == QTYPE_QNULL); g_assert(!qdict_haskey(copy, "tmp")); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Conflicting rename */ renames = (QDictRenames[]) { { "abcdef", "abc" }, { NULL , NULL } }; copy = qdict_clone_shallow(dict); qdict_rename_keys(copy, renames, &local_err); g_assert(local_err != NULL); error_free(local_err); local_err = NULL; g_assert_cmpstr(qdict_get_str(copy, "abc"), ==, "foo"); g_assert_cmpstr(qdict_get_str(copy, "abcdef"), ==, "bar"); g_assert_cmpint(qdict_get_int(copy, "number"), ==, 42); g_assert_cmpint(qdict_get_bool(copy, "flag"), ==, true); g_assert(qobject_type(qdict_get(copy, "nothing")) == QTYPE_QNULL); g_assert_cmpint(qdict_count_entries(copy), ==, 5); qobject_unref(copy); /* Renames in an empty dict */ renames = (QDictRenames[]) { { "abcdef", "abc" }, { NULL , NULL } }; qobject_unref(dict); dict = qdict_new(); qdict_rename_keys(dict, renames, &error_abort); g_assert(qdict_first(dict) == NULL); qobject_unref(dict); }