Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/elmarco/tags/option-pull-reques…
Browse files Browse the repository at this point in the history
…t' into staging

CLI help improvements

PULLv2:
 - fix uninitialized "seentype" variable in qom-test

# gpg: Signature made Fri 05 Oct 2018 13:28:21 BST
# gpg:                using RSA key DAE8E10975969CE5
# gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>"
# gpg:                 aka "Marc-André Lureau <marcandre.lureau@gmail.com>"
# Primary key fingerprint: 87A9 BD93 3F87 C606 D276  F62D DAE8 E109 7596 9CE5

* remotes/elmarco/tags/option-pull-request:
  vl: list user creatable properties when 'help' is argument
  hostmem: add some properties description
  vl: handle -object help
  tests/qom-proplist: check class properties iterator
  tests/qom-proplist: check properties are not listed multiple times
  tests/qom-proplist: check duplicate "bv" property registration failed
  qom/object: register 'type' property as class property
  qom/object: fix iterating properties over a class
  qemu-option: improve qemu_opts_print_help() output
  qemu-option: add help fallback to print the list of options
  cutils: add qemu_pstrcmp0()
  qdev-monitor: print help to stdout

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Oct 8, 2018
2 parents e2e3436 + 1195fa2 commit df51a00
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 60 deletions.
9 changes: 9 additions & 0 deletions backends/hostmem-memfd.c
Expand Up @@ -145,16 +145,25 @@ memfd_backend_class_init(ObjectClass *oc, void *data)
memfd_backend_get_hugetlb,
memfd_backend_set_hugetlb,
&error_abort);
object_class_property_set_description(oc, "hugetlb",
"Use huge pages",
&error_abort);
object_class_property_add(oc, "hugetlbsize", "int",
memfd_backend_get_hugetlbsize,
memfd_backend_set_hugetlbsize,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "hugetlbsize",
"Huge pages size (ex: 2M, 1G)",
&error_abort);
}
if (qemu_memfd_check(MFD_ALLOW_SEALING)) {
object_class_property_add_bool(oc, "seal",
memfd_backend_get_seal,
memfd_backend_set_seal,
&error_abort);
object_class_property_set_description(oc, "seal",
"Seal growing & shrinking",
&error_abort);
}
}

Expand Down
14 changes: 14 additions & 0 deletions backends/hostmem.c
Expand Up @@ -397,27 +397,41 @@ host_memory_backend_class_init(ObjectClass *oc, void *data)
object_class_property_add_bool(oc, "merge",
host_memory_backend_get_merge,
host_memory_backend_set_merge, &error_abort);
object_class_property_set_description(oc, "merge",
"Mark memory as mergeable", &error_abort);
object_class_property_add_bool(oc, "dump",
host_memory_backend_get_dump,
host_memory_backend_set_dump, &error_abort);
object_class_property_set_description(oc, "dump",
"Set to 'off' to exclude from core dump", &error_abort);
object_class_property_add_bool(oc, "prealloc",
host_memory_backend_get_prealloc,
host_memory_backend_set_prealloc, &error_abort);
object_class_property_set_description(oc, "prealloc",
"Preallocate memory", &error_abort);
object_class_property_add(oc, "size", "int",
host_memory_backend_get_size,
host_memory_backend_set_size,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "size",
"Size of the memory region (ex: 500M)", &error_abort);
object_class_property_add(oc, "host-nodes", "int",
host_memory_backend_get_host_nodes,
host_memory_backend_set_host_nodes,
NULL, NULL, &error_abort);
object_class_property_set_description(oc, "host-nodes",
"Binds memory to the list of NUMA host nodes", &error_abort);
object_class_property_add_enum(oc, "policy", "HostMemPolicy",
&HostMemPolicy_lookup,
host_memory_backend_get_policy,
host_memory_backend_set_policy, &error_abort);
object_class_property_set_description(oc, "policy",
"Set the NUMA policy", &error_abort);
object_class_property_add_bool(oc, "share",
host_memory_backend_get_share, host_memory_backend_set_share,
&error_abort);
object_class_property_set_description(oc, "share",
"Mark the memory as private to QEMU or shared", &error_abort);
}

static const TypeInfo host_memory_backend_info = {
Expand Down
3 changes: 3 additions & 0 deletions include/monitor/monitor.h
Expand Up @@ -47,4 +47,7 @@ int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd);
void monitor_fdset_dup_fd_remove(int dup_fd);
int monitor_fdset_dup_fd_find(int dup_fd);

void monitor_vfprintf(FILE *stream,
const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);

#endif /* MONITOR_H */
12 changes: 12 additions & 0 deletions include/qemu/cutils.h
Expand Up @@ -169,4 +169,16 @@ bool test_buffer_is_zero_next_accel(void);
int uleb128_encode_small(uint8_t *out, uint32_t n);
int uleb128_decode_small(const uint8_t *in, uint32_t *n);

