QOM/QTest infrastructure fixes
* QOM machine memory and build fixes * QOM link<> and child<> property reference counting fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJTKg+kAAoJEPou0S0+fgE/VoIP/0V9g3IzNHnLCmEUeS1TIy1T aCbjB1vzVu1cZPtV/afvD6WmhQivODlS82pioS93FxU0E52zx4U+roN1w81mer6R 9+ylYL27bH6I0VAyE68wD+C2HDZCgYSwZ2LPsOk9V1xlHad4cfmtrB+KEyd6dMdf II4FNyo3aYRodLbA/gWR0ZI86oVaS0HtZtZMI2OANpT+aKZYWDMnrDdEGKo92PEU QGKI6esmGEbm5DkKpHpUjjus8ml6AbfnFsT8adKnhw+t//IiZhAyfMadgySZ6yPO 35FRx/qHEoTiIDgbR4Nmhn4qJCXtyzufWT+jI9ARZ1SSrwRWX7uZQoaDW0J++5c+ 8W0mzhy0+9B0CwOnK31DcKqDSE6WAF8c8MYqwCC9fk6JlHmYsJh2Messw6ZxF2EP 2Rg3CeCM4XK4V+E+dy2aQWaOAEQ3XUGifA/n4LGwhrOAM/KXTy5XJOuCbEqhd3gz CPELYNubEG8mncPE/6A1IxdaVk+4FSvlzrtRlRmLmJKypSXjZ2vcAgo9P0LyRgDf 4mKuXTl1XgNYDtD+X2+5lrCCyZ23Z1L/kaPpZphlj3HrdAxvNWEYQZHMLTflMy1i HRAqxcZvwzz0ecZWTrpVBEnrgHR1YV5p+p/MdPG4w0+QplpGqPn+FQHOqrEYL+ub Q/A9y1c8CORaTx2P+OiP =+i1T -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/afaerber/tags/qom-devices-for-2.0' into staging QOM/QTest infrastructure fixes * QOM machine memory and build fixes * QOM link<> and child<> property reference counting fixes # gpg: Signature made Wed 19 Mar 2014 21:44:04 GMT using RSA key ID 3E7E013F # gpg: Good signature from "Andreas Färber <afaerber@suse.de>" # gpg: aka "Andreas Färber <afaerber@suse.com>" * remotes/afaerber/tags/qom-devices-for-2.0: virtio-rng: Avoid default_backend refcount leak qom: Add check() argument to object_property_add_link() qom: Make QOM link property unref optional qom: Don't make link NULL on object_property_set_link() failure qom: Split object_property_set_link() vl.c: Fix OpenBSD compilation issue due to namespace collisions vl.c: Fix memory leak in qemu_register_machine() Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
037b7addb7
|
@ -21,6 +21,18 @@ void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
|
|||
}
|
||||
}
|
||||
|
||||
void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name,
|
||||
Object *val, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
|
||||
if (dev->realized) {
|
||||
error_setg(errp, "Attempt to set link property '%s' on device '%s' "
|
||||
"(type '%s') after it was realized",
|
||||
name, dev->id, object_get_typename(obj));
|
||||
}
|
||||
}
|
||||
|
||||
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
|
||||
{
|
||||
void *ptr = dev;
|
||||
|
|
|
@ -98,6 +98,8 @@ static void bus_add_child(BusState *bus, DeviceState *child)
|
|||
object_property_add_link(OBJECT(bus), name,
|
||||
object_get_typename(OBJECT(child)),
|
||||
(Object **)&kid->child,
|
||||
NULL, /* read-only property */
|
||||
0, /* return ownership on prop deletion */
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -824,7 +826,8 @@ static void device_initfn(Object *obj)
|
|||
} while (class != object_class_by_name(TYPE_DEVICE));
|
||||
|
||||
object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS,
|
||||
(Object **)&dev->parent_bus, &error_abort);
|
||||
(Object **)&dev->parent_bus, NULL, 0,
|
||||
&error_abort);
|
||||
}
|
||||
|
||||
static void device_post_init(Object *obj)
|
||||
|
@ -944,7 +947,10 @@ static void qbus_initfn(Object *obj)
|
|||
QTAILQ_INIT(&bus->children);
|
||||
object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
|
||||
TYPE_HOTPLUG_HANDLER,
|
||||
(Object **)&bus->hotplug_handler, NULL);
|
||||
(Object **)&bus->hotplug_handler,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
NULL);
|
||||
object_property_add_bool(obj, "realized",
|
||||
bus_get_realized, bus_set_realized, NULL);
|
||||
}
|
||||
|
|
|
@ -537,9 +537,15 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
|
|||
Error *local_errp = NULL;
|
||||
|
||||
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
|
||||
(Object **)&ds->dma, &local_errp);
|
||||
(Object **)&ds->dma,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&local_errp);
|
||||
object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
|
||||
(Object **)&cs->dma, &local_errp);
|
||||
(Object **)&cs->dma,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&local_errp);
|
||||
if (local_errp) {
|
||||
goto xilinx_axidma_realize_fail;
|
||||
}
|
||||
|
@ -571,10 +577,16 @@ static void xilinx_axidma_init(Object *obj)
|
|||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
|
||||
object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
|
||||
(Object **)&s->tx_data_dev, &error_abort);
|
||||
(Object **)&s->tx_data_dev,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&error_abort);
|
||||
object_property_add_link(obj, "axistream-control-connected",
|
||||
TYPE_STREAM_SLAVE,
|
||||
(Object **)&s->tx_control_dev, &error_abort);
|
||||
(Object **)&s->tx_control_dev,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&error_abort);
|
||||
|
||||
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
|
||||
TYPE_XILINX_AXI_DMA_DATA_STREAM);
|
||||
|
|
|
@ -945,9 +945,15 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
|
|||
Error *local_errp = NULL;
|
||||
|
||||
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
|
||||
(Object **) &ds->enet, &local_errp);
|
||||
(Object **) &ds->enet,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&local_errp);
|
||||
object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",
|
||||
(Object **) &cs->enet, &local_errp);
|
||||
(Object **) &cs->enet,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&local_errp);
|
||||
if (local_errp) {
|
||||
goto xilinx_enet_realize_fail;
|
||||
}
|
||||
|
@ -982,10 +988,16 @@ static void xilinx_enet_init(Object *obj)
|
|||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
|
||||
object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
|
||||
(Object **) &s->tx_data_dev, &error_abort);
|
||||
(Object **) &s->tx_data_dev,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&error_abort);
|
||||
object_property_add_link(obj, "axistream-control-connected",
|
||||
TYPE_STREAM_SLAVE,
|
||||
(Object **) &s->tx_control_dev, &error_abort);
|
||||
(Object **) &s->tx_control_dev,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&error_abort);
|
||||
|
||||
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
|
||||
TYPE_XILINX_AXI_ENET_DATA_STREAM);
|
||||
|
|
|
@ -198,7 +198,9 @@ static void pxa2xx_pcmcia_initfn(Object *obj)
|
|||
s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
|
||||
|
||||
object_property_add_link(obj, "card", TYPE_PCMCIA_CARD,
|
||||
(Object **)&s->card, NULL);
|
||||
(Object **)&s->card,
|
||||
NULL, /* read-only property */
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
/* Insert a new card into a slot */
|
||||
|
|
|
@ -313,7 +313,9 @@ static void s390_virtio_rng_instance_init(Object *obj)
|
|||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
|
||||
(Object **)&dev->vdev.conf.rng, NULL);
|
||||
(Object **)&dev->vdev.conf.rng,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
|
||||
}
|
||||
|
||||
static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq)
|
||||
|
|
|
@ -1272,7 +1272,9 @@ static void virtio_ccw_rng_instance_init(Object *obj)
|
|||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
|
||||
(Object **)&dev->vdev.conf.rng, NULL);
|
||||
(Object **)&dev->vdev.conf.rng,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
|
||||
}
|
||||
|
||||
static Property virtio_ccw_rng_properties[] = {
|
||||
|
|
|
@ -1517,7 +1517,9 @@ static void virtio_rng_initfn(Object *obj)
|
|||
object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
|
||||
object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
|
||||
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
|
||||
(Object **)&dev->vdev.conf.rng, NULL);
|
||||
(Object **)&dev->vdev.conf.rng,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -162,6 +162,9 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp)
|
|||
OBJECT(vrng->conf.default_backend),
|
||||
NULL);
|
||||
|
||||
/* The child property took a reference, we can safely drop ours now */
|
||||
object_unref(OBJECT(vrng->conf.default_backend));
|
||||
|
||||
object_property_set_link(OBJECT(dev),
|
||||
OBJECT(vrng->conf.default_backend),
|
||||
"rng", NULL);
|
||||
|
@ -223,7 +226,9 @@ static void virtio_rng_initfn(Object *obj)
|
|||
VirtIORNG *vrng = VIRTIO_RNG(obj);
|
||||
|
||||
object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
|
||||
(Object **)&vrng->conf.rng, NULL);
|
||||
(Object **)&vrng->conf.rng,
|
||||
qdev_prop_allow_set_link_before_realize,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_rng_info = {
|
||||
|
|
|
@ -54,6 +54,7 @@ struct QEMUMachine {
|
|||
int qemu_register_machine(QEMUMachine *m);
|
||||
|
||||
#define TYPE_MACHINE "machine"
|
||||
#undef MACHINE /* BSD defines it and QEMU does not use it */
|
||||
#define MACHINE(obj) \
|
||||
OBJECT_CHECK(MachineState, (obj), TYPE_MACHINE)
|
||||
#define MACHINE_GET_CLASS(obj) \
|
||||
|
|
|
@ -204,4 +204,15 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
|
|||
*/
|
||||
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* qdev_prop_allow_set_link_before_realize:
|
||||
*
|
||||
* Set the #Error object if an attempt is made to set the link after realize.
|
||||
* This function should be used as the check() argument to
|
||||
* object_property_add_link().
|
||||
*/
|
||||
void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name,
|
||||
Object *val, Error **errp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1067,12 +1067,29 @@ Object *object_resolve_path_component(Object *parent, const gchar *part);
|
|||
void object_property_add_child(Object *obj, const char *name,
|
||||
Object *child, Error **errp);
|
||||
|
||||
typedef enum {
|
||||
/* Unref the link pointer when the property is deleted */
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE = 0x1,
|
||||
} ObjectPropertyLinkFlags;
|
||||
|
||||
/**
|
||||
* object_property_allow_set_link:
|
||||
*
|
||||
* The default implementation of the object_property_add_link() check()
|
||||
* callback function. It allows the link property to be set and never returns
|
||||
* an error.
|
||||
*/
|
||||
void object_property_allow_set_link(Object *, const char *,
|
||||
Object *, Error **);
|
||||
|
||||
/**
|
||||
* object_property_add_link:
|
||||
* @obj: the object to add a property to
|
||||
* @name: the name of the property
|
||||
* @type: the qobj type of the link
|
||||
* @child: a pointer to where the link object reference is stored
|
||||
* @check: callback to veto setting or NULL if the property is read-only
|
||||
* @flags: additional options for the link
|
||||
* @errp: if an error occurs, a pointer to an area to store the area
|
||||
*
|
||||
* Links establish relationships between objects. Links are unidirectional
|
||||
|
@ -1081,13 +1098,23 @@ void object_property_add_child(Object *obj, const char *name,
|
|||
*
|
||||
* Links form the graph in the object model.
|
||||
*
|
||||
* The <code>@check()</code> callback is invoked when
|
||||
* object_property_set_link() is called and can raise an error to prevent the
|
||||
* link being set. If <code>@check</code> is NULL, the property is read-only
|
||||
* and cannot be set.
|
||||
*
|
||||
* Ownership of the pointer that @child points to is transferred to the
|
||||
* link property. The reference count for <code>*@child</code> is
|
||||
* managed by the property from after the function returns till the
|
||||
* property is deleted with object_property_del().
|
||||
* property is deleted with object_property_del(). If the
|
||||
* <code>@flags</code> <code>OBJ_PROP_LINK_UNREF_ON_RELEASE</code> bit is set,
|
||||
* the reference count is decremented when the property is deleted.
|
||||
*/
|
||||
void object_property_add_link(Object *obj, const char *name,
|
||||
const char *type, Object **child,
|
||||
void (*check)(Object *obj, const char *name,
|
||||
Object *val, Error **errp),
|
||||
ObjectPropertyLinkFlags flags,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
|
|
139
qom/object.c
139
qom/object.c
|
@ -1023,10 +1023,23 @@ out:
|
|||
g_free(type);
|
||||
}
|
||||
|
||||
void object_property_allow_set_link(Object *obj, const char *name,
|
||||
Object *val, Error **errp)
|
||||
{
|
||||
/* Allow the link to be set, always */
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Object **child;
|
||||
void (*check)(Object *, const char *, Object *, Error **);
|
||||
ObjectPropertyLinkFlags flags;
|
||||
} LinkProperty;
|
||||
|
||||
static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
Object **child = opaque;
|
||||
LinkProperty *lprop = opaque;
|
||||
Object **child = lprop->child;
|
||||
gchar *path;
|
||||
|
||||
if (*child) {
|
||||
|
@ -1039,65 +1052,119 @@ static void object_get_link_property(Object *obj, Visitor *v, void *opaque,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* object_resolve_link:
|
||||
*
|
||||
* Lookup an object and ensure its type matches the link property type. This
|
||||
* is similar to object_resolve_path() except type verification against the
|
||||
* link property is performed.
|
||||
*
|
||||
* Returns: The matched object or NULL on path lookup failures.
|
||||
*/
|
||||
static Object *object_resolve_link(Object *obj, const char *name,
|
||||
const char *path, Error **errp)
|
||||
{
|
||||
const char *type;
|
||||
gchar *target_type;
|
||||
bool ambiguous = false;
|
||||
Object *target;
|
||||
|
||||
/* Go from link<FOO> to FOO. */
|
||||
type = object_property_get_type(obj, name, NULL);
|
||||
target_type = g_strndup(&type[5], strlen(type) - 6);
|
||||
target = object_resolve_path_type(path, target_type, &ambiguous);
|
||||
|
||||
if (ambiguous) {
|
||||
error_set(errp, QERR_AMBIGUOUS_PATH, path);
|
||||
} else if (!target) {
|
||||
target = object_resolve_path(path, &ambiguous);
|
||||
if (target || ambiguous) {
|
||||
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
|
||||
} else {
|
||||
error_set(errp, QERR_DEVICE_NOT_FOUND, path);
|
||||
}
|
||||
target = NULL;
|
||||
}
|
||||
g_free(target_type);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
static void object_set_link_property(Object *obj, Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
Object **child = opaque;
|
||||
Object *old_target;
|
||||
bool ambiguous = false;
|
||||
const char *type;
|
||||
char *path;
|
||||
gchar *target_type;
|
||||
Error *local_err = NULL;
|
||||
LinkProperty *prop = opaque;
|
||||
Object **child = prop->child;
|
||||
Object *old_target = *child;
|
||||
Object *new_target = NULL;
|
||||
char *path = NULL;
|
||||
|
||||
type = object_property_get_type(obj, name, NULL);
|
||||
visit_type_str(v, &path, name, &local_err);
|
||||
|
||||
visit_type_str(v, &path, name, errp);
|
||||
|
||||
old_target = *child;
|
||||
*child = NULL;
|
||||
|
||||
if (strcmp(path, "") != 0) {
|
||||
Object *target;
|
||||
|
||||
/* Go from link<FOO> to FOO. */
|
||||
target_type = g_strndup(&type[5], strlen(type) - 6);
|
||||
target = object_resolve_path_type(path, target_type, &ambiguous);
|
||||
|
||||
if (ambiguous) {
|
||||
error_set(errp, QERR_AMBIGUOUS_PATH, path);
|
||||
} else if (target) {
|
||||
object_ref(target);
|
||||
*child = target;
|
||||
} else {
|
||||
target = object_resolve_path(path, &ambiguous);
|
||||
if (target || ambiguous) {
|
||||
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, target_type);
|
||||
} else {
|
||||
error_set(errp, QERR_DEVICE_NOT_FOUND, path);
|
||||
}
|
||||
}
|
||||
g_free(target_type);
|
||||
if (!local_err && strcmp(path, "") != 0) {
|
||||
new_target = object_resolve_link(obj, name, path, &local_err);
|
||||
}
|
||||
|
||||
g_free(path);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
prop->check(obj, name, new_target, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_target) {
|
||||
object_ref(new_target);
|
||||
}
|
||||
*child = new_target;
|
||||
if (old_target != NULL) {
|
||||
object_unref(old_target);
|
||||
}
|
||||
}
|
||||
|
||||
static void object_release_link_property(Object *obj, const char *name,
|
||||
void *opaque)
|
||||
{
|
||||
LinkProperty *prop = opaque;
|
||||
|
||||
if ((prop->flags & OBJ_PROP_LINK_UNREF_ON_RELEASE) && *prop->child) {
|
||||
object_unref(*prop->child);
|
||||
}
|
||||
g_free(prop);
|
||||
}
|
||||
|
||||
void object_property_add_link(Object *obj, const char *name,
|
||||
const char *type, Object **child,
|
||||
void (*check)(Object *, const char *,
|
||||
Object *, Error **),
|
||||
ObjectPropertyLinkFlags flags,
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
LinkProperty *prop = g_malloc(sizeof(*prop));
|
||||
gchar *full_type;
|
||||
|
||||
prop->child = child;
|
||||
prop->check = check;
|
||||
prop->flags = flags;
|
||||
|
||||
full_type = g_strdup_printf("link<%s>", type);
|
||||
|
||||
object_property_add(obj, name, full_type,
|
||||
object_get_link_property,
|
||||
object_set_link_property,
|
||||
NULL, child, errp);
|
||||
check ? object_set_link_property : NULL,
|
||||
object_release_link_property,
|
||||
prop,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
g_free(prop);
|
||||
}
|
||||
|
||||
g_free(full_type);
|
||||
}
|
||||
|
|
|
@ -1180,7 +1180,10 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
|
|||
obj = object_new(TYPE_QEMU_CONSOLE);
|
||||
s = QEMU_CONSOLE(obj);
|
||||
object_property_add_link(obj, "device", TYPE_DEVICE,
|
||||
(Object **)&s->device, &local_err);
|
||||
(Object **)&s->device,
|
||||
object_property_allow_set_link,
|
||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||
&local_err);
|
||||
object_property_add_uint32_ptr(obj, "head",
|
||||
&s->head, &local_err);
|
||||
|
||||
|
|
6
vl.c
6
vl.c
|
@ -58,6 +58,7 @@ int main(int argc, char **argv)
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
#include "qemu/sockets.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/usb.h"
|
||||
|
@ -103,7 +104,6 @@ int main(int argc, char **argv)
|
|||
|
||||
#include "disas/disas.h"
|
||||
|
||||
#include "qemu/sockets.h"
|
||||
|
||||
#include "slirp/libslirp.h"
|
||||
|
||||
|
@ -1587,14 +1587,16 @@ static void machine_class_init(ObjectClass *oc, void *data)
|
|||
|
||||
int qemu_register_machine(QEMUMachine *m)
|
||||
{
|
||||
char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL);
|
||||
TypeInfo ti = {
|
||||
.name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL),
|
||||
.name = name,
|
||||
.parent = TYPE_MACHINE,
|
||||
.class_init = machine_class_init,
|
||||
.class_data = (void *)m,
|
||||
};
|
||||
|
||||
type_register(&ti);
|
||||
g_free(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue