@@ -149,6 +149,11 @@ DeviceState *qdev_new(const char *name)
return DEVICE(object_new_dynamic(name, &error_abort));
}
+DeviceState *qdev_new_dynamic(const char *name, Error **errp)
+{
+ return DEVICE(object_new_dynamic(name, errp));
+}
+
static QTAILQ_HEAD(, DeviceListener) device_listeners
= QTAILQ_HEAD_INITIALIZER(device_listeners);
@@ -435,14 +435,41 @@ compat_props_add(GPtrArray *arr,
* qdev_new: Create a device on the heap
* @name: device type to create (we assert() that this type exists)
*
+ * This method should be used where @name is statically specified
+ * from a const string at build time, where the caller does not expect
+ * failure to be possible.
+ *
* This only allocates the memory and initializes the device state
* structure, ready for the caller to set properties if they wish.
* The device still needs to be realized.
*
+ * If an instance of @name is not permitted to be instantiated, an
+ * assert will be raised. This can happen if @name is abstract.
+ *
* Return: a derived DeviceState object with a reference count of 1.
*/
DeviceState *qdev_new(const char *name);
+/**
+ * qdev_new_dynamic: Create a device on the heap
+ * @name: device type to create (we assert() that this type exists)
+ * @errp: pointer to be filled with error details on failure
+ *
+ * This method must be used where @name is dynamically chosen
+ * at runtime, which has the possibility of unexpected choices leading
+ * to failures.
+ *
+ * This only allocates the memory and initializes the device state
+ * structure, ready for the caller to set properties if they wish.
+ * The device still needs to be realized.
+ *
+ * If an instance of @name is not permitted to be instantiated, an
+ * error will be reported. This can happen if @name is abstract.
+ *
+ * Return: a derived DeviceState object with a reference count of 1.
+ */
+DeviceState *qdev_new_dynamic(const char *name, Error **errp);
+
/**
* qdev_is_realized() - check if device is realized
* @dev: The device to check.
qdev_new() has a failure scenario where it will assert() if given an abstract type. Callers which are creating qdevs based on user input, or unknown/untrusted type names, must manually check the result of qdev_class_is_abstract() before calling qdev_new() to propagate an Error, instead of asserting. Introduce a qdev_new_dynamic() method which is a counterpart to qdev_new() that directly returns an Error, instead of asserting. This new method is to be used where the typename is specified dynamically by code separate from the immediate caller. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- hw/core/qdev.c | 5 +++++ include/hw/qdev-core.h | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+)