/**
* qemu_pstrcmp0:
* @str1: a non-NULL pointer to a C string (*str1 can be NULL)
* @str2: a non-NULL pointer to a C string (*str2 can be NULL)
*
* Compares *str1 and *str2 with g_strcmp0().
*
* Returns: an integer less than, equal to, or greater than zero, if
* *str1 is <, == or > than *str2.
*/
int qemu_pstrcmp0(const char **str1, const char **str2);

#endif
16 changes: 13 additions & 3 deletions monitor.c
Expand Up @@ -4493,19 +4493,29 @@ static void monitor_readline_flush(void *opaque)
}

/*
* Print to current monitor if we have one, else to stderr.
* Print to current monitor if we have one, else to stream.
* TODO should return int, so callers can calculate width, but that
* requires surgery to monitor_vprintf(). Left for another day.
*/
void error_vprintf(const char *fmt, va_list ap)
void monitor_vfprintf(FILE *stream, const char *fmt, va_list ap)
{
if (cur_mon && !monitor_cur_is_qmp()) {
monitor_vprintf(cur_mon, fmt, ap);
} else {
vfprintf(stderr, fmt, ap);
vfprintf(stream, fmt, ap);
}
}

/*
* Print to current monitor if we have one, else to stderr.
* TODO should return int, so callers can calculate width, but that
* requires surgery to monitor_vprintf(). Left for another day.
*/
void error_vprintf(const char *fmt, va_list ap)
{
monitor_vfprintf(stderr, fmt, ap);
}

void error_vprintf_unless_qmp(const char *fmt, va_list ap)
{
if (cur_mon && !monitor_cur_is_qmp()) {
Expand Down
32 changes: 19 additions & 13 deletions qdev-monitor.c
Expand Up @@ -104,22 +104,31 @@ static bool qdev_class_has_alias(DeviceClass *dc)
return (qdev_class_get_alias(dc) != NULL);
}

static void out_printf(const char *fmt, ...)
{
va_list ap;

va_start(ap, fmt);
monitor_vfprintf(stdout, fmt, ap);
va_end(ap);
}

static void qdev_print_devinfo(DeviceClass *dc)
{
error_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
out_printf("name \"%s\"", object_class_get_name(OBJECT_CLASS(dc)));
if (dc->bus_type) {
error_printf(", bus %s", dc->bus_type);
out_printf(", bus %s", dc->bus_type);
}
if (qdev_class_has_alias(dc)) {
error_printf(", alias \"%s\"", qdev_class_get_alias(dc));
out_printf(", alias \"%s\"", qdev_class_get_alias(dc));
}
if (dc->desc) {
error_printf(", desc \"%s\"", dc->desc);
out_printf(", desc \"%s\"", dc->desc);
}
if (!dc->user_creatable) {
error_printf(", no-user");
out_printf(", no-user");
}
error_printf("\n");
out_printf("\n");
}

static void qdev_print_devinfos(bool show_no_user)
Expand Down Expand Up @@ -155,8 +164,7 @@ static void qdev_print_devinfos(bool show_no_user)
continue;
}
if (!cat_printed) {
error_printf("%s%s devices:\n", i ? "\n" : "",
cat_name[i]);
out_printf("%s%s devices:\n", i ? "\n" : "", cat_name[i]);
cat_printed = true;
}
qdev_print_devinfo(dc);
Expand Down Expand Up @@ -278,13 +286,11 @@ int qdev_device_help(QemuOpts *opts)
}

for (prop = prop_list; prop; prop = prop->next) {
error_printf("%s.%s=%s", driver,
prop->value->name,
prop->value->type);
out_printf("%s.%s=%s", driver, prop->value->name, prop->value->type);
if (prop->value->has_description) {
error_printf(" (%s)\n", prop->value->description);
out_printf(" (%s)\n", prop->value->description);
} else {
error_printf("\n");
out_printf("\n");
}
}

Expand Down
9 changes: 5 additions & 4 deletions qom/object.c
Expand Up @@ -1115,7 +1115,7 @@ void object_class_property_iter_init(ObjectPropertyIterator *iter,
ObjectClass *klass)
{
g_hash_table_iter_init(&iter->iter, klass->properties);
iter->nextclass = klass;
iter->nextclass = object_class_get_parent(klass);
}

ObjectProperty *object_class_property_find(ObjectClass *klass, const char *name,
Expand Down Expand Up @@ -2430,9 +2430,10 @@ void object_class_property_set_description(ObjectClass *klass,
op->description = g_strdup(description);
}

static void object_instance_init(Object *obj)
static void object_class_init(ObjectClass *klass, void *data)
{
object_property_add_str(obj, "type", qdev_get_type, NULL, NULL);
object_class_property_add_str(klass, "type", qdev_get_type,
NULL, &error_abort);
}

static void register_types(void)
Expand All @@ -2446,7 +2447,7 @@ static void register_types(void)
static TypeInfo object_info = {
.name = TYPE_OBJECT,
.instance_size = sizeof(Object),
.instance_init = object_instance_init,
.class_init = object_class_init,
.abstract = true,
};

Expand Down
6 changes: 3 additions & 3 deletions qom/object_interfaces.c
Expand Up @@ -141,14 +141,14 @@ Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)

