* [Qemu-devel] [PATCH 9/9] monitor: do_info_balloon(): use QError
2009-10-13 16:56 [Qemu-devel] [PATCH v0 0/9] QError Luiz Capitulino
@ 2009-10-13 16:57 ` Luiz Capitulino
0 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-10-13 16:57 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
monitor.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/monitor.c b/monitor.c
index 6f0ad11..5d7c816 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1717,10 +1717,9 @@ static void do_info_balloon(Monitor *mon, QObject **ret_data)
actual = qemu_balloon_status();
if (kvm_enabled() && !kvm_has_sync_mmu())
- monitor_printf(mon, "Using KVM without synchronous MMU, "
- "ballooning disabled\n");
+ qemu_error_structed(QERR_BAL_MMU, NULL);
else if (actual == 0)
- monitor_printf(mon, "Ballooning not activated in VM\n");
+ qemu_error_structed(QERR_BAL_DIS, NULL);
else
*ret_data = QOBJECT(qint_from_int((int)(actual >> 20)));
}
--
1.6.5.rc3.8.g8ba5e
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 0/9]: QError v3
@ 2009-11-12 20:42 Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va() Luiz Capitulino
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
Hi,
This is a new QError version which implements what has been suggested
by Anthony in this email:
http://lists.gnu.org/archive/html/qemu-devel/2009-11/msg00601.html
Basically, the error table is back and qemu_error_new() calls are like
this:
qemu_error_new(QERR_DEVICE_NOT_FOUND, driver);
Thanks.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va()
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 21:39 ` Anthony Liguori
2009-11-12 20:42 ` [Qemu-devel] [PATCH 2/9] QString: Introduce qstring_append_chr() Luiz Capitulino
` (7 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
Accepts a va_list, will be used by QError.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
qjson.c | 14 ++++++++++++++
qjson.h | 2 ++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/qjson.c b/qjson.c
index 7270909..491b61e 100644
--- a/qjson.c
+++ b/qjson.c
@@ -64,6 +64,20 @@ QObject *qobject_from_jsonf(const char *string, ...)
return state.result;
}
+QObject *qobject_from_json_va(const char *string, va_list *ap)
+{
+ JSONParsingState state = {};
+
+ state.ap = ap;
+
+ json_message_parser_init(&state.parser, parse_json);
+ json_message_parser_feed(&state.parser, string, strlen(string));
+ json_message_parser_flush(&state.parser);
+ json_message_parser_destroy(&state.parser);
+
+ return state.result;
+}
+
typedef struct ToJsonIterState
{
int count;
diff --git a/qjson.h b/qjson.h
index 7fce742..8b89e41 100644
--- a/qjson.h
+++ b/qjson.h
@@ -14,12 +14,14 @@
#ifndef QJSON_H
#define QJSON_H
+#include <stdarg.h>
#include "qobject.h"
#include "qstring.h"
QObject *qobject_from_json(const char *string);
QObject *qobject_from_jsonf(const char *string, ...)
__attribute__((__format__ (__printf__, 1, 2)));
+QObject *qobject_from_json_va(const char *string, va_list *ap);
QString *qobject_to_json(const QObject *obj);
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 2/9] QString: Introduce qstring_append_chr()
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va() Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 3/9] QString: Introduce qstring_append_int() Luiz Capitulino
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
It appends a C char to a QString.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
qstring.c | 24 +++++++++++++++++++-----
qstring.h | 1 +
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/qstring.c b/qstring.c
index 441a9e6..e422bd9 100644
--- a/qstring.c
+++ b/qstring.c
@@ -53,25 +53,39 @@ QString *qstring_from_str(const char *str)
return qstring;
}
-/* qstring_append(): Append a C string to a QString
- */
-void qstring_append(QString *qstring, const char *str)
+static void capacity_increase(QString *qstring, size_t len)
{
- size_t len = strlen(str);
-
if (qstring->capacity < (qstring->length + len)) {
qstring->capacity += len;
qstring->capacity *= 2; /* use exponential growth */
qstring->string = qemu_realloc(qstring->string, qstring->capacity + 1);
}
+}
+
+/* qstring_append(): Append a C string to a QString
+ */
+void qstring_append(QString *qstring, const char *str)
+{
+ size_t len = strlen(str);
+ capacity_increase(qstring, len);
memcpy(qstring->string + qstring->length, str, len);
qstring->length += len;
qstring->string[qstring->length] = 0;
}
/**
+ * qstring_append_chr(): Append a C char to a QString
+ */
+void qstring_append_chr(QString *qstring, int c)
+{
+ capacity_increase(qstring, 1);
+ qstring->string[qstring->length++] = c;
+ qstring->string[qstring->length] = 0;
+}
+
+/**
* qobject_to_qstring(): Convert a QObject to a QString
*/
QString *qobject_to_qstring(const QObject *obj)
diff --git a/qstring.h b/qstring.h
index 65905d4..43581de 100644
--- a/qstring.h
+++ b/qstring.h
@@ -14,6 +14,7 @@ QString *qstring_new(void);
QString *qstring_from_str(const char *str);
const char *qstring_get_str(const QString *qstring);
void qstring_append(QString *qstring, const char *str);
+void qstring_append_chr(QString *qstring, int c);
QString *qobject_to_qstring(const QObject *obj);
#endif /* QSTRING_H */
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 3/9] QString: Introduce qstring_append_int()
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va() Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 2/9] QString: Introduce qstring_append_chr() Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 4/9] Add qstring_append_chr() unit-test Luiz Capitulino
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
qstring.c | 8 ++++++++
qstring.h | 2 ++
2 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/qstring.c b/qstring.c
index e422bd9..ad17769 100644
--- a/qstring.c
+++ b/qstring.c
@@ -75,6 +75,14 @@ void qstring_append(QString *qstring, const char *str)
qstring->string[qstring->length] = 0;
}
+void qstring_append_int(QString *qstring, int64_t value)
+{
+ char num[32];
+
+ snprintf(num, sizeof(num), "%" PRId64, value);
+ qstring_append(qstring, num);
+}
+
/**
* qstring_append_chr(): Append a C char to a QString
*/
diff --git a/qstring.h b/qstring.h
index 43581de..c065331 100644
--- a/qstring.h
+++ b/qstring.h
@@ -1,6 +1,7 @@
#ifndef QSTRING_H
#define QSTRING_H
+#include <stdint.h>
#include "qobject.h"
typedef struct QString {
@@ -13,6 +14,7 @@ typedef struct QString {
QString *qstring_new(void);
QString *qstring_from_str(const char *str);
const char *qstring_get_str(const QString *qstring);
+void qstring_append_int(QString *qstring, int64_t value);
void qstring_append(QString *qstring, const char *str);
void qstring_append_chr(QString *qstring, int c);
QString *qobject_to_qstring(const QObject *obj);
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 4/9] Add qstring_append_chr() unit-test
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
` (2 preceding siblings ...)
2009-11-12 20:42 ` [Qemu-devel] [PATCH 3/9] QString: Introduce qstring_append_int() Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 5/9] Introduce QError Luiz Capitulino
` (4 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
check-qstring.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/check-qstring.c b/check-qstring.c
index ea4dfd0..412038a 100644
--- a/check-qstring.c
+++ b/check-qstring.c
@@ -55,6 +55,22 @@ START_TEST(qstring_get_str_test)
}
END_TEST
+START_TEST(qstring_append_chr_test)
+{
+ int i;
+ QString *qstring;
+ const char *str = "qstring append char unit-test";
+
+ qstring = qstring_new();
+
+ for (i = 0; str[i]; i++)
+ qstring_append_chr(qstring, str[i]);
+
+ fail_unless(strcmp(str, qstring_get_str(qstring)) == 0);
+ QDECREF(qstring);
+}
+END_TEST
+
START_TEST(qobject_to_qstring_test)
{
QString *qstring;
@@ -78,6 +94,7 @@ static Suite *qstring_suite(void)
tcase_add_test(qstring_public_tcase, qstring_from_str_test);
tcase_add_test(qstring_public_tcase, qstring_destroy_test);
tcase_add_test(qstring_public_tcase, qstring_get_str_test);
+ tcase_add_test(qstring_public_tcase, qstring_append_chr_test);
tcase_add_test(qstring_public_tcase, qobject_to_qstring_test);
return s;
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 5/9] Introduce QError
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
` (3 preceding siblings ...)
2009-11-12 20:42 ` [Qemu-devel] [PATCH 4/9] Add qstring_append_chr() unit-test Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 6/9] QJSON: Fix compile error Luiz Capitulino
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
QError is a high-level data type which represents an exception
in QEMU, it stores the following error information:
- class Error class name (eg. "ServiceUnavailable")
- description A detailed error description, which may contain
references to run-time error data
- filename The file name of where the error occurred
- line number The exact line number of the error
- run-time data Any run-time error data
This commit adds the basic interface plus two error classes, one
for 'device not found' errors and another one for 'service unavailable'
errors.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
Makefile | 2 +-
qerror.c | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
qerror.h | 46 ++++++++++
qobject.h | 1 +
4 files changed, 331 insertions(+), 1 deletions(-)
create mode 100644 qerror.c
create mode 100644 qerror.h
diff --git a/Makefile b/Makefile
index 4998226..98625e7 100644
--- a/Makefile
+++ b/Makefile
@@ -138,7 +138,7 @@ obj-y += qemu-char.o aio.o savevm.o
obj-y += msmouse.o ps2.o
obj-y += qdev.o qdev-properties.o
obj-y += qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o json-lexer.o
-obj-y += json-streamer.o json-parser.o qjson.o
+obj-y += json-streamer.o json-parser.o qjson.o qerror.o
obj-y += qemu-config.o
obj-$(CONFIG_BRLAPI) += baum.o
diff --git a/qerror.c b/qerror.c
new file mode 100644
index 0000000..91b0f72
--- /dev/null
+++ b/qerror.c
@@ -0,0 +1,283 @@
+/*
+ * QError: QEMU Error data-type.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#include "qjson.h"
+#include "qerror.h"
+#include "qstring.h"
+#include "sysemu.h"
+#include "qemu-common.h"
+
+static void qerror_destroy_obj(QObject *obj);
+
+static const QType qerror_type = {
+ .code = QTYPE_QERROR,
+ .destroy = qerror_destroy_obj,
+};
+
+/**
+ * The 'desc' parameter is a printf-like string, the format of the format
+ * string is:
+ *
+ * %(KEY)TYPE
+ *
+ * Where KEY is a QDict key and TYPE is the type of its value, KEY and
+ * its value must be passed to qerror_from_info().
+ *
+ * Valid types are:
+ *
+ * s (string)
+ * d (integer)
+ *
+ * Example:
+ *
+ * "foo error on device: %(device)s slot: %(slot_nr)d"
+ *
+ * A single percent sign can be printed if followed by a second one,
+ * for example:
+ *
+ * "running out of foo: %(foo)d%%"
+ */
+const QErrorStringTable qerror_table[] = {
+ {
+ .error_fmt = QERR_DEVICE_NOT_FOUND,
+ .desc = "device \"%(name)s\" not found",
+ },
+ {
+ .error_fmt = QERR_SERVICE_UNAVAILABLE,
+ .desc = "%(reason)s",
+ },
+ {}
+};
+
+/**
+ * qerror_new(): Create a new QError
+ *
+ * Return strong reference.
+ */
+QError *qerror_new(void)
+{
+ QError *qerr;
+
+ qerr = qemu_mallocz(sizeof(*qerr));
+ QOBJECT_INIT(qerr, &qerror_type);
+
+ return qerr;
+}
+
+static void qerror_abort(const QError *qerr, const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "qerror: ");
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ fprintf(stderr, " call at %s:%d\n", qerr->file, qerr->linenr);
+ abort();
+}
+
+static void qerror_set_data(QError *qerr, const char *fmt, va_list *va)
+{
+ QObject *obj;
+
+ obj = qobject_from_json_va(fmt, va);
+ if (!obj) {
+ qerror_abort(qerr, "invalid format '%s'", fmt);
+ }
+ if (qobject_type(obj) != QTYPE_QDICT) {
+ qerror_abort(qerr, "error format is not a QDict '%s'", fmt);
+ }
+
+ qerr->error = qobject_to_qdict(obj);
+
+ obj = qdict_get(qerr->error, "class");
+ if (!obj) {
+ qerror_abort(qerr, "missing 'class' key in '%s'", fmt);
+ }
+ if (qobject_type(obj) != QTYPE_QSTRING) {
+ qerror_abort(qerr, "'class' key value should be a QString");
+ }
+
+ obj = qdict_get(qerr->error, "data");
+ if (!obj) {
+ qerror_abort(qerr, "missing 'data' key in '%s'", fmt);
+ }
+ if (qobject_type(obj) != QTYPE_QDICT) {
+ qerror_abort(qerr, "'data' key value should be a QDICT");
+ }
+}
+
+static void qerror_set_desc(const char *fmt, QError *qerr)
+{
+ int i;
+
+ // FIXME: inefficient loop
+
+ for (i = 0; qerror_table[i].error_fmt; i++) {
+ if (strcmp(qerror_table[i].error_fmt, fmt) == 0) {
+ qerr->entry = &qerror_table[i];
+ return;
+ }
+ }
+
+ qerror_abort(qerr, "error format '%s' not found", fmt);
+}
+
+/**
+ * qerror_from_info(): Create a new QError from error information
+ *
+ * The information consists of:
+ *
+ * - file the file name of where the error occurred
+ * - linenr the line number of where the error occurred
+ * - fmt JSON printf-like dictionary, there must exist keys 'class' and
+ * 'data'
+ * - va va_list of all arguments specified by fmt
+ *
+ * Return strong reference.
+ */
+QError *qerror_from_info(const char *file, int linenr, const char *fmt,
+ va_list *va)
+{
+ QError *qerr;
+
+ qerr = qerror_new();
+ qerr->linenr = linenr;
+ qerr->file = file;
+
+ if (!fmt) {
+ qerror_abort(qerr, "QDict not specified");
+ }
+
+ qerror_set_data(qerr, fmt, va);
+ qerror_set_desc(fmt, qerr);
+
+ return qerr;
+}
+
+static char *get_substr(const char *start, const char *end)
+{
+ char *str;
+ size_t length;
+
+ length = end - start + 1;
+ str = qemu_malloc(length + 1);
+ memcpy(str, start, length);
+ str[length] = '\0';
+
+ return str;
+}
+
+static void parse_error(const QError *qerror, int c)
+{
+ qerror_abort(qerror, "expected '%c' in '%s'", c, qerror->entry->desc);
+}
+
+static const char *append_field(QString *qstring, const QError *qerror,
+ const char *start)
+{
+ int type;
+ char *name;
+ QDict *qdict;
+ const char *end;
+
+ if (*start != '%')
+ parse_error(qerror, '%');
+ start++;
+ if (*start != '(')
+ parse_error(qerror, '(');
+ start++;
+
+ end = strchr(start, ')');
+ if (!end)
+ parse_error(qerror, ')');
+
+ name = get_substr(start, end - 1);
+ qdict = qobject_to_qdict(qdict_get(qerror->error, "data"));
+
+ if (!qdict_haskey(qdict, name)) {
+ qerror_abort(qerror, "key '%s' not found in QDict", name);
+ }
+
+ type = *++end;
+ switch (type) {
+ case 's':
+ qstring_append(qstring, qdict_get_str(qdict, name));
+ break;
+ case 'd':
+ qstring_append_int(qstring, qdict_get_int(qdict, name));
+ break;
+ default:
+ qerror_abort(qerror, "invalid type '%c'", type);
+ }
+
+ qemu_free(name);
+ return ++end;
+}
+
+/**
+ * qerror_print(): Print QError data
+ *
+ * This function will print the member 'desc' of the specified QError object,
+ * it uses qemu_error() for this, so that the output is routed to the right
+ * place (ie. stderr ou Monitor's device).
+ */
+void qerror_print(const QError *qerror)
+{
+ const char *p;
+ QString *qstring;
+
+ assert(qerror->entry != NULL);
+
+ qstring = qstring_new();
+
+ for (p = qerror->entry->desc; *p != '\0';) {
+ if (*p != '%') {
+ qstring_append_chr(qstring, *p++);
+ } else if (*(p + 1) == '%') {
+ qstring_append_chr(qstring, '%');
+ p += 2;
+ } else {
+ p = append_field(qstring, qerror, p);
+ }
+ }
+
+ qemu_error("%s\n", qstring_get_str(qstring));
+ QDECREF(qstring);
+}
+
+/**
+ * qobject_to_qerror(): Convert a QObject into a QError
+ */
+QError *qobject_to_qerror(const QObject *obj)
+{
+ if (qobject_type(obj) != QTYPE_QERROR) {
+ return NULL;
+ }
+
+ return container_of(obj, QError, base);
+}
+
+/**
+ * qerror_destroy_obj(): Free all memory allocated by a QError
+ */
+static void qerror_destroy_obj(QObject *obj)
+{
+ QError *qerr;
+
+ assert(obj != NULL);
+ qerr = qobject_to_qerror(obj);
+
+ QDECREF(qerr->error);
+ qemu_free(qerr);
+}
diff --git a/qerror.h b/qerror.h
new file mode 100644
index 0000000..dc1aa35
--- /dev/null
+++ b/qerror.h
@@ -0,0 +1,46 @@
+/*
+ * QError header file.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef QERROR_H
+#define QERROR_H
+
+#include "qdict.h"
+#include <stdarg.h>
+
+typedef struct QErrorStringTable {
+ const char *desc;
+ const char *error_fmt;
+} QErrorStringTable;
+
+typedef struct QError {
+ QObject_HEAD;
+ QDict *error;
+ int linenr;
+ const char *file;
+ const QErrorStringTable *entry;
+} QError;
+
+QError *qerror_new(void);
+QError *qerror_from_info(const char *file, int linenr, const char *fmt,
+ va_list *va);
+void qerror_print(const QError *qerror);
+QError *qobject_to_qerror(const QObject *obj);
+
+/*
+ * QEMU error format list
+ */
+#define QERR_DEVICE_NOT_FOUND \
+ "{ 'class': 'DeviceNotFound', 'data': { 'name': %s } }"
+
+#define QERR_SERVICE_UNAVAILABLE \
+ "{ 'class': 'ServiceUnavailable', 'data': { 'reason': %s } }"
+
+#endif /* QERROR_H */
diff --git a/qobject.h b/qobject.h
index 2270ec1..07de211 100644
--- a/qobject.h
+++ b/qobject.h
@@ -43,6 +43,7 @@ typedef enum {
QTYPE_QLIST,
QTYPE_QFLOAT,
QTYPE_QBOOL,
+ QTYPE_QERROR,
} qtype_code;
struct QObject;
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 6/9] QJSON: Fix compile error
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
` (4 preceding siblings ...)
2009-11-12 20:42 ` [Qemu-devel] [PATCH 5/9] Introduce QError Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 7/9] monitor: QError support Luiz Capitulino
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
Add QTYPE_QERROR handling in the to_json() switch, otherwise GCC
will complain.
We just abort(), as QError design is not finished yet.
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
qjson.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/qjson.c b/qjson.c
index 491b61e..ca4fe7c 100644
--- a/qjson.c
+++ b/qjson.c
@@ -239,6 +239,9 @@ static void to_json(const QObject *obj, QString *str)
}
case QTYPE_NONE:
break;
+ case QTYPE_QERROR:
+ fprintf(stderr, "qerror can't be emitted yet\n");
+ abort();
}
}
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 7/9] monitor: QError support
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
` (5 preceding siblings ...)
2009-11-12 20:42 ` [Qemu-devel] [PATCH 6/9] QJSON: Fix compile error Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 8/9] qdev: Use QError for 'device not found' error Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 9/9] monitor: do_info_balloon(): use QError Luiz Capitulino
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
This commit adds QError support in the Monitor.
A QError member is added to the Monitor struct. This new member
stores error information and is also used to check if an error
has occurred when the called handlers returns.
Additionally, a new macro called qemu_error_new() is introduced.
It should be used in pace of qemu_error() to report errors.
When all conversion to qemu_error_new() is done, qemu_error() can
be turned private.
Basically, Monitor's error flow is something like this:
1. An error occurs in the handler, it calls qemu_error_new()
2. qemu_error_new() builds a new QError object and stores it in
the Monitor struct
3. The handler returns
4. Top level Monitor code checks the Monitor struct and calls
qerror_print() to print the error
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
monitor.c | 42 +++++++++++++++++++++++++++++++++++++++++-
sysemu.h | 6 ++++++
2 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/monitor.c b/monitor.c
index 132fb6e..a8fd552 100644
--- a/monitor.c
+++ b/monitor.c
@@ -49,6 +49,7 @@
#include "qlist.h"
#include "qdict.h"
#include "qstring.h"
+#include "qerror.h"
//#define DEBUG
//#define DEBUG_COMPLETION
@@ -103,6 +104,7 @@ struct Monitor {
CPUState *mon_cpu;
BlockDriverCompletionFunc *password_completion_cb;
void *password_opaque;
+ QError *error;
QLIST_HEAD(,mon_fd_t) fds;
QLIST_ENTRY(Monitor) entry;
};
@@ -3146,6 +3148,18 @@ fail:
return NULL;
}
+static inline int monitor_has_error(const Monitor *mon)
+{
+ return mon->error != NULL;
+}
+
+static void monitor_print_error(Monitor *mon)
+{
+ qerror_print(mon->error);
+ QDECREF(mon->error);
+ mon->error = NULL;
+}
+
static void monitor_handle_command(Monitor *mon, const char *cmdline)
{
QDict *qdict;
@@ -3171,7 +3185,10 @@ static void monitor_handle_command(Monitor *mon, const char *cmdline)
cmd->mhandler.cmd(mon, qdict);
}
- qemu_errors_to_previous();
+ if (monitor_has_error(mon))
+ monitor_print_error(mon);
+
+ qemu_errors_to_previous();
out:
QDECREF(qdict);
@@ -3622,3 +3639,26 @@ void qemu_error(const char *fmt, ...)
break;
}
}
+
+void qemu_error_full(const char *file, int linenr, const char *fmt, ...)
+{
+ va_list va;
+ QError *qerror;
+
+ assert(qemu_error_sink != NULL);
+
+ va_start(va, fmt);
+ qerror = qerror_from_info(file, linenr, fmt, &va);
+ va_end(va);
+
+ switch (qemu_error_sink->dest) {
+ case ERR_SINK_FILE:
+ qerror_print(qerror);
+ QDECREF(qerror);
+ break;
+ case ERR_SINK_MONITOR:
+ assert(qemu_error_sink->mon->error == NULL);
+ qemu_error_sink->mon->error = qerror;
+ break;
+ }
+}
diff --git a/sysemu.h b/sysemu.h
index 96804b4..5891def 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -7,6 +7,7 @@
#include "qemu-queue.h"
#include "qemu-timer.h"
#include "qdict.h"
+#include "qerror.h"
#ifdef _WIN32
#include <windows.h>
@@ -71,6 +72,11 @@ void qemu_errors_to_file(FILE *fp);
void qemu_errors_to_mon(Monitor *mon);
void qemu_errors_to_previous(void);
void qemu_error(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
+void qemu_error_full(const char *file, int linenr, const char *fmt, ...)
+ __attribute__ ((format(printf, 3, 4)));
+
+#define qemu_error_new(fmt, ...) \
+ qemu_error_full(__FILE__, __LINE__, fmt, ## __VA_ARGS__)
#ifdef _WIN32
/* Polling handling */
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 8/9] qdev: Use QError for 'device not found' error
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
` (6 preceding siblings ...)
2009-11-12 20:42 ` [Qemu-devel] [PATCH 7/9] monitor: QError support Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 9/9] monitor: do_info_balloon(): use QError Luiz Capitulino
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
hw/qdev.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index d19d531..875ca50 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -29,6 +29,7 @@
#include "qdev.h"
#include "sysemu.h"
#include "monitor.h"
+#include "qerror.h"
static int qdev_hotplug = 0;
@@ -176,8 +177,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
/* find driver */
info = qdev_find_info(NULL, driver);
if (!info) {
- qemu_error("Device \"%s\" not found. Try -device '?' for a list.\n",
- driver);
+ qemu_error_new(QERR_DEVICE_NOT_FOUND, driver);
return NULL;
}
if (info->no_user) {
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH 9/9] monitor: do_info_balloon(): use QError
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
` (7 preceding siblings ...)
2009-11-12 20:42 ` [Qemu-devel] [PATCH 8/9] qdev: Use QError for 'device not found' error Luiz Capitulino
@ 2009-11-12 20:42 ` Luiz Capitulino
8 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-12 20:42 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori, kraxel, armbru
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
monitor.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/monitor.c b/monitor.c
index a8fd552..76cb187 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1717,10 +1717,11 @@ static void do_info_balloon(Monitor *mon, QObject **ret_data)
actual = qemu_balloon_status();
if (kvm_enabled() && !kvm_has_sync_mmu())
- monitor_printf(mon, "Using KVM without synchronous MMU, "
- "ballooning disabled\n");
+ qemu_error_new(QERR_SERVICE_UNAVAILABLE,
+ "Using KVM without synchronous MMU, ballooning disabled");
else if (actual == 0)
- monitor_printf(mon, "Ballooning not activated in VM\n");
+ qemu_error_new(QERR_SERVICE_UNAVAILABLE,
+ "Ballooning not activated in VM");
else
*ret_data = QOBJECT(qint_from_int((int)(actual >> 20)));
}
--
1.6.5.2.155.gbb47
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va()
2009-11-12 20:42 ` [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va() Luiz Capitulino
@ 2009-11-12 21:39 ` Anthony Liguori
2009-11-13 12:31 ` Luiz Capitulino
0 siblings, 1 reply; 13+ messages in thread
From: Anthony Liguori @ 2009-11-12 21:39 UTC (permalink / raw)
To: Luiz Capitulino; +Cc: armbru, aliguori, qemu-devel, kraxel
Luiz Capitulino wrote:
> Accepts a va_list, will be used by QError.
>
> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
> ---
> qjson.c | 14 ++++++++++++++
> qjson.h | 2 ++
> 2 files changed, 16 insertions(+), 0 deletions(-)
>
> diff --git a/qjson.c b/qjson.c
> index 7270909..491b61e 100644
> --- a/qjson.c
> +++ b/qjson.c
> @@ -64,6 +64,20 @@ QObject *qobject_from_jsonf(const char *string, ...)
> return state.result;
> }
>
> +QObject *qobject_from_json_va(const char *string, va_list *ap)
> +{
> + JSONParsingState state = {};
> +
> + state.ap = ap;
> +
> + json_message_parser_init(&state.parser, parse_json);
> + json_message_parser_feed(&state.parser, string, strlen(string));
> + json_message_parser_flush(&state.parser);
> + json_message_parser_destroy(&state.parser);
> +
> + return state.result;
> +}
> +
>
qobject_from_jsonf() should just call qobject_from_json_va().
> typedef struct ToJsonIterState
> {
> int count;
> diff --git a/qjson.h b/qjson.h
> index 7fce742..8b89e41 100644
> --- a/qjson.h
> +++ b/qjson.h
> @@ -14,12 +14,14 @@
> #ifndef QJSON_H
> #define QJSON_H
>
> +#include <stdarg.h>
>
qemu-common.h is a better way to get stdarg.h
> #include "qobject.h"
> #include "qstring.h"
>
> QObject *qobject_from_json(const char *string);
> QObject *qobject_from_jsonf(const char *string, ...)
> __attribute__((__format__ (__printf__, 1, 2)));
> +QObject *qobject_from_json_va(const char *string, va_list *ap);
>
> QString *qobject_to_json(const QObject *obj);
>
>
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va()
2009-11-12 21:39 ` Anthony Liguori
@ 2009-11-13 12:31 ` Luiz Capitulino
0 siblings, 0 replies; 13+ messages in thread
From: Luiz Capitulino @ 2009-11-13 12:31 UTC (permalink / raw)
To: Anthony Liguori; +Cc: armbru, aliguori, qemu-devel, kraxel
On Thu, 12 Nov 2009 15:39:14 -0600
Anthony Liguori <anthony@codemonkey.ws> wrote:
> Luiz Capitulino wrote:
> > Accepts a va_list, will be used by QError.
> >
> > Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
> > ---
> > qjson.c | 14 ++++++++++++++
> > qjson.h | 2 ++
> > 2 files changed, 16 insertions(+), 0 deletions(-)
> >
> > diff --git a/qjson.c b/qjson.c
> > index 7270909..491b61e 100644
> > --- a/qjson.c
> > +++ b/qjson.c
> > @@ -64,6 +64,20 @@ QObject *qobject_from_jsonf(const char *string, ...)
> > return state.result;
> > }
> >
> > +QObject *qobject_from_json_va(const char *string, va_list *ap)
> > +{
> > + JSONParsingState state = {};
> > +
> > + state.ap = ap;
> > +
> > + json_message_parser_init(&state.parser, parse_json);
> > + json_message_parser_feed(&state.parser, string, strlen(string));
> > + json_message_parser_flush(&state.parser);
> > + json_message_parser_destroy(&state.parser);
> > +
> > + return state.result;
> > +}
> > +
> >
>
> qobject_from_jsonf() should just call qobject_from_json_va().
Right.
> > typedef struct ToJsonIterState
> > {
> > int count;
> > diff --git a/qjson.h b/qjson.h
> > index 7fce742..8b89e41 100644
> > --- a/qjson.h
> > +++ b/qjson.h
> > @@ -14,12 +14,14 @@
> > #ifndef QJSON_H
> > #define QJSON_H
> >
> > +#include <stdarg.h>
> >
>
> qemu-common.h is a better way to get stdarg.h
Why? I usually don't include qemu-common.h when all I need
are one or two headers.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-11-13 12:31 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-12 20:42 [Qemu-devel] [PATCH 0/9]: QError v3 Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 1/9] QJSON: Introduce qobject_from_json_va() Luiz Capitulino
2009-11-12 21:39 ` Anthony Liguori
2009-11-13 12:31 ` Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 2/9] QString: Introduce qstring_append_chr() Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 3/9] QString: Introduce qstring_append_int() Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 4/9] Add qstring_append_chr() unit-test Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 5/9] Introduce QError Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 6/9] QJSON: Fix compile error Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 7/9] monitor: QError support Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 8/9] qdev: Use QError for 'device not found' error Luiz Capitulino
2009-11-12 20:42 ` [Qemu-devel] [PATCH 9/9] monitor: do_info_balloon(): use QError Luiz Capitulino
-- strict thread matches above, loose matches on Subject: below --
2009-10-13 16:56 [Qemu-devel] [PATCH v0 0/9] QError Luiz Capitulino
2009-10-13 16:57 ` [Qemu-devel] [PATCH 9/9] monitor: do_info_balloon(): use QError Luiz Capitulino
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).