From f1fb9f0dc087c02b230be4cc96c5c76521f188fa Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 26 Jun 2015 14:22:36 +0100 Subject: qdev-properties-system: Change set_pointer's parse callback to use Error Instead of having set_pointer() call a parse callback which returns an error number that we then convert to an Error string with error_set_from_qdev_prop_error(), make the parse callback take an Error** and set the error itself. This will allow parse routines to provide more helpful error messages than the generic ones. Signed-off-by: Peter Maydell Reviewed-by: Markus Armbruster Reviewed-by: Stefan Hajnoczi Message-id: 1435068107-12594-2-git-send-email-peter.maydell@linaro.org --- hw/core/qdev-properties-system.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'hw/core/qdev-properties-system.c') diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index aa794ca445..c731bc657f 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -35,15 +35,15 @@ static void get_pointer(Object *obj, Visitor *v, Property *prop, } static void set_pointer(Object *obj, Visitor *v, Property *prop, - int (*parse)(DeviceState *dev, const char *str, - void **ptr), + void (*parse)(DeviceState *dev, const char *str, + void **ptr, const char *propname, + Error **errp), const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); Error *local_err = NULL; void **ptr = qdev_get_prop_ptr(dev, prop); char *str; - int ret; if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); @@ -60,26 +60,29 @@ static void set_pointer(Object *obj, Visitor *v, Property *prop, *ptr = NULL; return; } - ret = parse(dev, str, ptr); - error_set_from_qdev_prop_error(errp, ret, dev, prop, str); + parse(dev, str, ptr, prop->name, errp); g_free(str); } /* --- drive --- */ -static int parse_drive(DeviceState *dev, const char *str, void **ptr) +static void parse_drive(DeviceState *dev, const char *str, void **ptr, + const char *propname, Error **errp) { BlockBackend *blk; blk = blk_by_name(str); if (!blk) { - return -ENOENT; + error_setg(errp, "Property '%s.%s' can't find value '%s'", + object_get_typename(OBJECT(dev)), propname, str); + return; } if (blk_attach_dev(blk, dev) < 0) { - return -EEXIST; + error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", + object_get_typename(OBJECT(dev)), propname, str); + return; } *ptr = blk; - return 0; } static void release_drive(Object *obj, const char *name, void *opaque) @@ -121,17 +124,21 @@ PropertyInfo qdev_prop_drive = { /* --- character device --- */ -static int parse_chr(DeviceState *dev, const char *str, void **ptr) +static void parse_chr(DeviceState *dev, const char *str, void **ptr, + const char *propname, Error **errp) { CharDriverState *chr = qemu_chr_find(str); if (chr == NULL) { - return -ENOENT; + error_setg(errp, "Property '%s.%s' can't find value '%s'", + object_get_typename(OBJECT(dev)), propname, str); + return; } if (qemu_chr_fe_claim(chr) != 0) { - return -EEXIST; + error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", + object_get_typename(OBJECT(dev)), propname, str); + return; } *ptr = chr; - return 0; } static void release_chr(Object *obj, const char *name, void *opaque) -- cgit 1.4.1 From 62f7dbde4c75e48921fd1b773865250130c57bd8 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 26 Jun 2015 14:22:36 +0100 Subject: qdev-properties-system: Improve error message for drive assignment conflict If the user forgot if=none on their drive specification they're likely to get an error message because the drive is assigned once automatically by QEMU and once by the manual id=/drive= user command line specification. Improve the error message produced in this case to explicitly guide the user towards if=none. We rephrase the "drive conflict but not for an if=something" error as well to keep the wording in line. The two cases that change are: (1) Drive specified as to be auto-connected and also manually connected (and the board does handle this if= type): qemu-system-x86_64 -nodefaults -display none \ -drive if=scsi,file=tmp.qcow2,id=foo -device ide-hd,drive=foo Previously: qemu-system-x86_64: -device ide-hd,drive=foo: Property 'ide-hd.drive' can't take value 'foo', it's in use Now: qemu-system-x86_64: -device ide-hd,drive=foo: Drive 'foo' is already in use because it has been automatically connected to another device (did you need 'if=none' in the drive options?) (2) Drive specified to be manually connected in two different ways: qemu-system-x86_64 -nodefaults -display none \ -drive if=none,file=tmp.qcow2,id=foo -device ide-hd,drive=foo \ -device ide-hd,drive=foo Previously: qemu-system-x86_64: -device ide-hd,drive=foo: Property 'ide-hd.drive' can't take value 'foo', it's in use Now: qemu-system-x86_64: -device ide-hd,drive=foo: Drive 'foo' is already in use by another device Signed-off-by: Peter Maydell Reviewed-by: Markus Armbruster Reviewed-by: Stefan Hajnoczi Message-id: 1435068107-12594-3-git-send-email-peter.maydell@linaro.org --- hw/core/qdev-properties-system.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'hw/core/qdev-properties-system.c') diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index c731bc657f..921e799dbb 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -78,8 +78,17 @@ static void parse_drive(DeviceState *dev, const char *str, void **ptr, return; } if (blk_attach_dev(blk, dev) < 0) { - error_setg(errp, "Property '%s.%s' can't take value '%s', it's in use", - object_get_typename(OBJECT(dev)), propname, str); + DriveInfo *dinfo = blk_legacy_dinfo(blk); + + if (dinfo->type != IF_NONE) { + error_setg(errp, "Drive '%s' is already in use because " + "it has been automatically connected to another " + "device (did you need 'if=none' in the drive options?)", + str); + } else { + error_setg(errp, "Drive '%s' is already in use by another device", + str); + } return; } *ptr = blk; -- cgit 1.4.1