blob: 08185047b4bed6b24dde0034b0bae37bb1aae508 [file] [log] [blame]
Luiz Capitulino9f9daf92009-11-18 23:05:30 -02001/*
Luiz Capitulino41836a92010-05-12 16:34:42 -03002 * QError Module
Luiz Capitulino9f9daf92009-11-18 23:05:30 -02003 *
4 * Copyright (C) 2009 Red Hat Inc.
5 *
6 * Authors:
7 * Luiz Capitulino <lcapitulino@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10 * See the COPYING.LIB file in the top-level directory.
11 */
Markus Armbruster0167f772010-03-22 10:29:05 +010012
13#include "monitor.h"
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020014#include "qjson.h"
15#include "qerror.h"
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020016#include "qemu-common.h"
17
18static void qerror_destroy_obj(QObject *obj);
19
20static const QType qerror_type = {
21 .code = QTYPE_QERROR,
22 .destroy = qerror_destroy_obj,
23};
24
25/**
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020026 * qerror_new(): Create a new QError
27 *
28 * Return strong reference.
29 */
Luiz Capitulino2a744402012-07-19 17:29:34 -030030static QError *qerror_new(void)
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020031{
32 QError *qerr;
33
Anthony Liguori7267c092011-08-20 22:09:37 -050034 qerr = g_malloc0(sizeof(*qerr));
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020035 QOBJECT_INIT(qerr, &qerror_type);
36
37 return qerr;
38}
39
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020040/**
41 * qerror_from_info(): Create a new QError from error information
42 *
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020043 * Return strong reference.
44 */
Luiz Capitulino13f59ae2012-07-27 14:09:29 -030045static QError *qerror_from_info(ErrorClass err_class, const char *fmt,
46 va_list *va)
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020047{
48 QError *qerr;
49
50 qerr = qerror_new();
Markus Armbruster827b0812010-02-18 19:46:49 +010051 loc_save(&qerr->loc);
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020052
Luiz Capitulinodf1e6082012-07-27 17:51:03 -030053 qerr->err_msg = g_strdup_vprintf(fmt, *va);
Luiz Capitulino13f59ae2012-07-27 14:09:29 -030054 qerr->err_class = err_class;
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020055
56 return qerr;
57}
58
Markus Armbruster77e595e2009-12-07 21:37:16 +010059/**
Luiz Capitulinoa12eeaa2011-06-01 12:14:47 -050060 * qerror_human(): Format QError data into human-readable string.
61 */
62QString *qerror_human(const QError *qerror)
63{
Luiz Capitulino18da7c02012-07-20 12:02:58 -030064 return qstring_from_str(qerror->err_msg);
Luiz Capitulinoa12eeaa2011-06-01 12:14:47 -050065}
66
67/**
Markus Armbruster77e595e2009-12-07 21:37:16 +010068 * qerror_print(): Print QError data
69 *
70 * This function will print the member 'desc' of the specified QError object,
Markus Armbruster1ecda022010-02-18 17:25:24 +010071 * it uses error_report() for this, so that the output is routed to the right
Markus Armbruster77e595e2009-12-07 21:37:16 +010072 * place (ie. stderr or Monitor's device).
73 */
Luiz Capitulino2a744402012-07-19 17:29:34 -030074static void qerror_print(QError *qerror)
Markus Armbruster77e595e2009-12-07 21:37:16 +010075{
76 QString *qstring = qerror_human(qerror);
Markus Armbruster827b0812010-02-18 19:46:49 +010077 loc_push_restore(&qerror->loc);
Markus Armbruster1ecda022010-02-18 17:25:24 +010078 error_report("%s", qstring_get_str(qstring));
Markus Armbruster827b0812010-02-18 19:46:49 +010079 loc_pop(&qerror->loc);
Luiz Capitulino9f9daf92009-11-18 23:05:30 -020080 QDECREF(qstring);
81}
82
Luiz Capitulino13f59ae2012-07-27 14:09:29 -030083void qerror_report(ErrorClass eclass, const char *fmt, ...)
Markus Armbruster0167f772010-03-22 10:29:05 +010084{
85 va_list va;
86 QError *qerror;
87
88 va_start(va, fmt);
Luiz Capitulino13f59ae2012-07-27 14:09:29 -030089 qerror = qerror_from_info(eclass, fmt, &va);
Markus Armbruster0167f772010-03-22 10:29:05 +010090 va_end(va);
91
92 if (monitor_cur_is_qmp()) {
93 monitor_set_error(cur_mon, qerror);
94 } else {
95 qerror_print(qerror);
96 QDECREF(qerror);
97 }
98}
99
Anthony Liguori2a82d932011-09-02 12:34:45 -0500100/* Evil... */
101struct Error
102{
Anthony Liguori2a82d932011-09-02 12:34:45 -0500103 char *msg;
Luiz Capitulino13f59ae2012-07-27 14:09:29 -0300104 ErrorClass err_class;
Anthony Liguori2a82d932011-09-02 12:34:45 -0500105};
106
107void qerror_report_err(Error *err)
108{
109 QError *qerr;
Anthony Liguori2a82d932011-09-02 12:34:45 -0500110
111 qerr = qerror_new();
112 loc_save(&qerr->loc);
Luiz Capitulinodd7520f2012-07-20 13:43:37 -0300113 qerr->err_msg = g_strdup(err->msg);
Luiz Capitulino13f59ae2012-07-27 14:09:29 -0300114 qerr->err_class = err->err_class;
Anthony Liguori2a82d932011-09-02 12:34:45 -0500115
116 if (monitor_cur_is_qmp()) {
117 monitor_set_error(cur_mon, qerr);
118 } else {
119 qerror_print(qerr);
120 QDECREF(qerr);
121 }
122}
123
Paolo Bonzini59f971d2012-02-14 10:19:53 +0100124void assert_no_error(Error *err)
125{
126 if (err) {
127 qerror_report_err(err);
128 abort();
129 }
130}
131
Luiz Capitulino9f9daf92009-11-18 23:05:30 -0200132/**
133 * qobject_to_qerror(): Convert a QObject into a QError
134 */
Luiz Capitulino2a744402012-07-19 17:29:34 -0300135static QError *qobject_to_qerror(const QObject *obj)
Luiz Capitulino9f9daf92009-11-18 23:05:30 -0200136{
137 if (qobject_type(obj) != QTYPE_QERROR) {
138 return NULL;
139 }
140
141 return container_of(obj, QError, base);
142}
143
144/**
145 * qerror_destroy_obj(): Free all memory allocated by a QError
146 */
147static void qerror_destroy_obj(QObject *obj)
148{
149 QError *qerr;
150
151 assert(obj != NULL);
152 qerr = qobject_to_qerror(obj);
153
Luiz Capitulino18da7c02012-07-20 12:02:58 -0300154 g_free(qerr->err_msg);
Anthony Liguori7267c092011-08-20 22:09:37 -0500155 g_free(qerr);
Luiz Capitulino9f9daf92009-11-18 23:05:30 -0200156}