* [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name
2011-12-16 12:01 [Qemu-devel] [PATCH " Paolo Bonzini
@ 2011-12-16 12:01 ` Paolo Bonzini
2011-12-16 14:06 ` Anthony Liguori
0 siblings, 1 reply; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-16 12:01 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
For non-string properties, there is no reason to distinguish type names
such as "uint32" or "hex32". Restrict those to legacy properties.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 12 ++++++++----
hw/qdev.c | 9 ++++++---
hw/qdev.h | 1 +
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 5e8dd9a..6b6732e 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -86,7 +86,8 @@ static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_bit = {
- .name = "on/off",
+ .name = "boolean",
+ .legacy_name = "on/off",
.type = PROP_TYPE_BIT,
.size = sizeof(uint32_t),
.parse = parse_bit,
@@ -189,7 +190,8 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
}
PropertyInfo qdev_prop_hex8 = {
- .name = "hex8",
+ .name = "uint8",
+ .legacy_name = "hex8",
.type = PROP_TYPE_UINT8,
.size = sizeof(uint8_t),
.parse = parse_hex8,
@@ -397,7 +399,8 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
}
PropertyInfo qdev_prop_hex32 = {
- .name = "hex32",
+ .name = "uint32",
+ .legacy_name = "hex32",
.type = PROP_TYPE_UINT32,
.size = sizeof(uint32_t),
.parse = parse_hex32,
@@ -485,7 +488,8 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
}
PropertyInfo qdev_prop_hex64 = {
- .name = "hex64",
+ .name = "uint64",
+ .legacy_name = "hex64",
.type = PROP_TYPE_UINT64,
.size = sizeof(uint64_t),
.parse = parse_hex64,
diff --git a/hw/qdev.c b/hw/qdev.c
index c020a6f..d76861e 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -218,13 +218,15 @@ int qdev_device_help(QemuOpts *opts)
if (!prop->info->parse) {
continue; /* no way to set it, don't show */
}
- error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
+ error_printf("%s.%s=%s\n", info->name, prop->name,
+ prop->info->legacy_name ?: prop->info->name);
}
for (prop = info->bus_info->props; prop && prop->name; prop++) {
if (!prop->info->parse) {
continue; /* no way to set it, don't show */
}
- error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
+ error_printf("%s.%s=%s\n", info->name, prop->name,
+ prop->info->legacy_name ?: prop->info->name);
}
return 1;
}
@@ -1183,7 +1185,8 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
{
gchar *type;
- type = g_strdup_printf("legacy<%s>", prop->info->name);
+ type = g_strdup_printf("legacy<%s>",
+ prop->info->legacy_name ?: prop->info->name);
qdev_property_add(dev, prop->name, type,
prop->info->print ? qdev_get_legacy_property : NULL,
diff --git a/hw/qdev.h b/hw/qdev.h
index 9778123..c7d9535 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -156,6 +156,7 @@ enum PropertyType {
struct PropertyInfo {
const char *name;
+ const char *legacy_name;
size_t size;
enum PropertyType type;
int64_t min;
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name
2011-12-16 12:01 ` [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
@ 2011-12-16 14:06 ` Anthony Liguori
2011-12-16 14:18 ` Paolo Bonzini
0 siblings, 1 reply; 14+ messages in thread
From: Anthony Liguori @ 2011-12-16 14:06 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: kwolf, qemu-devel
On 12/16/2011 06:01 AM, Paolo Bonzini wrote:
> For non-string properties, there is no reason to distinguish type names
> such as "uint32" or "hex32". Restrict those to legacy properties.
>
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
> hw/qdev-properties.c | 12 ++++++++----
> hw/qdev.c | 9 ++++++---
> hw/qdev.h | 1 +
> 3 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
> index 5e8dd9a..6b6732e 100644
> --- a/hw/qdev-properties.c
> +++ b/hw/qdev-properties.c
> @@ -86,7 +86,8 @@ static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
> }
>
> PropertyInfo qdev_prop_bit = {
> - .name = "on/off",
> + .name = "boolean",
> + .legacy_name = "on/off",
> .type = PROP_TYPE_BIT,
> .size = sizeof(uint32_t),
> .parse = parse_bit,
> @@ -189,7 +190,8 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
> }
>
> PropertyInfo qdev_prop_hex8 = {
> - .name = "hex8",
> + .name = "uint8",
> + .legacy_name = "hex8",
> .type = PROP_TYPE_UINT8,
> .size = sizeof(uint8_t),
> .parse = parse_hex8,
> @@ -397,7 +399,8 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
> }
>
> PropertyInfo qdev_prop_hex32 = {
> - .name = "hex32",
> + .name = "uint32",
> + .legacy_name = "hex32",
> .type = PROP_TYPE_UINT32,
> .size = sizeof(uint32_t),
> .parse = parse_hex32,
> @@ -485,7 +488,8 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
> }
>
> PropertyInfo qdev_prop_hex64 = {
> - .name = "hex64",
> + .name = "uint64",
> + .legacy_name = "hex64",
> .type = PROP_TYPE_UINT64,
> .size = sizeof(uint64_t),
> .parse = parse_hex64,
> diff --git a/hw/qdev.c b/hw/qdev.c
> index c020a6f..d76861e 100644
> --- a/hw/qdev.c
> +++ b/hw/qdev.c
> @@ -218,13 +218,15 @@ int qdev_device_help(QemuOpts *opts)
> if (!prop->info->parse) {
> continue; /* no way to set it, don't show */
> }
> - error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
> + error_printf("%s.%s=%s\n", info->name, prop->name,
> + prop->info->legacy_name ?: prop->info->name);
> }
> for (prop = info->bus_info->props; prop&& prop->name; prop++) {
> if (!prop->info->parse) {
> continue; /* no way to set it, don't show */
> }
> - error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
> + error_printf("%s.%s=%s\n", info->name, prop->name,
> + prop->info->legacy_name ?: prop->info->name);
> }
> return 1;
> }
> @@ -1183,7 +1185,8 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
> {
> gchar *type;
>
> - type = g_strdup_printf("legacy<%s>", prop->info->name);
> + type = g_strdup_printf("legacy<%s>",
> + prop->info->legacy_name ?: prop->info->name);
I think this confuses the legacy type with the legacy property names.
I think it would be better to do 'legacy-%s' as then it's at least clear when
something is a type name vs. a property name.
Regards,
Anthony Liguori
>
> qdev_property_add(dev, prop->name, type,
> prop->info->print ? qdev_get_legacy_property : NULL,
> diff --git a/hw/qdev.h b/hw/qdev.h
> index 9778123..c7d9535 100644
> --- a/hw/qdev.h
> +++ b/hw/qdev.h
> @@ -156,6 +156,7 @@ enum PropertyType {
>
> struct PropertyInfo {
> const char *name;
> + const char *legacy_name;
> size_t size;
> enum PropertyType type;
> int64_t min;
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name
2011-12-16 14:06 ` Anthony Liguori
@ 2011-12-16 14:18 ` Paolo Bonzini
2011-12-16 14:43 ` Anthony Liguori
0 siblings, 1 reply; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-16 14:18 UTC (permalink / raw)
To: Anthony Liguori; +Cc: kwolf, qemu-devel
On 12/16/2011 03:06 PM, Anthony Liguori wrote:
>>
>> - type = g_strdup_printf("legacy<%s>", prop->info->name);
>> + type = g_strdup_printf("legacy<%s>",
>> + prop->info->legacy_name ?: prop->info->name);
>
> I think this confuses the legacy type with the legacy property names.
>
> I think it would be better to do 'legacy-%s' as then it's at least clear
> when something is a type name vs. a property name.
That's only in 8/8. Here I'm not changing property names yet, note that
everything is in prop->info.
This patch prepares for when you'll have a legacy<hex32> type for
property legacy<iobase>, and uint32 for iobase. But I can surely rename
legacy<iobase> to legacy-iobase, if that's what you meant.
paolo
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name
2011-12-16 14:18 ` Paolo Bonzini
@ 2011-12-16 14:43 ` Anthony Liguori
0 siblings, 0 replies; 14+ messages in thread
From: Anthony Liguori @ 2011-12-16 14:43 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: kwolf, qemu-devel
On 12/16/2011 08:18 AM, Paolo Bonzini wrote:
> On 12/16/2011 03:06 PM, Anthony Liguori wrote:
>>>
>>> - type = g_strdup_printf("legacy<%s>", prop->info->name);
>>> + type = g_strdup_printf("legacy<%s>",
>>> + prop->info->legacy_name ?: prop->info->name);
>>
>> I think this confuses the legacy type with the legacy property names.
>>
>> I think it would be better to do 'legacy-%s' as then it's at least clear
>> when something is a type name vs. a property name.
>
> That's only in 8/8. Here I'm not changing property names yet, note that
> everything is in prop->info.
>
> This patch prepares for when you'll have a legacy<hex32> type for property
> legacy<iobase>, and uint32 for iobase. But I can surely rename legacy<iobase> to
> legacy-iobase, if that's what you meant.
No, I got confused. Ignore my comments.
Regards,
Anthony Liguori
>
> paolo
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties
@ 2011-12-18 16:05 Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
` (8 more replies)
0 siblings, 9 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
QOM right now does not have a way to communicate values for qdev
properties except as strings. This is bad.
This patch improves the Property implementation so that properties
export a visitor-based interface in addition to the string-based
interface. The new interface can then be registered as a "static"
property. It's called static because it uses a struct field for
storage and, as such, should be present in all objects of a given
class.
Patches 1-2 are bugfixes and patches 3-4 are cleanups.
Example using qmp-shell:
x86_64-softmmu/qemu-system-x86_64 \
-hda ~/test.img -snapshot -S \
-qmp unix:/tmp/server.sock,server,nowait \
-netdev type=user,id=net -device virtio-net-pci,netdev=net,id=net \
-net user,vlan=1 -device virtio-net-pci,id=net2,vlan=1 \
-chardev id=stdio,backend=stdio -device isa-serial,chardev=stdio,id=serial
Boolean properties:
(QEMU) qom-get path=/i440fx/piix3 property=command_serr_enable
{u'return': True}
(QEMU) qom-get path=/i440fx/piix3 property=legacy<command_serr_enable>
{u'return': u'on'}
PCI address properties (perhaps will disappear later, but not yet):
(QEMU) qom-get path=/i440fx/piix3 property=addr
{u'return': u'01.0'}
(QEMU) qom-get path=/i440fx/piix3 property=legacy-addr
{u'return': u'01.0'}
String properties (NULL mapped to empty string):
(QEMU) qom-get path=/vga property=romfile
{u'return': u'vgabios-cirrus.bin'}
(QEMU) qom-get path=/vga property=legacy-romfile
{u'return': u'"vgabios-cirrus.bin"'}
(QEMU) qom-get path=/i440fx/piix3 property=romfile
{u'return': u''}
(QEMU) qom-get path=/i440fx/piix3 property=legacy-romfile
{u'return': u'<null>'}
MAC properties:
(QEMU) qom-get path=/peripheral/net property=mac
{u'return': u'52:54:00:12:34:56'}
(QEMU) qom-get path=/peripheral/net property=legacy-mac
{u'return': u'52:54:00:12:34:56'}
(QEMU) qom-set path=/peripheral/net property=mac value=52-54-00-12-34-57
{u'error': {u'data': {}, u'class': u'PermissionDenied', u'desc': u'Insufficient permission to perform this operation'}}
Network properties:
(QEMU) qom-get path=/peripheral/net property=netdev
{u'return': u'net'}
(QEMU) qom-get path=/peripheral/net property=legacy-netdev
{u'return': u'net'}
VLAN properties:
(QEMU) qom-get path=/peripheral/net property=vlan
{u'return': -1}
(QEMU) qom-get path=/peripheral/net property=legacy-vlan
{u'return': u'<null>'}
(QEMU) qom-get path=/peripheral/net2 property=vlan
{u'return': 1}
(QEMU) qom-get path=/peripheral/net2 property=legacy-vlan
{u'return': u'1'}
Chardev properties:
(QEMU) qom-get path=/peripheral/serial property=chardev
{u'return': u'stdio'}
(QEMU) qom-get path=/peripheral/serial property=legacy-chardev
{u'return': u'stdio'}
Legacy hex32 properties:
(QEMU) qom-get path=/peripheral/serial property=iobase
{u'return': 1016}
(QEMU) qom-get path=/peripheral/serial property=legacy-iobase
{u'return': u'0x3f8'}
Examples of setting properties (after disabling the DEV_STATE_CREATED
check for testing only):
(QEMU) qom-set path=/peripheral/net2 property=vlan value=-1
{u'return': {}}
(QEMU) qom-get path=/peripheral/net2 property=vlan
{u'return': -1}
(QEMU) qom-get path=/peripheral/net2 property=legacy-vlan
{u'return': u'<null>'}
(QEMU) qom-set path=/peripheral/serial property=iobase value=760
{u'return': {}}
(QEMU) qom-get path=/peripheral/serial property=iobase
{u'return': 760}
(QEMU) qom-get path=/peripheral/serial property=legacy-iobase
{u'return': u'0x2f8'}
v2->v3:
Tweaks to patch 4.
v1->v2:
New "qom: interpret the return value when setting legacy
properties". Always pass a value to the visitor when there
is no error. Handle empty strings as NULL. Did not change
QERR_PROPERTY_VALUE_OUT_OF_RANGE because it is consistent
with other QERR_PROPERTY_* errors, now used by QOM too.
Paolo Bonzini (8):
qapi: protect against NULL QObject in qmp_input_get_object
qom: fix swapped parameters
qom: push permission checks up into qdev_property_add_legacy
qom: interpret the return value when setting legacy properties
qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE
qom: introduce get/set methods for Property
qom: distinguish "legacy" property type name from QOM type name
qom: register qdev properties also as non-legacy properties
hw/qdev-addr.c | 41 +++++
hw/qdev-properties.c | 407 +++++++++++++++++++++++++++++++++++++++++++--
hw/qdev.c | 84 ++++++----
hw/qdev.h | 14 +-
qapi/qmp-input-visitor.c | 10 +-
qerror.c | 5 +
qerror.h | 3 +
7 files changed, 502 insertions(+), 62 deletions(-)
--
1.7.7.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 1/8] qapi: protect against NULL QObject in qmp_input_get_object
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 2/8] qom: fix swapped parameters Paolo Bonzini
` (7 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
A NULL qobj can occur when a parameter is fetched via qdict_get, but
the parameter is not in the command. By returning NULL, the caller can
choose whether to raise a missing parameter error, an invalid parameter
type error, or use a default value. For example, qom-set could can
use this to reset a property to its default value, though at this time
it will fail with "Invalid parameter type". In any case, anything is
better than crashing!
Reviewed-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qapi/qmp-input-visitor.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 8cbc0ab..c78022b 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -49,10 +49,12 @@ static const QObject *qmp_input_get_object(QmpInputVisitor *qiv,
qobj = qiv->stack[qiv->nb_stack - 1].obj;
}
- if (name && qobject_type(qobj) == QTYPE_QDICT) {
- return qdict_get(qobject_to_qdict(qobj), name);
- } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
- return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
+ if (qobj) {
+ if (name && qobject_type(qobj) == QTYPE_QDICT) {
+ return qdict_get(qobject_to_qdict(qobj), name);
+ } else if (qiv->nb_stack > 0 && qobject_type(qobj) == QTYPE_QLIST) {
+ return qlist_entry_obj(qiv->stack[qiv->nb_stack - 1].entry);
+ }
}
return qobj;
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 2/8] qom: fix swapped parameters
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 3/8] qom: push permission checks up into qdev_property_add_legacy Paolo Bonzini
` (6 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
Reviewed-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index 83913c7..bda8d6c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1110,7 +1110,7 @@ void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
if (!prop->set) {
error_set(errp, QERR_PERMISSION_DENIED);
} else {
- prop->set(dev, prop->opaque, v, name, errp);
+ prop->set(dev, v, prop->opaque, name, errp);
}
}
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 3/8] qom: push permission checks up into qdev_property_add_legacy
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 2/8] qom: fix swapped parameters Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 4/8] qom: interpret the return value when setting legacy properties Paolo Bonzini
` (5 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
qdev_property_get and qdev_property_set can generate permission
denied errors themselves. Do not duplicate this functionality in
qdev_get/set_legacy_property, and clean up excessive indentation.
Reviewed-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev.c | 46 +++++++++++++++++++---------------------------
1 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index bda8d6c..c020a6f 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1135,46 +1135,38 @@ static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
{
Property *prop = opaque;
- if (prop->info->print) {
- char buffer[1024];
- char *ptr = buffer;
+ char buffer[1024];
+ char *ptr = buffer;
- prop->info->print(dev, prop, buffer, sizeof(buffer));
- visit_type_str(v, &ptr, name, errp);
- } else {
- error_set(errp, QERR_PERMISSION_DENIED);
- }
+ prop->info->print(dev, prop, buffer, sizeof(buffer));
+ visit_type_str(v, &ptr, name, errp);
}
static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
const char *name, Error **errp)
{
Property *prop = opaque;
+ Error *local_err = NULL;
+ char *ptr = NULL;
+ int ret;
if (dev->state != DEV_STATE_CREATED) {
error_set(errp, QERR_PERMISSION_DENIED);
return;
}
- if (prop->info->parse) {
- Error *local_err = NULL;
- char *ptr = NULL;
+ visit_type_str(v, &ptr, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
- visit_type_str(v, &ptr, name, &local_err);
- if (!local_err) {
- int ret;
- ret = prop->info->parse(dev, prop, ptr);
- if (ret != 0) {
- error_set(errp, QERR_INVALID_PARAMETER_VALUE,
- name, prop->info->name);
- }
- g_free(ptr);
- } else {
- error_propagate(errp, local_err);
- }
- } else {
- error_set(errp, QERR_PERMISSION_DENIED);
+ ret = prop->info->parse(dev, prop, ptr);
+ if (ret != 0) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+ name, prop->info->name);
}
+ g_free(ptr);
}
/**
@@ -1194,8 +1186,8 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
type = g_strdup_printf("legacy<%s>", prop->info->name);
qdev_property_add(dev, prop->name, type,
- qdev_get_legacy_property,
- qdev_set_legacy_property,
+ prop->info->print ? qdev_get_legacy_property : NULL,
+ prop->info->parse ? qdev_set_legacy_property : NULL,
NULL,
prop, errp);
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 4/8] qom: interpret the return value when setting legacy properties
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
` (2 preceding siblings ...)
2011-12-18 16:05 ` [Qemu-devel] [PATCH 3/8] qom: push permission checks up into qdev_property_add_legacy Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE Paolo Bonzini
` (4 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 41 ++++++++++++++++++++++++++---------------
hw/qdev.c | 5 +----
hw/qdev.h | 2 ++
3 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index f0b811c..de618f2 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -614,6 +614,28 @@ int qdev_prop_exists(DeviceState *dev, const char *name)
return qdev_prop_find(dev, name) ? true : false;
}
+void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+ Property *prop, const char *value)
+{
+ switch (ret) {
+ case -EEXIST:
+ error_set(errp, QERR_PROPERTY_VALUE_IN_USE,
+ dev->info->name, prop->name, value);
+ break;
+ default:
+ case -EINVAL:
+ error_set(errp, QERR_PROPERTY_VALUE_BAD,
+ dev->info->name, prop->name, value);
+ break;
+ case -ENOENT:
+ error_set(errp, QERR_PROPERTY_VALUE_NOT_FOUND,
+ dev->info->name, prop->name, value);
+ break;
+ case 0:
+ break;
+ }
+}
+
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
{
Property *prop;
@@ -632,21 +654,10 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
}
ret = prop->info->parse(dev, prop, value);
if (ret < 0) {
- switch (ret) {
- case -EEXIST:
- qerror_report(QERR_PROPERTY_VALUE_IN_USE,
- dev->info->name, name, value);
- break;
- default:
- case -EINVAL:
- qerror_report(QERR_PROPERTY_VALUE_BAD,
- dev->info->name, name, value);
- break;
- case -ENOENT:
- qerror_report(QERR_PROPERTY_VALUE_NOT_FOUND,
- dev->info->name, name, value);
- break;
- }
+ Error *err;
+ error_set_from_qdev_prop_error(&err, ret, dev, prop, value);
+ qerror_report_err(err);
+ error_free(err);
return -1;
}
return 0;
diff --git a/hw/qdev.c b/hw/qdev.c
index c020a6f..2a146f7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1162,10 +1162,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
}
ret = prop->info->parse(dev, prop, ptr);
- if (ret != 0) {
- error_set(errp, QERR_INVALID_PARAMETER_VALUE,
- name, prop->info->name);
- }
+ error_set_from_qdev_prop_error(errp, ret, dev, prop, ptr);
g_free(ptr);
}
diff --git a/hw/qdev.h b/hw/qdev.h
index 6e18427..94f5ce9 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -370,6 +370,8 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props);
void qdev_prop_register_global_list(GlobalProperty *props);
void qdev_prop_set_globals(DeviceState *dev);
+void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
+ Property *prop, const char *value);
static inline const char *qdev_fw_name(DeviceState *dev)
{
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
` (3 preceding siblings ...)
2011-12-18 16:05 ` [Qemu-devel] [PATCH 4/8] qom: interpret the return value when setting legacy properties Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 6/8] qom: introduce get/set methods for Property Paolo Bonzini
` (3 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
This will be used when reject invalid values for integer fields that
are less than 64-bits wide.
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
qerror.c | 5 +++++
qerror.h | 3 +++
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/qerror.c b/qerror.c
index adde8a5..9a75d06 100644
--- a/qerror.c
+++ b/qerror.c
@@ -206,6 +206,11 @@ static const QErrorStringTable qerror_table[] = {
.desc = "Property '%(device).%(property)' can't find value '%(value)'",
},
{
+ .error_fmt = QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+ .desc = "Property '%(device).%(property)' doesn't take "
+ "value %(value) (minimum: %(min), maximum: %(max)'",
+ },
+ {
.error_fmt = QERR_QMP_BAD_INPUT_OBJECT,
.desc = "Expected '%(expected)' in QMP input",
},
diff --git a/qerror.h b/qerror.h
index 9190b02..efda232 100644
--- a/qerror.h
+++ b/qerror.h
@@ -171,6 +171,9 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_PROPERTY_VALUE_NOT_FOUND \
"{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
+#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
+ "{ 'class': 'PropertyValueOutOfRange', 'data': { 'device': %s, 'property': %s, 'value': %"PRId64", 'min': %"PRId64", 'max': %"PRId64" } }"
+
#define QERR_QMP_BAD_INPUT_OBJECT \
"{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 6/8] qom: introduce get/set methods for Property
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
` (4 preceding siblings ...)
2011-12-18 16:05 ` [Qemu-devel] [PATCH 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
` (2 subsequent siblings)
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
This patch adds a visitor interface to Property. This way, QOM will be
able to expose Properties that access a fixed field in a struct without
exposing also the everything-is-a-string "feature" of qdev properties.
Whenever the printed representation in both QOM and qdev (which is
typically the case for device backends), parse/print code can be reused
via get_generic/set_generic. Dually, whenever multiple PropertyInfos
have the same representation in both the struct and the visitors the
code can be reused (for example among all of int32/uint32/hex32).
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-addr.c | 41 ++++++
hw/qdev-properties.c | 354 ++++++++++++++++++++++++++++++++++++++++++++++++++
hw/qdev.h | 4 +
3 files changed, 399 insertions(+), 0 deletions(-)
diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c
index 305c2d3..5ddda2d 100644
--- a/hw/qdev-addr.c
+++ b/hw/qdev-addr.c
@@ -18,12 +18,53 @@ static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len)
return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr);
}
+static void get_taddr(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t value;
+
+ value = *ptr;
+ visit_type_int(v, &value, name, errp);
+}
+
+static void set_taddr(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ int64_t value;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_int(v, &value, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if ((uint64_t)value <= (uint64_t) ~(target_phys_addr_t)0) {
+ *ptr = value;
+ } else {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+ dev->id?:"", name, value, (uint64_t) 0,
+ (uint64_t) ~(target_phys_addr_t)0);
+ }
+}
+
+
PropertyInfo qdev_prop_taddr = {
.name = "taddr",
.type = PROP_TYPE_TADDR,
.size = sizeof(target_phys_addr_t),
.parse = parse_taddr,
.print = print_taddr,
+ .get = get_taddr,
+ .set = set_taddr,
};
void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index de618f2..41d2165 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -55,12 +55,44 @@ static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len)
return snprintf(dest, len, (*p & qdev_get_prop_mask(prop)) ? "on" : "off");
}
+static void get_bit(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ uint32_t *p = qdev_get_prop_ptr(dev, prop);
+ bool value = (*p & qdev_get_prop_mask(prop)) != 0;
+
+ visit_type_bool(v, &value, name, errp);
+}
+
+static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ Error *local_err = NULL;
+ bool value;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_bool(v, &value, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ bit_prop_set(dev, prop, value);
+}
+
PropertyInfo qdev_prop_bit = {
.name = "on/off",
.type = PROP_TYPE_BIT,
.size = sizeof(uint32_t),
.parse = parse_bit,
.print = print_bit,
+ .get = get_bit,
+ .set = set_bit,
};
/* --- 8bit integer --- */
@@ -85,12 +117,54 @@ static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len)
return snprintf(dest, len, "%" PRIu8, *ptr);
}
+static void get_int8(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int8_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t value;
+
+ value = *ptr;
+ visit_type_int(v, &value, name, errp);
+}
+
+static void set_int8(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int8_t *ptr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ int64_t value;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_int(v, &value, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if (value > prop->info->min && value <= prop->info->max) {
+ *ptr = value;
+ } else {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+ dev->id?:"", name, value, prop->info->min,
+ prop->info->max);
+ }
+}
+
PropertyInfo qdev_prop_uint8 = {
.name = "uint8",
.type = PROP_TYPE_UINT8,
.size = sizeof(uint8_t),
.parse = parse_uint8,
.print = print_uint8,
+ .get = get_int8,
+ .set = set_int8,
+ .min = 0,
+ .max = 255,
};
/* --- 8bit hex value --- */
@@ -120,6 +194,10 @@ PropertyInfo qdev_prop_hex8 = {
.size = sizeof(uint8_t),
.parse = parse_hex8,
.print = print_hex8,
+ .get = get_int8,
+ .set = set_int8,
+ .min = 0,
+ .max = 255,
};
/* --- 16bit integer --- */
@@ -144,12 +222,54 @@ static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len
return snprintf(dest, len, "%" PRIu16, *ptr);
}
+static void get_int16(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int16_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t value;
+
+ value = *ptr;
+ visit_type_int(v, &value, name, errp);
+}
+
+static void set_int16(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int16_t *ptr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ int64_t value;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_int(v, &value, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if (value > prop->info->min && value <= prop->info->max) {
+ *ptr = value;
+ } else {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+ dev->id?:"", name, value, prop->info->min,
+ prop->info->max);
+ }
+}
+
PropertyInfo qdev_prop_uint16 = {
.name = "uint16",
.type = PROP_TYPE_UINT16,
.size = sizeof(uint16_t),
.parse = parse_uint16,
.print = print_uint16,
+ .get = get_int16,
+ .set = set_int16,
+ .min = 0,
+ .max = 65535,
};
/* --- 32bit integer --- */
@@ -174,12 +294,54 @@ static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len
return snprintf(dest, len, "%" PRIu32, *ptr);
}
+static void get_int32(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t value;
+
+ value = *ptr;
+ visit_type_int(v, &value, name, errp);
+}
+
+static void set_int32(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ int64_t value;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_int(v, &value, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if (value > prop->info->min && value <= prop->info->max) {
+ *ptr = value;
+ } else {
+ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+ dev->id?:"", name, value, prop->info->min,
+ prop->info->max);
+ }
+}
+
PropertyInfo qdev_prop_uint32 = {
.name = "uint32",
.type = PROP_TYPE_UINT32,
.size = sizeof(uint32_t),
.parse = parse_uint32,
.print = print_uint32,
+ .get = get_int32,
+ .set = set_int32,
+ .min = 0,
+ .max = 0xFFFFFFFFULL,
};
static int parse_int32(DeviceState *dev, Property *prop, const char *str)
@@ -207,6 +369,10 @@ PropertyInfo qdev_prop_int32 = {
.size = sizeof(int32_t),
.parse = parse_int32,
.print = print_int32,
+ .get = get_int32,
+ .set = set_int32,
+ .min = -0x80000000LL,
+ .max = 0x7FFFFFFFLL,
};
/* --- 32bit hex value --- */
@@ -236,6 +402,10 @@ PropertyInfo qdev_prop_hex32 = {
.size = sizeof(uint32_t),
.parse = parse_hex32,
.print = print_hex32,
+ .get = get_int32,
+ .set = set_int32,
+ .min = 0,
+ .max = 0xFFFFFFFFULL,
};
/* --- 64bit integer --- */
@@ -260,12 +430,37 @@ static int print_uint64(DeviceState *dev, Property *prop, char *dest, size_t len
return snprintf(dest, len, "%" PRIu64, *ptr);
}
+static void get_int64(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+ visit_type_int(v, ptr, name, errp);
+}
+
+static void set_int64(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ int64_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_int(v, ptr, name, errp);
+}
+
PropertyInfo qdev_prop_uint64 = {
.name = "uint64",
.type = PROP_TYPE_UINT64,
.size = sizeof(uint64_t),
.parse = parse_uint64,
.print = print_uint64,
+ .get = get_int64,
+ .set = set_int64,
};
/* --- 64bit hex value --- */
@@ -295,6 +490,8 @@ PropertyInfo qdev_prop_hex64 = {
.size = sizeof(uint64_t),
.parse = parse_hex64,
.print = print_hex64,
+ .get = get_int64,
+ .set = set_int64,
};
/* --- string --- */
@@ -322,6 +519,48 @@ static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len
return snprintf(dest, len, "\"%s\"", *ptr);
}
+static void get_string(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ char **ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (!*ptr) {
+ char *str = (char *)"";
+ visit_type_str(v, &str, name, errp);
+ } else {
+ visit_type_str(v, ptr, name, errp);
+ }
+}
+
+static void set_string(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ char **ptr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ char *str;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_str(v, &str, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if (!*str) {
+ g_free(str);
+ str = NULL;
+ }
+ if (*ptr) {
+ g_free(*ptr);
+ }
+ *ptr = str;
+}
+
PropertyInfo qdev_prop_string = {
.name = "string",
.type = PROP_TYPE_STRING,
@@ -329,6 +568,8 @@ PropertyInfo qdev_prop_string = {
.parse = parse_string,
.print = print_string,
.free = free_string,
+ .get = get_string,
+ .set = set_string,
};
/* --- drive --- */
@@ -364,12 +605,57 @@ static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
*ptr ? bdrv_get_device_name(*ptr) : "<null>");
}
+static void get_generic(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ void **ptr = qdev_get_prop_ptr(dev, prop);
+ char buffer[1024];
+ char *p = buffer;
+
+ buffer[0] = 0;
+ if (*ptr) {
+ prop->info->print(dev, prop, buffer, sizeof(buffer));
+ }
+ visit_type_str(v, &p, name, errp);
+}
+
+static void set_generic(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ Error *local_err = NULL;
+ char *str;
+ int ret;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_str(v, &str, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if (!*str) {
+ g_free(str);
+ error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+ return;
+ }
+ ret = prop->info->parse(dev, prop, str);
+ error_set_from_qdev_prop_error(errp, ret, dev, prop, str);
+ g_free(str);
+}
+
PropertyInfo qdev_prop_drive = {
.name = "drive",
.type = PROP_TYPE_DRIVE,
.size = sizeof(BlockDriverState *),
.parse = parse_drive,
.print = print_drive,
+ .get = get_generic,
+ .set = set_generic,
.free = free_drive,
};
@@ -407,6 +693,8 @@ PropertyInfo qdev_prop_chr = {
.size = sizeof(CharDriverState*),
.parse = parse_chr,
.print = print_chr,
+ .get = get_generic,
+ .set = set_generic,
};
/* --- netdev device --- */
@@ -441,6 +729,8 @@ PropertyInfo qdev_prop_netdev = {
.size = sizeof(VLANClientState*),
.parse = parse_netdev,
.print = print_netdev,
+ .get = get_generic,
+ .set = set_generic,
};
/* --- vlan --- */
@@ -469,12 +759,57 @@ static int print_vlan(DeviceState *dev, Property *prop, char *dest, size_t len)
}
}
+static void get_vlan(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+ int64_t id;
+
+ id = *ptr ? (*ptr)->id : -1;
+ visit_type_int(v, &id, name, errp);
+}
+
+static void set_vlan(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ VLANState **ptr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ int64_t id;
+ VLANState *vlan;
+
+ if (dev->state != DEV_STATE_CREATED) {
+ error_set(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ visit_type_int(v, &id, name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ if (id == -1) {
+ *ptr = NULL;
+ return;
+ }
+ vlan = qemu_find_vlan(id, 1);
+ if (!vlan) {
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+ name, prop->info->name);
+ return;
+ }
+ *ptr = vlan;
+}
+
PropertyInfo qdev_prop_vlan = {
.name = "vlan",
.type = PROP_TYPE_VLAN,
.size = sizeof(VLANClientState*),
.parse = parse_vlan,
.print = print_vlan,
+ .get = get_vlan,
+ .set = set_vlan,
};
/* --- pointer --- */
@@ -531,6 +866,8 @@ PropertyInfo qdev_prop_macaddr = {
.size = sizeof(MACAddr),
.parse = parse_mac,
.print = print_mac,
+ .get = get_generic,
+ .set = set_generic,
};
/* --- pci address --- */
@@ -570,12 +907,29 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest, size_t
}
}
+static void get_pci_devfn(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ Property *prop = opaque;
+ uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ char buffer[32];
+ char *p = buffer;
+
+ buffer[0] = 0;
+ if (*ptr != -1) {
+ snprintf(buffer, sizeof(buffer), "%02x.%x", *ptr >> 3, *ptr & 7);
+ }
+ visit_type_str(v, &p, name, errp);
+}
+
PropertyInfo qdev_prop_pci_devfn = {
.name = "pci-devfn",
.type = PROP_TYPE_UINT32,
.size = sizeof(uint32_t),
.parse = parse_pci_devfn,
.print = print_pci_devfn,
+ .get = get_pci_devfn,
+ .set = set_generic,
};
/* --- public helpers --- */
diff --git a/hw/qdev.h b/hw/qdev.h
index 94f5ce9..42495ae 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -158,9 +158,13 @@ struct PropertyInfo {
const char *name;
size_t size;
enum PropertyType type;
+ int64_t min;
+ int64_t max;
int (*parse)(DeviceState *dev, Property *prop, const char *str);
int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
void (*free)(DeviceState *dev, Property *prop);
+ DevicePropertyAccessor *get;
+ DevicePropertyAccessor *set;
};
typedef struct GlobalProperty {
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
` (5 preceding siblings ...)
2011-12-18 16:05 ` [Qemu-devel] [PATCH 6/8] qom: introduce get/set methods for Property Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 8/8] qom: register qdev properties also as non-legacy properties Paolo Bonzini
2011-12-19 20:18 ` [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Anthony Liguori
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev-properties.c | 12 ++++++++----
hw/qdev.c | 9 ++++++---
hw/qdev.h | 1 +
3 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 41d2165..663c2a0 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -86,7 +86,8 @@ static void set_bit(DeviceState *dev, Visitor *v, void *opaque,
}
PropertyInfo qdev_prop_bit = {
- .name = "on/off",
+ .name = "boolean",
+ .legacy_name = "on/off",
.type = PROP_TYPE_BIT,
.size = sizeof(uint32_t),
.parse = parse_bit,
@@ -189,7 +190,8 @@ static int print_hex8(DeviceState *dev, Property *prop, char *dest, size_t len)
}
PropertyInfo qdev_prop_hex8 = {
- .name = "hex8",
+ .name = "uint8",
+ .legacy_name = "hex8",
.type = PROP_TYPE_UINT8,
.size = sizeof(uint8_t),
.parse = parse_hex8,
@@ -397,7 +399,8 @@ static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
}
PropertyInfo qdev_prop_hex32 = {
- .name = "hex32",
+ .name = "uint32",
+ .legacy_name = "hex32",
.type = PROP_TYPE_UINT32,
.size = sizeof(uint32_t),
.parse = parse_hex32,
@@ -485,7 +488,8 @@ static int print_hex64(DeviceState *dev, Property *prop, char *dest, size_t len)
}
PropertyInfo qdev_prop_hex64 = {
- .name = "hex64",
+ .name = "uint64",
+ .legacy_name = "hex64",
.type = PROP_TYPE_UINT64,
.size = sizeof(uint64_t),
.parse = parse_hex64,
diff --git a/hw/qdev.c b/hw/qdev.c
index 2a146f7..c6fcf4c 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -218,13 +218,15 @@ int qdev_device_help(QemuOpts *opts)
if (!prop->info->parse) {
continue; /* no way to set it, don't show */
}
- error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
+ error_printf("%s.%s=%s\n", info->name, prop->name,
+ prop->info->legacy_name ?: prop->info->name);
}
for (prop = info->bus_info->props; prop && prop->name; prop++) {
if (!prop->info->parse) {
continue; /* no way to set it, don't show */
}
- error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
+ error_printf("%s.%s=%s\n", info->name, prop->name,
+ prop->info->legacy_name ?: prop->info->name);
}
return 1;
}
@@ -1180,7 +1182,8 @@ void qdev_property_add_legacy(DeviceState *dev, Property *prop,
{
gchar *type;
- type = g_strdup_printf("legacy<%s>", prop->info->name);
+ type = g_strdup_printf("legacy<%s>",
+ prop->info->legacy_name ?: prop->info->name);
qdev_property_add(dev, prop->name, type,
prop->info->print ? qdev_get_legacy_property : NULL,
diff --git a/hw/qdev.h b/hw/qdev.h
index 42495ae..5f23cac 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -156,6 +156,7 @@ enum PropertyType {
struct PropertyInfo {
const char *name;
+ const char *legacy_name;
size_t size;
enum PropertyType type;
int64_t min;
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 8/8] qom: register qdev properties also as non-legacy properties
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
` (6 preceding siblings ...)
2011-12-18 16:05 ` [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
@ 2011-12-18 16:05 ` Paolo Bonzini
2011-12-19 20:18 ` [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Anthony Liguori
8 siblings, 0 replies; 14+ messages in thread
From: Paolo Bonzini @ 2011-12-18 16:05 UTC (permalink / raw)
To: qemu-devel
Push legacy properties into a "legacy-..." namespace, and make them
available with correct types too.
For now, all properties come in both variants. This need not be the
case for string properties. We will revisit this after -device is
changed to actually use the legacy properties.
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/qdev.c | 28 +++++++++++++++++++++++++---
hw/qdev.h | 7 +++----
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index c6fcf4c..0465632 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -80,6 +80,9 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
return NULL;
}
+static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+ Error **errp);
+
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
{
DeviceState *dev;
@@ -104,10 +107,12 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
for (prop = dev->info->props; prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
+ qdev_property_add_static(dev, prop, NULL);
}
for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
qdev_property_add_legacy(dev, prop, NULL);
+ qdev_property_add_static(dev, prop, NULL);
}
qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
@@ -1172,7 +1177,7 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
* @qdev_add_legacy_property - adds a legacy property
*
* Do not use this is new code! Properties added through this interface will
- * be given types in the "legacy<>" type namespace.
+ * be given names and types in the "legacy" namespace.
*
* Legacy properties are always processed as strings. The format of the string
* depends on the property type.
@@ -1180,18 +1185,35 @@ static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void *opaque,
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp)
{
- gchar *type;
+ gchar *name, *type;
+ name = g_strdup_printf("legacy-%s", prop->name);
type = g_strdup_printf("legacy<%s>",
prop->info->legacy_name ?: prop->info->name);
- qdev_property_add(dev, prop->name, type,
+ qdev_property_add(dev, name, type,
prop->info->print ? qdev_get_legacy_property : NULL,
prop->info->parse ? qdev_set_legacy_property : NULL,
NULL,
prop, errp);
g_free(type);
+ g_free(name);
+}
+
+/**
+ * @qdev_property_add_static - add a @Property to a device.
+ *
+ * Static properties access data in a struct. The actual type of the
+ * property and the field depends on the property type.
+ */
+void qdev_property_add_static(DeviceState *dev, Property *prop,
+ Error **errp)
+{
+ qdev_property_add(dev, prop->name, prop->info->name,
+ prop->info->get, prop->info->set,
+ NULL,
+ prop, errp);
}
DeviceState *qdev_get_root(void)
diff --git a/hw/qdev.h b/hw/qdev.h
index 5f23cac..d5896be 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -487,11 +487,10 @@ const char *qdev_property_get_type(DeviceState *dev, const char *name,
Error **errp);
/**
- * @qdev_property_add_legacy - add a legacy @Property to a device
- *
- * DO NOT USE THIS IN NEW CODE!
+ * @qdev_property_add_static - add a @Property to a device referencing a
+ * field in a struct.
*/
-void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
+void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
/**
* @qdev_get_root - returns the root device of the composition tree
--
1.7.7.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
` (7 preceding siblings ...)
2011-12-18 16:05 ` [Qemu-devel] [PATCH 8/8] qom: register qdev properties also as non-legacy properties Paolo Bonzini
@ 2011-12-19 20:18 ` Anthony Liguori
8 siblings, 0 replies; 14+ messages in thread
From: Anthony Liguori @ 2011-12-19 20:18 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On 12/18/2011 10:05 AM, Paolo Bonzini wrote:
> QOM right now does not have a way to communicate values for qdev
> properties except as strings. This is bad.
>
> This patch improves the Property implementation so that properties
> export a visitor-based interface in addition to the string-based
> interface. The new interface can then be registered as a "static"
> property. It's called static because it uses a struct field for
> storage and, as such, should be present in all objects of a given
> class.
>
> Patches 1-2 are bugfixes and patches 3-4 are cleanups.
Applied all. Thanks.
Regards,
Anthony Liguori
>
> Example using qmp-shell:
>
> x86_64-softmmu/qemu-system-x86_64 \
> -hda ~/test.img -snapshot -S \
> -qmp unix:/tmp/server.sock,server,nowait \
> -netdev type=user,id=net -device virtio-net-pci,netdev=net,id=net \
> -net user,vlan=1 -device virtio-net-pci,id=net2,vlan=1 \
> -chardev id=stdio,backend=stdio -device isa-serial,chardev=stdio,id=serial
>
> Boolean properties:
>
> (QEMU) qom-get path=/i440fx/piix3 property=command_serr_enable
> {u'return': True}
> (QEMU) qom-get path=/i440fx/piix3 property=legacy<command_serr_enable>
> {u'return': u'on'}
>
> PCI address properties (perhaps will disappear later, but not yet):
>
> (QEMU) qom-get path=/i440fx/piix3 property=addr
> {u'return': u'01.0'}
> (QEMU) qom-get path=/i440fx/piix3 property=legacy-addr
> {u'return': u'01.0'}
>
> String properties (NULL mapped to empty string):
>
> (QEMU) qom-get path=/vga property=romfile
> {u'return': u'vgabios-cirrus.bin'}
> (QEMU) qom-get path=/vga property=legacy-romfile
> {u'return': u'"vgabios-cirrus.bin"'}
> (QEMU) qom-get path=/i440fx/piix3 property=romfile
> {u'return': u''}
> (QEMU) qom-get path=/i440fx/piix3 property=legacy-romfile
> {u'return': u'<null>'}
>
> MAC properties:
>
> (QEMU) qom-get path=/peripheral/net property=mac
> {u'return': u'52:54:00:12:34:56'}
> (QEMU) qom-get path=/peripheral/net property=legacy-mac
> {u'return': u'52:54:00:12:34:56'}
> (QEMU) qom-set path=/peripheral/net property=mac value=52-54-00-12-34-57
> {u'error': {u'data': {}, u'class': u'PermissionDenied', u'desc': u'Insufficient permission to perform this operation'}}
>
> Network properties:
>
> (QEMU) qom-get path=/peripheral/net property=netdev
> {u'return': u'net'}
> (QEMU) qom-get path=/peripheral/net property=legacy-netdev
> {u'return': u'net'}
>
> VLAN properties:
>
> (QEMU) qom-get path=/peripheral/net property=vlan
> {u'return': -1}
> (QEMU) qom-get path=/peripheral/net property=legacy-vlan
> {u'return': u'<null>'}
> (QEMU) qom-get path=/peripheral/net2 property=vlan
> {u'return': 1}
> (QEMU) qom-get path=/peripheral/net2 property=legacy-vlan
> {u'return': u'1'}
>
> Chardev properties:
>
> (QEMU) qom-get path=/peripheral/serial property=chardev
> {u'return': u'stdio'}
> (QEMU) qom-get path=/peripheral/serial property=legacy-chardev
> {u'return': u'stdio'}
>
> Legacy hex32 properties:
>
> (QEMU) qom-get path=/peripheral/serial property=iobase
> {u'return': 1016}
> (QEMU) qom-get path=/peripheral/serial property=legacy-iobase
> {u'return': u'0x3f8'}
>
> Examples of setting properties (after disabling the DEV_STATE_CREATED
> check for testing only):
>
> (QEMU) qom-set path=/peripheral/net2 property=vlan value=-1
> {u'return': {}}
> (QEMU) qom-get path=/peripheral/net2 property=vlan
> {u'return': -1}
> (QEMU) qom-get path=/peripheral/net2 property=legacy-vlan
> {u'return': u'<null>'}
>
> (QEMU) qom-set path=/peripheral/serial property=iobase value=760
> {u'return': {}}
> (QEMU) qom-get path=/peripheral/serial property=iobase
> {u'return': 760}
> (QEMU) qom-get path=/peripheral/serial property=legacy-iobase
> {u'return': u'0x2f8'}
>
> v2->v3:
> Tweaks to patch 4.
>
> v1->v2:
> New "qom: interpret the return value when setting legacy
> properties". Always pass a value to the visitor when there
> is no error. Handle empty strings as NULL. Did not change
> QERR_PROPERTY_VALUE_OUT_OF_RANGE because it is consistent
> with other QERR_PROPERTY_* errors, now used by QOM too.
>
> Paolo Bonzini (8):
> qapi: protect against NULL QObject in qmp_input_get_object
> qom: fix swapped parameters
> qom: push permission checks up into qdev_property_add_legacy
> qom: interpret the return value when setting legacy properties
> qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE
> qom: introduce get/set methods for Property
> qom: distinguish "legacy" property type name from QOM type name
> qom: register qdev properties also as non-legacy properties
>
> hw/qdev-addr.c | 41 +++++
> hw/qdev-properties.c | 407 +++++++++++++++++++++++++++++++++++++++++++--
> hw/qdev.c | 84 ++++++----
> hw/qdev.h | 14 +-
> qapi/qmp-input-visitor.c | 10 +-
> qerror.c | 5 +
> qerror.h | 3 +
> 7 files changed, 502 insertions(+), 62 deletions(-)
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2011-12-19 20:18 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-18 16:05 [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 1/8] qapi: protect against NULL QObject in qmp_input_get_object Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 2/8] qom: fix swapped parameters Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 3/8] qom: push permission checks up into qdev_property_add_legacy Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 4/8] qom: interpret the return value when setting legacy properties Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 5/8] qom: introduce QERR_PROPERTY_VALUE_OUT_OF_RANGE Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 6/8] qom: introduce get/set methods for Property Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
2011-12-18 16:05 ` [Qemu-devel] [PATCH 8/8] qom: register qdev properties also as non-legacy properties Paolo Bonzini
2011-12-19 20:18 ` [Qemu-devel] [PATCH v3 0/8] qom: introduce non-legacy static properties Anthony Liguori
-- strict thread matches above, loose matches on Subject: below --
2011-12-16 12:01 [Qemu-devel] [PATCH " Paolo Bonzini
2011-12-16 12:01 ` [Qemu-devel] [PATCH 7/8] qom: distinguish "legacy" property type name from QOM type name Paolo Bonzini
2011-12-16 14:06 ` Anthony Liguori
2011-12-16 14:18 ` Paolo Bonzini
2011-12-16 14:43 ` Anthony Liguori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).