qom: add link properties (v2)

Links represent an ephemeral relationship between devices.  They are meant to
replace the qdev concept of busses by allowing more informal relationships
between devices.

Links are fairly limited in their usefulness without implementing QOM-style
subclassing and interfaces.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Anthony Liguori 2011-12-12 14:29:32 -06:00
parent 3de1c3e82d
commit 83e94fb8d5
2 changed files with 97 additions and 0 deletions

View file

@ -1200,6 +1200,80 @@ void qdev_property_add_child(DeviceState *dev, const char *name,
g_free(type);
}
static void qdev_get_link_property(DeviceState *dev, Visitor *v, void *opaque,
const char *name, Error **errp)
{
DeviceState **child = opaque;
gchar *path;
if (*child) {
path = qdev_get_canonical_path(*child);
visit_type_str(v, &path, name, errp);
g_free(path);
} else {
path = (gchar *)"";
visit_type_str(v, &path, name, errp);
}
}
static void qdev_set_link_property(DeviceState *dev, Visitor *v, void *opaque,
const char *name, Error **errp)
{
DeviceState **child = opaque;
bool ambiguous = false;
const char *type;
char *path;
type = qdev_property_get_type(dev, name, NULL);
visit_type_str(v, &path, name, errp);
if (*child) {
qdev_unref(*child);
}
if (strcmp(path, "") != 0) {
DeviceState *target;
target = qdev_resolve_path(path, &ambiguous);
if (target) {
gchar *target_type;
target_type = g_strdup_printf("link<%s>", target->info->name);
if (strcmp(target_type, type) == 0) {
*child = target;
qdev_ref(target);
} else {
error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);
}
g_free(target_type);
} else {
error_set(errp, QERR_DEVICE_NOT_FOUND, path);
}
} else {
*child = NULL;
}
g_free(path);
}
void qdev_property_add_link(DeviceState *dev, const char *name,
const char *type, DeviceState **child,
Error **errp)
{
gchar *full_type;
full_type = g_strdup_printf("link<%s>", type);
qdev_property_add(dev, name, full_type,
qdev_get_link_property,
qdev_set_link_property,
NULL, child, errp);
g_free(full_type);
}
static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev)
{
DeviceProperty *prop;