qom: use correct field name when getting/setting alias properties
Alias targets have a different name than the alias property itself (e.g. a machine's pflash0 might be an alias of a property named 'drive'). When the target's getter or setter invokes the visitor, it will use a different name than what the caller expects, and the visitor will not be able to find it (or will consume erroneously). The solution is for alias getters and setters to wrap the incoming visitor, and forward the sole field that the target is expecting while renaming it appropriately. This bug has been there forever, but it was exposed after -M parsing switched from QemuOptions and StringInputVisitor to keyval and QObjectInputVisitor. Before, the visitor ignored the name. Now, it checks "drive" against what was passed on the command line and finds that no such property exists. Fixes: https://gitlab.com/qemu-project/qemu/-/issues/484 Reported-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
18fa3ebc45
commit
cbc94d9702
@ -20,6 +20,7 @@
|
|||||||
#include "qapi/string-input-visitor.h"
|
#include "qapi/string-input-visitor.h"
|
||||||
#include "qapi/string-output-visitor.h"
|
#include "qapi/string-output-visitor.h"
|
||||||
#include "qapi/qobject-input-visitor.h"
|
#include "qapi/qobject-input-visitor.h"
|
||||||
|
#include "qapi/forward-visitor.h"
|
||||||
#include "qapi/qapi-builtin-visit.h"
|
#include "qapi/qapi-builtin-visit.h"
|
||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qapi/qmp/qjson.h"
|
#include "qapi/qmp/qjson.h"
|
||||||
@ -2683,16 +2684,20 @@ static void property_get_alias(Object *obj, Visitor *v, const char *name,
|
|||||||
void *opaque, Error **errp)
|
void *opaque, Error **errp)
|
||||||
{
|
{
|
||||||
AliasProperty *prop = opaque;
|
AliasProperty *prop = opaque;
|
||||||
|
Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
|
||||||
|
|
||||||
object_property_get(prop->target_obj, prop->target_name, v, errp);
|
object_property_get(prop->target_obj, prop->target_name, alias_v, errp);
|
||||||
|
visit_free(alias_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void property_set_alias(Object *obj, Visitor *v, const char *name,
|
static void property_set_alias(Object *obj, Visitor *v, const char *name,
|
||||||
void *opaque, Error **errp)
|
void *opaque, Error **errp)
|
||||||
{
|
{
|
||||||
AliasProperty *prop = opaque;
|
AliasProperty *prop = opaque;
|
||||||
|
Visitor *alias_v = visitor_forward_field(v, prop->target_name, name);
|
||||||
|
|
||||||
object_property_set(prop->target_obj, prop->target_name, v, errp);
|
object_property_set(prop->target_obj, prop->target_name, alias_v, errp);
|
||||||
|
visit_free(alias_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object *property_resolve_alias(Object *obj, void *opaque,
|
static Object *property_resolve_alias(Object *obj, void *opaque,
|
||||||
|
Loading…
Reference in New Issue
Block a user