mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 13:30:52 +00:00
Merge remote-tracking branch 'qmp-unstable/queue/qmp' into staging
* qmp-unstable/queue/qmp: monitor: Cleanup mon->outbuf on write error virtio_rng: replace custom backend API with UserCreatable.complete() callback add optional 2nd stage initialization to -object/object-add commands vl.c: -object: don't ignore duplicate 'id' object_add: consolidate error handling Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
2f61120c10
@ -12,6 +12,7 @@
|
||||
|
||||
#include "sysemu/rng.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
|
||||
void rng_backend_request_entropy(RngBackend *s, size_t size,
|
||||
EntropyReceiveFunc *receive_entropy,
|
||||
@ -40,9 +41,9 @@ static bool rng_backend_prop_get_opened(Object *obj, Error **errp)
|
||||
return s->opened;
|
||||
}
|
||||
|
||||
void rng_backend_open(RngBackend *s, Error **errp)
|
||||
static void rng_backend_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
object_property_set_bool(OBJECT(s), true, "opened", errp);
|
||||
object_property_set_bool(OBJECT(uc), true, "opened", errp);
|
||||
}
|
||||
|
||||
static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
|
||||
@ -76,13 +77,25 @@ static void rng_backend_init(Object *obj)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void rng_backend_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
|
||||
|
||||
ucc->complete = rng_backend_complete;
|
||||
}
|
||||
|
||||
static const TypeInfo rng_backend_info = {
|
||||
.name = TYPE_RNG_BACKEND,
|
||||
.parent = TYPE_OBJECT,
|
||||
.instance_size = sizeof(RngBackend),
|
||||
.instance_init = rng_backend_init,
|
||||
.class_size = sizeof(RngBackendClass),
|
||||
.class_init = rng_backend_class_init,
|
||||
.abstract = true,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_USER_CREATABLE },
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
static void register_types(void)
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "hw/virtio/virtio-rng.h"
|
||||
#include "sysemu/rng.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
|
||||
static bool is_guest_ready(VirtIORNG *vrng)
|
||||
{
|
||||
@ -148,6 +149,14 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp)
|
||||
if (vrng->conf.rng == NULL) {
|
||||
vrng->conf.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM));
|
||||
|
||||
user_creatable_complete(OBJECT(vrng->conf.default_backend),
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
object_unref(OBJECT(vrng->conf.default_backend));
|
||||
return;
|
||||
}
|
||||
|
||||
object_property_add_child(OBJECT(dev),
|
||||
"default-backend",
|
||||
OBJECT(vrng->conf.default_backend),
|
||||
@ -166,12 +175,6 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
rng_backend_open(vrng->rng, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
vrng->vq = virtio_add_queue(vdev, 8, handle_input);
|
||||
|
||||
assert(vrng->conf.max_bytes <= INT64_MAX);
|
||||
|
62
include/qom/object_interfaces.h
Normal file
62
include/qom/object_interfaces.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef OBJECT_INTERFACES_H
|
||||
#define OBJECT_INTERFACES_H
|
||||
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_USER_CREATABLE "user-creatable"
|
||||
|
||||
#define USER_CREATABLE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(UserCreatableClass, (klass), \
|
||||
TYPE_USER_CREATABLE)
|
||||
#define USER_CREATABLE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(UserCreatableClass, (obj), \
|
||||
TYPE_USER_CREATABLE)
|
||||
#define USER_CREATABLE(obj) \
|
||||
INTERFACE_CHECK(UserCreatable, (obj), \
|
||||
TYPE_USER_CREATABLE)
|
||||
|
||||
|
||||
typedef struct UserCreatable {
|
||||
/* <private> */
|
||||
Object Parent;
|
||||
} UserCreatable;
|
||||
|
||||
/**
|
||||
* UserCreatableClass:
|
||||
* @parent_class: the base class
|
||||
* @complete: callback to be called after @obj's properties are set.
|
||||
*
|
||||
* Interface is designed to work with -object/object-add/object_add
|
||||
* commands.
|
||||
* Interface is mandatory for objects that are designed to be user
|
||||
* creatable (i.e. -object/object-add/object_add, will accept only
|
||||
* objects that inherit this interface).
|
||||
*
|
||||
* Interface also provides an optional ability to do the second
|
||||
* stage * initialization of the object after its properties were
|
||||
* set.
|
||||
*
|
||||
* For objects created without using -object/object-add/object_add,
|
||||
* @user_creatable_complete() wrapper should be called manually if
|
||||
* object's type implements USER_CREATABLE interface and needs
|
||||
* complete() callback to be called.
|
||||
*/
|
||||
typedef struct UserCreatableClass {
|
||||
/* <private> */
|
||||
InterfaceClass parent_class;
|
||||
|
||||
/* <public> */
|
||||
void (*complete)(UserCreatable *uc, Error **errp);
|
||||
} UserCreatableClass;
|
||||
|
||||
/**
|
||||
* user_creatable_complete:
|
||||
* @obj: the object whose complete() method is called if defined
|
||||
* @errp: if an error occurs, a pointer to an area to store the error
|
||||
*
|
||||
* Wrapper to call complete() method if one of types it's inherited
|
||||
* from implements USER_CREATABLE interface, otherwise the call does
|
||||
* nothing.
|
||||
*/
|
||||
void user_creatable_complete(Object *obj, Error **errp);
|
||||
#endif
|
@ -79,15 +79,4 @@ void rng_backend_request_entropy(RngBackend *s, size_t size,
|
||||
* to stop tracking any request.
|
||||
*/
|
||||
void rng_backend_cancel_requests(RngBackend *s);
|
||||
|
||||
/**
|
||||
* rng_backend_open:
|
||||
* @s: the backend to open
|
||||
* @errp: a pointer to return the #Error object if an error occurs.
|
||||
*
|
||||
* This function will open the backend if it is not already open. Calling this
|
||||
* function on an already opened backend will not result in an error.
|
||||
*/
|
||||
void rng_backend_open(RngBackend *s, Error **errp);
|
||||
|
||||
#endif
|
||||
|
@ -288,8 +288,8 @@ void monitor_flush(Monitor *mon)
|
||||
|
||||
if (len && !mon->mux_out) {
|
||||
rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len);
|
||||
if (rc == len) {
|
||||
/* all flushed */
|
||||
if ((rc < 0 && errno != EAGAIN) || (rc == len)) {
|
||||
/* all flushed or error */
|
||||
QDECREF(mon->outbuf);
|
||||
mon->outbuf = qstring_new();
|
||||
return;
|
||||
|
22
qmp.c
22
qmp.c
@ -27,6 +27,7 @@
|
||||
#include "qapi/qmp/qobject.h"
|
||||
#include "qapi/qmp-input-visitor.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
|
||||
NameInfo *qmp_query_name(Error **errp)
|
||||
{
|
||||
@ -549,15 +550,28 @@ void object_add(const char *type, const char *id, const QDict *qdict,
|
||||
for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
|
||||
object_property_set(obj, v, e->key, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
object_unref(obj);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
|
||||
error_setg(&local_err, "object '%s' isn't supported by object-add",
|
||||
id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
user_creatable_complete(obj, &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
object_property_add_child(container_get(object_get_root(), "/objects"),
|
||||
id, obj, errp);
|
||||
id, obj, &local_err);
|
||||
out:
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
object_unref(obj);
|
||||
}
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
common-obj-y = object.o container.o qom-qobject.o
|
||||
common-obj-y += cpu.o
|
||||
common-obj-y += object_interfaces.o
|
||||
|
32
qom/object_interfaces.c
Normal file
32
qom/object_interfaces.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
void user_creatable_complete(Object *obj, Error **errp)
|
||||
{
|
||||
|
||||
UserCreatableClass *ucc;
|
||||
UserCreatable *uc =
|
||||
(UserCreatable *)object_dynamic_cast(obj, TYPE_USER_CREATABLE);
|
||||
|
||||
if (!uc) {
|
||||
return;
|
||||
}
|
||||
|
||||
ucc = USER_CREATABLE_GET_CLASS(uc);
|
||||
if (ucc->complete) {
|
||||
ucc->complete(uc, errp);
|
||||
}
|
||||
}
|
||||
|
||||
static void register_types(void)
|
||||
{
|
||||
static const TypeInfo uc_interface_info = {
|
||||
.name = TYPE_USER_CREATABLE,
|
||||
.parent = TYPE_INTERFACE,
|
||||
.class_size = sizeof(UserCreatableClass),
|
||||
};
|
||||
|
||||
type_register_static(&uc_interface_info);
|
||||
}
|
||||
|
||||
type_init(register_types)
|
22
vl.c
22
vl.c
@ -170,6 +170,7 @@ int main(int argc, char **argv)
|
||||
|
||||
#include "ui/qemu-spice.h"
|
||||
#include "qapi/string-input-visitor.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
|
||||
//#define DEBUG_NET
|
||||
//#define DEBUG_SLIRP
|
||||
@ -2800,6 +2801,7 @@ static int object_create(QemuOpts *opts, void *opaque)
|
||||
{
|
||||
const char *type = qemu_opt_get(opts, "qom-type");
|
||||
const char *id = qemu_opts_id(opts);
|
||||
Error *local_err = NULL;
|
||||
Object *obj;
|
||||
|
||||
g_assert(type != NULL);
|
||||
@ -2815,9 +2817,27 @@ static int object_create(QemuOpts *opts, void *opaque)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!object_dynamic_cast(obj, TYPE_USER_CREATABLE)) {
|
||||
error_setg(&local_err, "object '%s' isn't supported by -object",
|
||||
id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
user_creatable_complete(obj, &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
object_property_add_child(container_get(object_get_root(), "/objects"),
|
||||
id, obj, NULL);
|
||||
id, obj, &local_err);
|
||||
|
||||
out:
|
||||
object_unref(obj);
|
||||
if (local_err) {
|
||||
qerror_report_err(local_err);
|
||||
error_free(local_err);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user