summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/block/nbd.h1
-rw-r--r--include/hw/audio/pcspk.h2
-rw-r--r--include/hw/i386/pc.h1
-rw-r--r--include/hw/qdev-properties.h4
-rw-r--r--include/qapi/clone-visitor.h8
-rw-r--r--include/qapi/error.h261
-rw-r--r--include/qapi/visitor-impl.h26
-rw-r--r--include/qapi/visitor.h102
-rw-r--r--include/qemu/option.h16
-rw-r--r--include/qom/object.h104
-rw-r--r--include/qom/object_interfaces.h12
-rw-r--r--include/qom/qom-qobject.h9
12 files changed, 393 insertions, 153 deletions
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 20363280ae..9bc3bfaeec 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -361,6 +361,7 @@ void nbd_server_start_options(NbdServerOptions *arg, Error **errp);
static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size,
const char *desc, Error **errp)
{
+ ERRP_GUARD();
int ret = qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
if (ret < 0) {
diff --git a/include/hw/audio/pcspk.h b/include/hw/audio/pcspk.h
index 06cba00b83..9506179587 100644
--- a/include/hw/audio/pcspk.h
+++ b/include/hw/audio/pcspk.h
@@ -33,7 +33,7 @@
static inline void pcspk_init(ISADevice *isadev, ISABus *bus, ISADevice *pit)
{
- object_property_set_link(OBJECT(isadev), OBJECT(pit), "pit", NULL);
+ object_property_set_link(OBJECT(isadev), "pit", OBJECT(pit), NULL);
isa_realize_and_unref(isadev, bus, &error_fatal);
}
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index a802e69974..3d7ed3a55e 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -186,6 +186,7 @@ ISADevice *pc_find_fdc0(void);
/* pc_sysfw.c */
void pc_system_flash_create(PCMachineState *pcms);
+void pc_system_flash_cleanup_unused(PCMachineState *pcms);
void pc_system_firmware_init(PCMachineState *pcms, MemoryRegion *rom_memory);
/* acpi-build.c */
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 944e3f2e0c..587e5b7d31 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -239,8 +239,8 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
/*
* Set properties between creation and realization.
*/
-void qdev_prop_set_drive_err(DeviceState *dev, const char *name,
- BlockBackend *value, Error **errp);
+bool qdev_prop_set_drive_err(DeviceState *dev, const char *name,
+ BlockBackend *value, Error **errp);
/*
* Set properties between creation and realization.
diff --git a/include/qapi/clone-visitor.h b/include/qapi/clone-visitor.h
index 5b665ee38c..adf9a788e2 100644
--- a/include/qapi/clone-visitor.h
+++ b/include/qapi/clone-visitor.h
@@ -20,10 +20,10 @@
*/
typedef struct QapiCloneVisitor QapiCloneVisitor;
-void *qapi_clone(const void *src, void (*visit_type)(Visitor *, const char *,
+void *qapi_clone(const void *src, bool (*visit_type)(Visitor *, const char *,
void **, Error **));
void qapi_clone_members(void *dst, const void *src, size_t sz,
- void (*visit_type_members)(Visitor *, void *,
+ bool (*visit_type_members)(Visitor *, void *,
Error **));
/*
@@ -34,7 +34,7 @@ void qapi_clone_members(void *dst, const void *src, size_t sz,
*/
#define QAPI_CLONE(type, src) \
((type *)qapi_clone(src, \
- (void (*)(Visitor *, const char *, void**, \
+ (bool (*)(Visitor *, const char *, void **, \
Error **))visit_type_ ## type))
/*
@@ -45,7 +45,7 @@ void qapi_clone_members(void *dst, const void *src, size_t sz,
*/
#define QAPI_CLONE_MEMBERS(type, dst, src) \
qapi_clone_members(dst, src, sizeof(type), \
- (void (*)(Visitor *, void *, \
+ (bool (*)(Visitor *, void *, \
Error **))visit_type_ ## type ## _members)
#endif
diff --git a/include/qapi/error.h b/include/qapi/error.h
index ad5b6e896d..7932594dce 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -15,18 +15,55 @@
/*
* Error reporting system loosely patterned after Glib's GError.
*
+ * = Rules =
+ *
+ * - Functions that use Error to report errors have an Error **errp
+ * parameter. It should be the last parameter, except for functions
+ * taking variable arguments.
+ *
+ * - You may pass NULL to not receive the error, &error_abort to abort
+ * on error, &error_fatal to exit(1) on error, or a pointer to a
+ * variable containing NULL to receive the error.
+ *
+ * - Separation of concerns: the function is responsible for detecting
+ * errors and failing cleanly; handling the error is its caller's
+ * job. Since the value of @errp is about handling the error, the
+ * function should not examine it.
+ *
+ * - The function may pass @errp to functions it calls to pass on
+ * their errors to its caller. If it dereferences @errp to check
+ * for errors, it must use ERRP_GUARD().
+ *
+ * - On success, the function should not touch *errp. On failure, it
+ * should set a new error, e.g. with error_setg(errp, ...), or
+ * propagate an existing one, e.g. with error_propagate(errp, ...).
+ *
+ * - Whenever practical, also return a value that indicates success /
+ * failure. This can make the error checking more concise, and can
+ * avoid useless error object creation and destruction. Note that
+ * we still have many functions returning void. We recommend
+ * • bool-valued functions return true on success / false on failure,
+ * • pointer-valued functions return non-null / null pointer, and
+ * • integer-valued functions return non-negative / negative.
+ *
+ * = Creating errors =
+ *
* Create an error:
- * error_setg(&err, "situation normal, all fouled up");
+ * error_setg(errp, "situation normal, all fouled up");
+ * where @errp points to the location to receive the error.
*
* Create an error and add additional explanation:
- * error_setg(&err, "invalid quark");
- * error_append_hint(&err, "Valid quarks are up, down, strange, "
+ * error_setg(errp, "invalid quark");
+ * error_append_hint(errp, "Valid quarks are up, down, strange, "
* "charm, top, bottom.\n");
+ * This may require use of ERRP_GUARD(); more on that below.
*
* Do *not* contract this to
- * error_setg(&err, "invalid quark\n"
+ * error_setg(errp, "invalid quark\n" // WRONG!
* "Valid quarks are up, down, strange, charm, top, bottom.");
*
+ * = Reporting and destroying errors =
+ *
* Report an error to the current monitor if we have one, else stderr:
* error_report_err(err);
* This frees the error object.
@@ -40,6 +77,30 @@
* error_free(err);
* Note that this loses hints added with error_append_hint().
*
+ * Call a function ignoring errors:
+ * foo(arg, NULL);
+ * This is more concise than
+ * Error *err = NULL;
+ * foo(arg, &err);
+ * error_free(err); // don't do this
+ *
+ * Call a function aborting on errors:
+ * foo(arg, &error_abort);
+ * This is more concise and fails more nicely than
+ * Error *err = NULL;
+ * foo(arg, &err);
+ * assert(!err); // don't do this
+ *
+ * Call a function treating errors as fatal:
+ * foo(arg, &error_fatal);
+ * This is more concise than
+ * Error *err = NULL;
+ * foo(arg, &err);
+ * if (err) { // don't do this
+ * error_report_err(err);
+ * exit(1);
+ * }
+ *
* Handle an error without reporting it (just for completeness):
* error_free(err);
*
@@ -47,57 +108,73 @@
* reporting it (primarily useful in testsuites):
* error_free_or_abort(&err);
*
- * Pass an existing error to the caller:
- * error_propagate(errp, err);
- * where Error **errp is a parameter, by convention the last one.
+ * = Passing errors around =
*
- * Pass an existing error to the caller with the message modified:
- * error_propagate_prepend(errp, err);
- *
- * Avoid
- * error_propagate(errp, err);
- * error_prepend(errp, "Could not frobnicate '%s': ", name);
- * because this fails to prepend when @errp is &error_fatal.
+ * Errors get passed to the caller through the conventional @errp
+ * parameter.
*
* Create a new error and pass it to the caller:
* error_setg(errp, "situation normal, all fouled up");
*
- * Call a function and receive an error from it:
- * Error *err = NULL;
- * foo(arg, &err);
- * if (err) {
+ * Call a function, receive an error from it, and pass it to the caller
+ * - when the function returns a value that indicates failure, say
+ * false:
+ * if (!foo(arg, errp)) {
* handle the error...
* }
+ * - when it does not, say because it is a void function:
+ * ERRP_GUARD();
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * }
+ * More on ERRP_GUARD() below.
*
- * Call a function ignoring errors:
- * foo(arg, NULL);
- *
- * Call a function aborting on errors:
- * foo(arg, &error_abort);
- *
- * Call a function treating errors as fatal:
- * foo(arg, &error_fatal);
- *
- * Receive an error and pass it on to the caller:
+ * Code predating ERRP_GUARD() still exists, and looks like this:
* Error *err = NULL;
* foo(arg, &err);
* if (err) {
* handle the error...
- * error_propagate(errp, err);
+ * error_propagate(errp, err); // deprecated
* }
- * where Error **errp is a parameter, by convention the last one.
- *
- * Do *not* "optimize" this to
+ * Avoid in new code. Do *not* "optimize" it to
* foo(arg, errp);
* if (*errp) { // WRONG!
* handle the error...
* }
- * because errp may be NULL!
+ * because errp may be NULL without the ERRP_GUARD() guard.
*
* But when all you do with the error is pass it on, please use
* foo(arg, errp);
* for readability.
*
+ * Receive an error, and handle it locally
+ * - when the function returns a value that indicates failure, say
+ * false:
+ * Error *err = NULL;
+ * if (!foo(arg, &err)) {
+ * handle the error...
+ * }
+ * - when it does not, say because it is a void function:
+ * Error *err = NULL;
+ * foo(arg, &err);
+ * if (err) {
+ * handle the error...
+ * }
+ *
+ * Pass an existing error to the caller:
+ * error_propagate(errp, err);
+ * This is rarely needed. When @err is a local variable, use of
+ * ERRP_GUARD() commonly results in more readable code.
+ *
+ * Pass an existing error to the caller with the message modified:
+ * error_propagate_prepend(errp, err,
+ * "Could not frobnicate '%s': ", name);
+ * This is more concise than
+ * error_propagate(errp, err); // don't do this
+ * error_prepend(errp, "Could not frobnicate '%s': ", name);
+ * and works even when @errp is &error_fatal.
+ *
* Receive and accumulate multiple errors (first one wins):
* Error *err = NULL, *local_err = NULL;
* foo(arg, &err);
@@ -108,12 +185,88 @@
* }
*
* Do *not* "optimize" this to
+ * Error *err = NULL;
* foo(arg, &err);
* bar(arg, &err); // WRONG!
* if (err) {
* handle the error...
* }
* because this may pass a non-null err to bar().
+ *
+ * Likewise, do *not*
+ * Error *err = NULL;
+ * if (cond1) {
+ * error_setg(&err, ...);
+ * }
+ * if (cond2) {
+ * error_setg(&err, ...); // WRONG!
+ * }
+ * because this may pass a non-null err to error_setg().
+ *
+ * = Why, when and how to use ERRP_GUARD() =
+ *
+ * Without ERRP_GUARD(), use of the @errp parameter is restricted:
+ * - It must not be dereferenced, because it may be null.
+ * - It should not be passed to error_prepend() or
+ * error_append_hint(), because that doesn't work with &error_fatal.
+ * ERRP_GUARD() lifts these restrictions.
+ *
+ * To use ERRP_GUARD(), add it right at the beginning of the function.
+ * @errp can then be used without worrying about the argument being
+ * NULL or &error_fatal.
+ *
+ * Using it when it's not needed is safe, but please avoid cluttering
+ * the source with useless code.
+ *
+ * = Converting to ERRP_GUARD() =
+ *
+ * To convert a function to use ERRP_GUARD():
+ *
+ * 0. If the Error ** parameter is not named @errp, rename it to
+ * @errp.
+ *
+ * 1. Add an ERRP_GUARD() invocation, by convention right at the
+ * beginning of the function. This makes @errp safe to use.
+ *
+ * 2. Replace &err by errp, and err by *errp. Delete local variable
+ * @err.
+ *
+ * 3. Delete error_propagate(errp, *errp), replace
+ * error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...)
+ *
+ * 4. Ensure @errp is valid at return: when you destroy *errp, set
+ * errp = NULL.
+ *
+ * Example:
+ *
+ * bool fn(..., Error **errp)
+ * {
+ * Error *err = NULL;
+ *
+ * foo(arg, &err);
+ * if (err) {
+ * handle the error...
+ * error_propagate(errp, err);
+ * return false;
+ * }
+ * ...
+ * }
+ *
+ * becomes
+ *
+ * bool fn(..., Error **errp)
+ * {
+ * ERRP_GUARD();
+ *
+ * foo(arg, errp);
+ * if (*errp) {
+ * handle the error...
+ * return false;
+ * }
+ * ...
+ * }
+ *
+ * For mass-conversion, use scripts/coccinelle/errp-guard.cocci.
*/
#ifndef ERROR_H
@@ -214,6 +367,7 @@ void error_setg_win32_internal(Error **errp,
* the error object.
* Else, move the error object from @local_err to *@dst_errp.
* On return, @local_err is invalid.
+ * Please use ERRP_GUARD() instead when possible.
* Please don't error_propagate(&error_fatal, ...), use
* error_report_err() and exit(), because that's more obvious.
*/
@@ -225,6 +379,7 @@ void error_propagate(Error **dst_errp, Error *local_err);
* Behaves like
* error_prepend(&local_err, fmt, ...);
* error_propagate(dst_errp, local_err);
+ * Please use ERRP_GUARD() and error_prepend() instead when possible.
*/
void error_propagate_prepend(Error **dst_errp, Error *local_err,
const char *fmt, ...);
@@ -323,6 +478,46 @@ void error_set_internal(Error **errp,
GCC_FMT_ATTR(6, 7);
/*
+ * Make @errp parameter easier to use regardless of argument value
+ *
+ * This macro is for use right at the beginning of a function that
+ * takes an Error **errp parameter to pass errors to its caller. The
+ * parameter must be named @errp.
+ *
+ * It must be used when the function dereferences @errp or passes
+ * @errp to error_prepend(), error_vprepend(), or error_append_hint().
+ * It is safe to use even when it's not needed, but please avoid
+ * cluttering the source with useless code.
+ *
+ * If @errp is NULL or &error_fatal, rewrite it to point to a local
+ * Error variable, which will be automatically propagated to the
+ * original @errp on function exit.
+ *
+ * Note: &error_abort is not rewritten, because that would move the
+ * abort from the place where the error is created to the place where
+ * it's propagated.
+ */
+#define ERRP_GUARD() \
+ g_auto(ErrorPropagator) _auto_errp_prop = {.errp = errp}; \
+ do { \
+ if (!errp || errp == &error_fatal) { \
+ errp = &_auto_errp_prop.local_err; \
+ } \
+ } while (0)
+
+typedef struct ErrorPropagator {
+ Error *local_err;
+ Error **errp;
+} ErrorPropagator;
+
+static inline void error_propagator_cleanup(ErrorPropagator *prop)
+{
+ error_propagate(prop->errp, prop->local_err);
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ErrorPropagator, error_propagator_cleanup);
+
+/*
* Special error destination to abort on error.
* See error_setg() and error_propagate() for details.
*/
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 98dc533d39..7362c043be 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -48,31 +48,31 @@ struct Visitor
*/
/* Must be set to visit structs */
- void (*start_struct)(Visitor *v, const char *name, void **obj,
+ bool (*start_struct)(Visitor *v, const char *name, void **obj,
size_t size, Error **errp);
/* Optional; intended for input visitors */
- void (*check_struct)(Visitor *v, Error **errp);
+ bool (*check_struct)(Visitor *v, Error **errp);
/* Must be set to visit structs */
void (*end_struct)(Visitor *v, void **obj);
/* Must be set; implementations may require @list to be non-null,
* but must document it. */
- void (*start_list)(Visitor *v, const char *name, GenericList **list,
+ bool (*start_list)(Visitor *v, const char *name, GenericList **list,
size_t size, Error **errp);
/* Must be set */
GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size);
/* Optional; intended for input visitors */
- void (*check_list)(Visitor *v, Error **errp);
+ bool (*check_list)(Visitor *v, Error **errp);
/* Must be set */
void (*end_list)(Visitor *v, void **list);
/* Must be set by input and clone visitors to visit alternates */
- void (*start_alternate)(Visitor *v, const char *name,
+ bool (*start_alternate)(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
Error **errp);
@@ -80,33 +80,33 @@ struct Visitor
void (*end_alternate)(Visitor *v, void **obj);
/* Must be set */
- void (*type_int64)(Visitor *v, const char *name, int64_t *obj,
+ bool (*type_int64)(Visitor *v, const char *name, int64_t *obj,
Error **errp);
/* Must be set */
- void (*type_uint64)(Visitor *v, const char *name, uint64_t *obj,
+ bool (*type_uint64)(Visitor *v, const char *name, uint64_t *obj,
Error **errp);
/* Optional; fallback is type_uint64() */
- void (*type_size)(Visitor *v, const char *name, uint64_t *obj,
+ bool (*type_size)(Visitor *v, const char *name, uint64_t *obj,
Error **errp);
/* Must be set */
- void (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
+ bool (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
/* Must be set */
- void (*type_str)(Visitor *v, const char *name, char **obj, Error **errp);
+ bool (*type_str)(Visitor *v, const char *name, char **obj, Error **errp);
/* Must be set to visit numbers */
- void (*type_number)(Visitor *v, const char *name, double *obj,
+ bool (*type_number)(Visitor *v, const char *name, double *obj,
Error **errp);
/* Must be set to visit arbitrary QTypes */
- void (*type_any)(Visitor *v, const char *name, QObject **obj,
+ bool (*type_any)(Visitor *v, const char *name, QObject **obj,
Error **errp);
/* Must be set to visit explicit null values. */
- void (*type_null)(Visitor *v, const char *name, QNull **obj,
+ bool (*type_null)(Visitor *v, const char *name, QNull **obj,
Error **errp);
/* Must be set for input visitors to visit structs, optional otherwise.
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 5573906966..ebc19ede7f 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -60,7 +60,7 @@
* All QAPI types have a corresponding function with a signature
* roughly compatible with this:
*
- * void visit_type_FOO(Visitor *v, const char *name, T obj, Error **errp);
+ * bool visit_type_FOO(Visitor *v, const char *name, T obj, Error **errp);
*
* where T is FOO for scalar types, and FOO * otherwise. The scalar
* visitors are declared here; the remaining visitors are generated in
@@ -95,14 +95,16 @@
* incomplete object, such an object is possible only by manual
* construction.
*
+ * visit_type_FOO() returns true on success, false on error.
+ *
* For the QAPI object types (structs, unions, and alternates), there
* is an additional generated function in qapi-visit-MODULE.h
* compatible with:
*
- * void visit_type_FOO_members(Visitor *v, FOO *obj, Error **errp);
+ * bool visit_type_FOO_members(Visitor *v, FOO *obj, Error **errp);
*
* for visiting the members of a type without also allocating the QAPI
- * struct.
+ * struct. It also returns true on success, false on error.
*
* Additionally, QAPI pointer types (structs, unions, alternates, and
* lists) have a generated function in qapi-types-MODULE.h compatible
@@ -131,8 +133,7 @@
* Visitor *v;
*
* v = FOO_visitor_new(...);
- * visit_type_Foo(v, NULL, &f, &err);
- * if (err) {
+ * if (!visit_type_Foo(v, NULL, &f, &err)) {
* ...handle error...
* } else {
* ...use f...
@@ -148,8 +149,7 @@
* Visitor *v;
*
* v = FOO_visitor_new(...);
- * visit_type_FooList(v, NULL, &l, &err);
- * if (err) {
+ * if (!visit_type_FooList(v, NULL, &l, &err)) {
* ...handle error...
* } else {
* for ( ; l; l = l->next) {
@@ -186,34 +186,32 @@
* <example>
* Visitor *v;
* Error *err = NULL;
+ * bool ok = false;
* int value;
*
* v = FOO_visitor_new(...);
- * visit_start_struct(v, NULL, NULL, 0, &err);
- * if (err) {
+ * if (!visit_start_struct(v, NULL, NULL, 0, &err)) {
* goto out;
* }
- * visit_start_list(v, "list", NULL, 0, &err);
- * if (err) {
+ * if (!visit_start_list(v, "list", NULL, 0, &err)) {
* goto outobj;
* }
* value = 1;
- * visit_type_int(v, NULL, &value, &err);
- * if (err) {
+ * if (!visit_type_int(v, NULL, &value, &err)) {
* goto outlist;
* }
* value = 2;
- * visit_type_int(v, NULL, &value, &err);
- * if (err) {
+ * if (!visit_type_int(v, NULL, &value, &err)) {
* goto outlist;
* }
+ * ok = true;
* outlist:
- * if (!err) {
- * visit_check_list(v, &err);
+ * if (ok) {
+ * ok = visit_check_list(v, &err);
* }
* visit_end_list(v, NULL);
- * if (!err) {
- * visit_check_struct(v, &err);
+ * if (ok) {
+ * ok = visit_check_struct(v, &err);
* }
* outobj:
* visit_end_struct(v, NULL);
@@ -286,6 +284,8 @@ void visit_free(Visitor *v);
* On failure, set *@obj to NULL and store an error through @errp.
* Can happen only when @v is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* After visit_start_struct() succeeds, the caller may visit its
* members one after the other, passing the member's name and address
* within the struct. Finally, visit_end_struct() needs to be called
@@ -295,7 +295,7 @@ void visit_free(Visitor *v);
* FIXME Should this be named visit_start_object, since it is also
* used for QAPI unions, and maps to JSON objects?
*/
-void visit_start_struct(Visitor *v, const char *name, void **obj,
+bool visit_start_struct(Visitor *v, const char *name, void **obj,
size_t size, Error **errp);
/*
@@ -304,12 +304,14 @@ void visit_start_struct(Visitor *v, const char *name, void **obj,
* On failure, store an error through @errp. Can happen only when @v
* is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* Should be called prior to visit_end_struct() if all other
* intermediate visit steps were successful, to allow the visitor one
* last chance to report errors. May be skipped on a cleanup path,
* where there is no need to check for further errors.
*/
-void visit_check_struct(Visitor *v, Error **errp);
+bool visit_check_struct(Visitor *v, Error **errp);
/*
* Complete an object visit started earlier.
@@ -341,6 +343,8 @@ void visit_end_struct(Visitor *v, void **obj);
* On failure, set *@list to NULL and store an error through @errp.
* Can happen only when @v is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* After visit_start_list() succeeds, the caller may visit its members
* one after the other. A real visit (where @list is non-NULL) uses
* visit_next_list() for traversing the linked list, while a virtual
@@ -351,7 +355,7 @@ void visit_end_struct(Visitor *v, void **obj);
* same @list to clean up, even if intermediate visits fail. See the
* examples above.
*/
-void visit_start_list(Visitor *v, const char *name, GenericList **list,
+bool visit_start_list(Visitor *v, const char *name, GenericList **list,
size_t size, Error **errp);
/*
@@ -376,12 +380,14 @@ GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size);
* On failure, store an error through @errp. Can happen only when @v
* is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* Should be called prior to visit_end_list() if all other
* intermediate visit steps were successful, to allow the visitor one
* last chance to report errors. May be skipped on a cleanup path,
* where there is no need to check for further errors.
*/
-void visit_check_list(Visitor *v, Error **errp);
+bool visit_check_list(Visitor *v, Error **errp);
/*
* Complete a list visit started earlier.
@@ -412,11 +418,13 @@ void visit_end_list(Visitor *v, void **list);
* On failure, set *@obj to NULL and store an error through @errp.
* Can happen only when @v is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* If successful, this must be paired with visit_end_alternate() with
* the same @obj to clean up, even if visiting the contents of the
* alternate fails.
*/
-void visit_start_alternate(Visitor *v, const char *name,
+bool visit_start_alternate(Visitor *v, const char *name,
GenericAlternate **obj, size_t size,
Error **errp);
@@ -468,12 +476,14 @@ bool visit_optional(Visitor *v, const char *name, bool *present);
* On failure, store an error through @errp. Can happen only when @v
* is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* May call visit_type_str() under the hood, and the enum visit may
* fail even if the corresponding string visit succeeded; this implies
* that an input visitor's visit_type_str() must have no unwelcome
* side effects.
*/
-void visit_type_enum(Visitor *v, const char *name, int *obj,
+bool visit_type_enum(Visitor *v, const char *name, int *obj,
const QEnumLookup *lookup, Error **errp);
/*
@@ -499,28 +509,30 @@ bool visit_is_dealloc(Visitor *v);
*
* On failure, store an error through @errp. Can happen only when @v
* is an input visitor.
+ *
+ * Return true on success, false on failure.
*/
-void visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp);
+bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp);
/*
* Visit a uint8_t value.
* Like visit_type_int(), except clamps the value to uint8_t range.
*/
-void visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
+bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
Error **errp);
/*
* Visit a uint16_t value.
* Like visit_type_int(), except clamps the value to uint16_t range.
*/
-void visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
+bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
Error **errp);
/*
* Visit a uint32_t value.
* Like visit_type_int(), except clamps the value to uint32_t range.
*/
-void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
+bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
Error **errp);
/*
@@ -528,34 +540,34 @@ void visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
* Like visit_type_int(), except clamps the value to uint64_t range,
* that is, ensures it is unsigned.
*/
-void visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
+bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
Error **errp);
/*
* Visit an int8_t value.
* Like visit_type_int(), except clamps the value to int8_t range.
*/
-void visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp);
+bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp);
/*
* Visit an int16_t value.
* Like visit_type_int(), except clamps the value to int16_t range.
*/
-void visit_type_int16(Visitor *v, const char *name, int16_t *obj,
+bool visit_type_int16(Visitor *v, const char *name, int16_t *obj,
Error **errp);
/*
* Visit an int32_t value.
* Like visit_type_int(), except clamps the value to int32_t range.
*/
-void visit_type_int32(Visitor *v, const char *name, int32_t *obj,
+bool visit_type_int32(Visitor *v, const char *name, int32_t *obj,
Error **errp);
/*
* Visit an int64_t value.
* Identical to visit_type_int().
*/
-void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
+bool visit_type_int64(Visitor *v, const char *name, int64_t *obj,
Error **errp);
/*
@@ -564,7 +576,7 @@ void visit_type_int64(Visitor *v, const char *name, int64_t *obj,
* recognize additional syntax, such as suffixes for easily scaling
* values.
*/
-void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
+bool visit_type_size(Visitor *v, const char *name, uint64_t *obj,
Error **errp);
/*
@@ -578,8 +590,10 @@ void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
*
* On failure, store an error through @errp. Can happen only when @v
* is an input visitor.
+ *
+ * Return true on success, false on failure.
*/
-void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
+bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
/*
* Visit a string value.
@@ -598,9 +612,11 @@ void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
* On failure, set *@obj to NULL and store an error through @errp.
* Can happen only when @v is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* FIXME: Callers that try to output NULL *obj should not be allowed.
*/
-void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
+bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
/*
* Visit a number (i.e. double) value.
@@ -614,8 +630,10 @@ void visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
*
* On failure, store an error through @errp. Can happen only when @v
* is an input visitor.
+ *
+ * Return true on success, false on failure.
*/
-void visit_type_number(Visitor *v, const char *name, double *obj,
+bool visit_type_number(Visitor *v, const char *name, double *obj,
Error **errp);
/*
@@ -631,11 +649,13 @@ void visit_type_number(Visitor *v, const char *name, double *obj,
* On failure, set *@obj to NULL and store an error through @errp.
* Can happen only when @v is an input visitor.
*
+ * Return true on success, false on failure.
+ *
* Note that some kinds of input can't express arbitrary QObject.
* E.g. the visitor returned by qobject_input_visitor_new_keyval()
* can't create numbers or booleans, only strings.
*/
-void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
+bool visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
/*
* Visit a JSON null value.
@@ -648,8 +668,10 @@ void visit_type_any(Visitor *v, const char *name, QObject **obj, Error **errp);
*
* On failure, set *@obj to NULL and store an error through @errp.
* Can happen only when @v is an input visitor.
+ *
+ * Return true on success, false on failure.
*/
-void visit_type_null(Visitor *v, const char *name, QNull **obj,
+bool visit_type_null(Visitor *v, const char *name, QNull **obj,
Error **errp);
#endif
diff --git a/include/qemu/option.h b/include/qemu/option.h
index ac50d25774..05e8a15c73 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -43,7 +43,7 @@
*/
const char *get_opt_value(const char *p, char **value);
-void parse_option_size(const char *name, const char *value,
+bool parse_option_size(const char *name, const char *value,
uint64_t *ret, Error **errp);
bool has_help_option(const char *param);
@@ -93,11 +93,11 @@ uint64_t qemu_opt_get_number_del(QemuOpts *opts, const char *name,
uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
uint64_t defval);
int qemu_opt_unset(QemuOpts *opts, const char *name);
-void qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
+bool qemu_opt_set(QemuOpts *opts, const char *name, const char *value,
Error **errp);
-void qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
+bool qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val,
Error **errp);
-void qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
+bool qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val,
Error **errp);
typedef int (*qemu_opt_loopfunc)(void *opaque,
const char *name, const char *value,
@@ -119,13 +119,13 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);
void qemu_opts_reset(QemuOptsList *list);
void qemu_opts_loc_restore(QemuOpts *opts);
-void qemu_opts_set(QemuOptsList *list, const char *id,
+bool qemu_opts_set(QemuOptsList *list, const char *id,
const char *name, const char *value, Error **errp);
const char *qemu_opts_id(QemuOpts *opts);
void qemu_opts_set_id(QemuOpts *opts, char *id);
void qemu_opts_del(QemuOpts *opts);
-void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
-void qemu_opts_do_parse(QemuOpts *opts, const char *params,
+bool qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error **errp);
+bool qemu_opts_do_parse(QemuOpts *opts, const char *params,
const char *firstname, Error **errp);
QemuOpts *qemu_opts_parse_noisily(QemuOptsList *list, const char *params,
bool permit_abbrev);
@@ -138,7 +138,7 @@ QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict,
QemuOptsList *list, bool del);
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
-void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
+bool qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
typedef int (*qemu_opts_loopfunc)(void *opaque, QemuOpts *opts, Error **errp);
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func,
diff --git a/include/qom/object.h b/include/qom/object.h
index 51f188137f..10fd4a2d4c 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -671,8 +671,7 @@ Object *object_new(const char *typename);
* NULL);
*
* if (!obj) {
- * g_printerr("Cannot create memory backend: %s\n",
- * error_get_pretty(err));
+ * error_reportf_err(err, "Cannot create memory backend: ");
* }
* </programlisting>
* </example>
@@ -704,7 +703,7 @@ Object *object_new_with_propv(const char *typename,
Error **errp,
va_list vargs);
-void object_apply_global_props(Object *obj, const GPtrArray *props,
+bool object_apply_global_props(Object *obj, const GPtrArray *props,
Error **errp);
void object_set_machine_compat_props(GPtrArray *compat_props);
void object_set_accelerator_compat_props(GPtrArray *compat_props);
@@ -730,17 +729,14 @@ void object_apply_compat_props(Object *obj);
* Error *err = NULL;
* Object *obj = ...get / create object...;
*
- * obj = object_set_props(obj,
- * &err,
- * "share", "yes",
- * "mem-path", "/dev/shm/somefile",
- * "prealloc", "yes",
- * "size", "1048576",
- * NULL);
- *
- * if (!obj) {
- * g_printerr("Cannot set properties: %s\n",
- * error_get_pretty(err));
+ * if (!object_set_props(obj,
+ * &err,
+ * "share", "yes",
+ * "mem-path", "/dev/shm/somefile",
+ * "prealloc", "yes",
+ * "size", "1048576",
+ * NULL)) {
+ * error_reportf_err(err, "Cannot set properties: ");
* }
* </programlisting>
* </example>
@@ -748,11 +744,9 @@ void object_apply_compat_props(Object *obj);
* The returned object will have one stable reference maintained
* for as long as it is present in the object hierarchy.
*
- * Returns: -1 on error, 0 on success
+ * Returns: %true on success, %false on error.
*/
-int object_set_props(Object *obj,
- Error **errp,
- ...) QEMU_SENTINEL;
+bool object_set_props(Object *obj, Error **errp, ...) QEMU_SENTINEL;
/**
* object_set_propv:
@@ -762,11 +756,9 @@ int object_set_props(Object *obj,
*
* See object_set_props() for documentation.
*
- * Returns: -1 on error, 0 on success
+ * Returns: %true on success, %false on error.
*/
-int object_set_propv(Object *obj,
- Error **errp,
- va_list vargs);
+bool object_set_propv(Object *obj, Error **errp, va_list vargs);
/**
* object_initialize:
@@ -800,8 +792,10 @@ void object_initialize(void *obj, size_t size, const char *typename);
* strings. The propname of %NULL indicates the end of the property list.
* If the object implements the user creatable interface, the object will
* be marked complete once all the properties have been processed.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_initialize_child_with_props(Object *parentobj,
+bool object_initialize_child_with_props(Object *parentobj,
const char *propname,
void *childobj, size_t size, const char *type,
Error **errp, ...) QEMU_SENTINEL;
@@ -817,8 +811,10 @@ void object_initialize_child_with_props(Object *parentobj,
* @vargs: list of property names and values
*
* See object_initialize_child() for documentation.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_initialize_child_with_propsv(Object *parentobj,
+bool object_initialize_child_with_propsv(Object *parentobj,
const char *propname,
void *childobj, size_t size, const char *type,
Error **errp, va_list vargs);
@@ -1205,26 +1201,30 @@ void object_unparent(Object *obj);
/**
* object_property_get:
* @obj: the object
+ * @name: the name of the property
* @v: the visitor that will receive the property value. This should be an
* Output visitor and the data will be written with @name as the name.
- * @name: the name of the property
* @errp: returns an error if this function fails
*
* Reads a property from a object.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_get(Object *obj, Visitor *v, const char *name,
+bool object_property_get(Object *obj, const char *name, Visitor *v,
Error **errp);
/**
* object_property_set_str:
- * @value: the value to be written to the property
* @name: the name of the property
+ * @value: the value to be written to the property
* @errp: returns an error if this function fails
*
* Writes a string value to a property.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_set_str(Object *obj, const char *value,
- const char *name, Error **errp);
+bool object_property_set_str(Object *obj, const char *name,
+ const char *value, Error **errp);
/**
* object_property_get_str:
@@ -1241,8 +1241,8 @@ char *object_property_get_str(Object *obj, const char *name,
/**
* object_property_set_link:
- * @value: the value to be written to the property
* @name: the name of the property
+ * @value: the value to be written to the property
* @errp: returns an error if this function fails
*
* Writes an object's canonical path to a property.
@@ -1251,9 +1251,10 @@ char *object_property_get_str(Object *obj, const char *name,
* <code>OBJ_PROP_LINK_STRONG</code> bit, the old target object is
* unreferenced, and a reference is added to the new target object.
*
+ * Returns: %true on success, %false on failure.
*/
-void object_property_set_link(Object *obj, Object *value,
- const char *name, Error **errp);
+bool object_property_set_link(Object *obj, const char *name,
+ Object *value, Error **errp);
/**
* object_property_get_link:
@@ -1270,14 +1271,16 @@ Object *object_property_get_link(Object *obj, const char *name,
/**
* object_property_set_bool:
- * @value: the value to be written to the property
* @name: the name of the property
+ * @value: the value to be written to the property
* @errp: returns an error if this function fails
*
* Writes a bool value to a property.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_set_bool(Object *obj, bool value,
- const char *name, Error **errp);
+bool object_property_set_bool(Object *obj, const char *name,
+ bool value, Error **errp);
/**
* object_property_get_bool:
@@ -1293,14 +1296,16 @@ bool object_property_get_bool(Object *obj, const char *name,
/**
* object_property_set_int:
- * @value: the value to be written to the property
* @name: the name of the property
+ * @value: the value to be written to the property
* @errp: returns an error if this function fails
*
* Writes an integer value to a property.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_set_int(Object *obj, int64_t value,
- const char *name, Error **errp);
+bool object_property_set_int(Object *obj, const char *name,
+ int64_t value, Error **errp);
/**
* object_property_get_int:
@@ -1316,14 +1321,16 @@ int64_t object_property_get_int(Object *obj, const char *name,
/**
* object_property_set_uint:
- * @value: the value to be written to the property
* @name: the name of the property
+ * @value: the value to be written to the property
* @errp: returns an error if this function fails
*
* Writes an unsigned integer value to a property.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_set_uint(Object *obj, uint64_t value,
- const char *name, Error **errp);
+bool object_property_set_uint(Object *obj, const char *name,
+ uint64_t value, Error **errp);
/**
* object_property_get_uint:
@@ -1354,28 +1361,32 @@ int object_property_get_enum(Object *obj, const char *name,
/**
* object_property_set:
* @obj: the object
+ * @name: the name of the property
* @v: the visitor that will be used to write the property value. This should
* be an Input visitor and the data will be first read with @name as the
* name and then written as the property value.
- * @name: the name of the property
* @errp: returns an error if this function fails
*
* Writes a property to a object.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_set(Object *obj, Visitor *v, const char *name,
+bool object_property_set(Object *obj, const char *name, Visitor *v,
Error **errp);
/**
* object_property_parse:
* @obj: the object
- * @string: the string that will be used to parse the property value.
* @name: the name of the property
+ * @string: the string that will be used to parse the property value.
* @errp: returns an error if this function fails
*
* Parses a string and writes the result into a property of an object.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_parse(Object *obj, const char *string,
- const char *name, Error **errp);
+bool object_property_parse(Object *obj, const char *name,
+ const char *string, Error **errp);
/**
* object_property_print:
@@ -1817,6 +1828,7 @@ ObjectProperty *object_property_add_const_link(Object *obj, const char *name,
*
* Set an object property's description.
*
+ * Returns: %true on success, %false on failure.
*/
void object_property_set_description(Object *obj, const char *name,
const char *description);
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 65172120fa..7035829337 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -57,8 +57,10 @@ typedef struct UserCreatableClass {
* Wrapper to call complete() method if one of types it's inherited
* from implements USER_CREATABLE interface, otherwise the call does
* nothing.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void user_creatable_complete(UserCreatable *uc, Error **errp);
+bool user_creatable_complete(UserCreatable *uc, Error **errp);
/**
* user_creatable_can_be_deleted:
@@ -100,8 +102,10 @@ Object *user_creatable_add_type(const char *type, const char *id,
* @qdict. The object type is taken from the QDict key 'qom-type', its
* ID from the key 'id'. The remaining entries in @qdict are used to
* initialize the object properties.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
+bool user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
/**
* user_creatable_add_opts:
@@ -167,8 +171,10 @@ bool user_creatable_print_help(const char *type, QemuOpts *opts);
*
* Delete an instance of the user creatable object identified
* by @id.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void user_creatable_del(const char *id, Error **errp);
+bool user_creatable_del(const char *id, Error **errp);
/**
* user_creatable_cleanup:
diff --git a/include/qom/qom-qobject.h b/include/qom/qom-qobject.h
index 82136e6e80..73e4e0e474 100644
--- a/include/qom/qom-qobject.h
+++ b/include/qom/qom-qobject.h
@@ -28,13 +28,16 @@ struct QObject *object_property_get_qobject(Object *obj, const char *name,
/**
* object_property_set_qobject:
* @obj: the object
- * @ret: The value that will be written to the property.
* @name: the name of the property
+ * @value: The value that will be written to the property.
* @errp: returns an error if this function fails
*
* Writes a property to a object.
+ *
+ * Returns: %true on success, %false on failure.
*/
-void object_property_set_qobject(Object *obj, struct QObject *qobj,
- const char *name, struct Error **errp);
+bool object_property_set_qobject(Object *obj,
+ const char *name, struct QObject *value,
+ struct Error **errp);
#endif