int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
{
bool (*type_predicate)(const char *) = opaque;
bool (*type_opt_predicate)(const char *, QemuOpts *) = opaque;
Object *obj = NULL;
Error *err = NULL;
const char *type;

type = qemu_opt_get(opts, "qom-type");
if (type && type_predicate &&
!type_predicate(type)) {
if (type && type_opt_predicate &&
!type_opt_predicate(type, opts)) {
return 0;
}

Expand Down
58 changes: 37 additions & 21 deletions tests/check-qom-proplist.c
Expand Up @@ -125,10 +125,13 @@ static char *dummy_get_sv(Object *obj,

static void dummy_init(Object *obj)
{
Error *err = NULL;

object_property_add_bool(obj, "bv",
dummy_get_bv,
dummy_set_bv,
NULL);
&err);
error_free_or_abort(&err);
}


Expand Down Expand Up @@ -517,32 +520,19 @@ static void test_dummy_getenum(void)
}


static void test_dummy_iterator(void)
static void test_dummy_prop_iterator(ObjectPropertyIterator *iter)
{
Object *parent = object_get_objects_root();
DummyObject *dobj = DUMMY_OBJECT(
object_new_with_props(TYPE_DUMMY,
parent,
"dummy0",
&error_abort,
"bv", "yes",
"sv", "Hiss hiss hiss",
"av", "platypus",
NULL));

bool seenbv = false, seensv = false, seenav = false, seentype = false;
ObjectProperty *prop;
ObjectPropertyIterator iter;
bool seenbv = false, seensv = false, seenav = false, seentype;

object_property_iter_init(&iter, OBJECT(dobj));
while ((prop = object_property_iter_next(&iter))) {
if (g_str_equal(prop->name, "bv")) {
while ((prop = object_property_iter_next(iter))) {
if (!seenbv && g_str_equal(prop->name, "bv")) {
seenbv = true;
} else if (g_str_equal(prop->name, "sv")) {
} else if (!seensv && g_str_equal(prop->name, "sv")) {
seensv = true;
} else if (g_str_equal(prop->name, "av")) {
} else if (!seenav && g_str_equal(prop->name, "av")) {
seenav = true;
} else if (g_str_equal(prop->name, "type")) {
} else if (!seentype && g_str_equal(prop->name, "type")) {
/* This prop comes from the base Object class */
seentype = true;
} else {
Expand All @@ -554,10 +544,35 @@ static void test_dummy_iterator(void)
g_assert(seenav);
g_assert(seensv);
g_assert(seentype);
}

static void test_dummy_iterator(void)
{
Object *parent = object_get_objects_root();
DummyObject *dobj = DUMMY_OBJECT(
object_new_with_props(TYPE_DUMMY,
parent,
"dummy0",
&error_abort,
"bv", "yes",
"sv", "Hiss hiss hiss",
"av", "platypus",
NULL));
ObjectPropertyIterator iter;

object_property_iter_init(&iter, OBJECT(dobj));
test_dummy_prop_iterator(&iter);
object_unparent(OBJECT(dobj));
}

static void test_dummy_class_iterator(void)
{
ObjectPropertyIterator iter;
ObjectClass *klass = object_class_by_name(TYPE_DUMMY);

object_class_property_iter_init(&iter, klass);
test_dummy_prop_iterator(&iter);
}

static void test_dummy_delchild(void)
{
Expand Down Expand Up @@ -629,6 +644,7 @@ int main(int argc, char **argv)
g_test_add_func("/qom/proplist/badenum", test_dummy_badenum);
g_test_add_func("/qom/proplist/getenum", test_dummy_getenum);
g_test_add_func("/qom/proplist/iterator", test_dummy_iterator);
g_test_add_func("/qom/proplist/class_iterator", test_dummy_class_iterator);
g_test_add_func("/qom/proplist/delchild", test_dummy_delchild);
g_test_add_func("/qom/resolve/partial", test_qom_partial_path);

Expand Down
5 changes: 5 additions & 0 deletions util/cutils.c
Expand Up @@ -769,3 +769,8 @@ char *size_to_str(uint64_t val)

return g_strdup_printf("%0.3g %sB", (double)val / div, suffixes[i]);
}

int qemu_pstrcmp0(const char **str1, const char **str2)
{
return g_strcmp0(*str1, *str2);
}

0 comments on commit df51a00

Please sign in to comment.