1baacf047SPaolo Bonzini /* 2baacf047SPaolo Bonzini * QEMU Error Objects 3baacf047SPaolo Bonzini * 4baacf047SPaolo Bonzini * Copyright IBM, Corp. 2011 5a29a37b9SMarkus Armbruster * Copyright (C) 2011-2015 Red Hat, Inc. 6baacf047SPaolo Bonzini * 7baacf047SPaolo Bonzini * Authors: 8baacf047SPaolo Bonzini * Anthony Liguori <aliguori@us.ibm.com> 9a29a37b9SMarkus Armbruster * Markus Armbruster <armbru@redhat.com>, 10baacf047SPaolo Bonzini * 11baacf047SPaolo Bonzini * This work is licensed under the terms of the GNU LGPL, version 2. See 12baacf047SPaolo Bonzini * the COPYING.LIB file in the top-level directory. 13baacf047SPaolo Bonzini */ 14baacf047SPaolo Bonzini 15aafd7584SPeter Maydell #include "qemu/osdep.h" 16*da34e65cSMarkus Armbruster #include "qapi/error.h" 17baacf047SPaolo Bonzini #include "qemu-common.h" 18073a3411SCole Robinson #include "qemu/error-report.h" 19baacf047SPaolo Bonzini 20baacf047SPaolo Bonzini struct Error 21baacf047SPaolo Bonzini { 22baacf047SPaolo Bonzini char *msg; 23baacf047SPaolo Bonzini ErrorClass err_class; 241e9b65bbSMarkus Armbruster const char *src, *func; 251e9b65bbSMarkus Armbruster int line; 2650b7b000SEric Blake GString *hint; 27baacf047SPaolo Bonzini }; 28baacf047SPaolo Bonzini 295d24ee70SPeter Crosthwaite Error *error_abort; 30a29a37b9SMarkus Armbruster Error *error_fatal; 315d24ee70SPeter Crosthwaite 32a29a37b9SMarkus Armbruster static void error_handle_fatal(Error **errp, Error *err) 331e9b65bbSMarkus Armbruster { 34a29a37b9SMarkus Armbruster if (errp == &error_abort) { 351e9b65bbSMarkus Armbruster fprintf(stderr, "Unexpected error in %s() at %s:%d:\n", 361e9b65bbSMarkus Armbruster err->func, err->src, err->line); 371e9b65bbSMarkus Armbruster error_report_err(err); 381e9b65bbSMarkus Armbruster abort(); 391e9b65bbSMarkus Armbruster } 40a29a37b9SMarkus Armbruster if (errp == &error_fatal) { 41a29a37b9SMarkus Armbruster error_report_err(err); 42a29a37b9SMarkus Armbruster exit(1); 43a29a37b9SMarkus Armbruster } 44a29a37b9SMarkus Armbruster } 451e9b65bbSMarkus Armbruster 461e9b65bbSMarkus Armbruster static void error_setv(Error **errp, 471e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 4820e2dec1SDaniel P. Berrange ErrorClass err_class, const char *fmt, va_list ap, 4920e2dec1SDaniel P. Berrange const char *suffix) 50baacf047SPaolo Bonzini { 51baacf047SPaolo Bonzini Error *err; 52b276d249SMax Reitz int saved_errno = errno; 53baacf047SPaolo Bonzini 54baacf047SPaolo Bonzini if (errp == NULL) { 55baacf047SPaolo Bonzini return; 56baacf047SPaolo Bonzini } 57baacf047SPaolo Bonzini assert(*errp == NULL); 58baacf047SPaolo Bonzini 59baacf047SPaolo Bonzini err = g_malloc0(sizeof(*err)); 60baacf047SPaolo Bonzini err->msg = g_strdup_vprintf(fmt, ap); 6120e2dec1SDaniel P. Berrange if (suffix) { 6220e2dec1SDaniel P. Berrange char *msg = err->msg; 6320e2dec1SDaniel P. Berrange err->msg = g_strdup_printf("%s: %s", msg, suffix); 6420e2dec1SDaniel P. Berrange g_free(msg); 6520e2dec1SDaniel P. Berrange } 66baacf047SPaolo Bonzini err->err_class = err_class; 671e9b65bbSMarkus Armbruster err->src = src; 681e9b65bbSMarkus Armbruster err->line = line; 691e9b65bbSMarkus Armbruster err->func = func; 70baacf047SPaolo Bonzini 71a29a37b9SMarkus Armbruster error_handle_fatal(errp, err); 72baacf047SPaolo Bonzini *errp = err; 73b276d249SMax Reitz 74b276d249SMax Reitz errno = saved_errno; 75baacf047SPaolo Bonzini } 76baacf047SPaolo Bonzini 771e9b65bbSMarkus Armbruster void error_set_internal(Error **errp, 781e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 791e9b65bbSMarkus Armbruster ErrorClass err_class, const char *fmt, ...) 8055237508SMarkus Armbruster { 8155237508SMarkus Armbruster va_list ap; 8255237508SMarkus Armbruster 8355237508SMarkus Armbruster va_start(ap, fmt); 8420e2dec1SDaniel P. Berrange error_setv(errp, src, line, func, err_class, fmt, ap, NULL); 8555237508SMarkus Armbruster va_end(ap); 8655237508SMarkus Armbruster } 8755237508SMarkus Armbruster 881e9b65bbSMarkus Armbruster void error_setg_internal(Error **errp, 891e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 901e9b65bbSMarkus Armbruster const char *fmt, ...) 91a9499dddSMarkus Armbruster { 92a9499dddSMarkus Armbruster va_list ap; 93a9499dddSMarkus Armbruster 94a9499dddSMarkus Armbruster va_start(ap, fmt); 9520e2dec1SDaniel P. Berrange error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap, NULL); 96a9499dddSMarkus Armbruster va_end(ap); 97a9499dddSMarkus Armbruster } 98a9499dddSMarkus Armbruster 991e9b65bbSMarkus Armbruster void error_setg_errno_internal(Error **errp, 1001e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 1011e9b65bbSMarkus Armbruster int os_errno, const char *fmt, ...) 102baacf047SPaolo Bonzini { 103baacf047SPaolo Bonzini va_list ap; 104b276d249SMax Reitz int saved_errno = errno; 105baacf047SPaolo Bonzini 106baacf047SPaolo Bonzini if (errp == NULL) { 107baacf047SPaolo Bonzini return; 108baacf047SPaolo Bonzini } 109baacf047SPaolo Bonzini 110baacf047SPaolo Bonzini va_start(ap, fmt); 11120e2dec1SDaniel P. Berrange error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap, 11220e2dec1SDaniel P. Berrange os_errno != 0 ? strerror(os_errno) : NULL); 113baacf047SPaolo Bonzini va_end(ap); 114baacf047SPaolo Bonzini 115b276d249SMax Reitz errno = saved_errno; 116baacf047SPaolo Bonzini } 117baacf047SPaolo Bonzini 1181e9b65bbSMarkus Armbruster void error_setg_file_open_internal(Error **errp, 1191e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 1201e9b65bbSMarkus Armbruster int os_errno, const char *filename) 12154028d75SLuiz Capitulino { 1221e9b65bbSMarkus Armbruster error_setg_errno_internal(errp, src, line, func, os_errno, 1231e9b65bbSMarkus Armbruster "Could not open '%s'", filename); 12454028d75SLuiz Capitulino } 12554028d75SLuiz Capitulino 1268277d2aaSMarkus Armbruster void error_vprepend(Error **errp, const char *fmt, va_list ap) 1278277d2aaSMarkus Armbruster { 1288277d2aaSMarkus Armbruster GString *newmsg; 1298277d2aaSMarkus Armbruster 1308277d2aaSMarkus Armbruster if (!errp) { 1318277d2aaSMarkus Armbruster return; 1328277d2aaSMarkus Armbruster } 1338277d2aaSMarkus Armbruster 1348277d2aaSMarkus Armbruster newmsg = g_string_new(NULL); 1358277d2aaSMarkus Armbruster g_string_vprintf(newmsg, fmt, ap); 1368277d2aaSMarkus Armbruster g_string_append(newmsg, (*errp)->msg); 1378277d2aaSMarkus Armbruster (*errp)->msg = g_string_free(newmsg, 0); 1388277d2aaSMarkus Armbruster } 1398277d2aaSMarkus Armbruster 1408277d2aaSMarkus Armbruster void error_prepend(Error **errp, const char *fmt, ...) 1418277d2aaSMarkus Armbruster { 1428277d2aaSMarkus Armbruster va_list ap; 1438277d2aaSMarkus Armbruster 1448277d2aaSMarkus Armbruster va_start(ap, fmt); 1458277d2aaSMarkus Armbruster error_vprepend(errp, fmt, ap); 1468277d2aaSMarkus Armbruster va_end(ap); 1478277d2aaSMarkus Armbruster } 1488277d2aaSMarkus Armbruster 14950b7b000SEric Blake void error_append_hint(Error **errp, const char *fmt, ...) 15050b7b000SEric Blake { 15150b7b000SEric Blake va_list ap; 15250b7b000SEric Blake int saved_errno = errno; 15350b7b000SEric Blake Error *err; 15450b7b000SEric Blake 15550b7b000SEric Blake if (!errp) { 15650b7b000SEric Blake return; 15750b7b000SEric Blake } 15850b7b000SEric Blake err = *errp; 159f4d0064aSMarkus Armbruster assert(err && errp != &error_abort && errp != &error_fatal); 16050b7b000SEric Blake 16150b7b000SEric Blake if (!err->hint) { 16250b7b000SEric Blake err->hint = g_string_new(NULL); 16350b7b000SEric Blake } 16450b7b000SEric Blake va_start(ap, fmt); 16550b7b000SEric Blake g_string_append_vprintf(err->hint, fmt, ap); 16650b7b000SEric Blake va_end(ap); 16750b7b000SEric Blake 16850b7b000SEric Blake errno = saved_errno; 16950b7b000SEric Blake } 17050b7b000SEric Blake 17120840d4cSTomoki Sekiyama #ifdef _WIN32 17220840d4cSTomoki Sekiyama 1731e9b65bbSMarkus Armbruster void error_setg_win32_internal(Error **errp, 1741e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 1751e9b65bbSMarkus Armbruster int win32_err, const char *fmt, ...) 17620840d4cSTomoki Sekiyama { 17720840d4cSTomoki Sekiyama va_list ap; 17820e2dec1SDaniel P. Berrange char *suffix = NULL; 17920840d4cSTomoki Sekiyama 18020840d4cSTomoki Sekiyama if (errp == NULL) { 18120840d4cSTomoki Sekiyama return; 18220840d4cSTomoki Sekiyama } 18320840d4cSTomoki Sekiyama 18420e2dec1SDaniel P. Berrange if (win32_err != 0) { 18520e2dec1SDaniel P. Berrange suffix = g_win32_error_message(win32_err); 18620e2dec1SDaniel P. Berrange } 18720e2dec1SDaniel P. Berrange 18820840d4cSTomoki Sekiyama va_start(ap, fmt); 18920e2dec1SDaniel P. Berrange error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, 19020e2dec1SDaniel P. Berrange fmt, ap, suffix); 19155237508SMarkus Armbruster va_end(ap); 19255237508SMarkus Armbruster 19320e2dec1SDaniel P. Berrange g_free(suffix); 19420840d4cSTomoki Sekiyama } 19520840d4cSTomoki Sekiyama 19620840d4cSTomoki Sekiyama #endif 19720840d4cSTomoki Sekiyama 198baacf047SPaolo Bonzini Error *error_copy(const Error *err) 199baacf047SPaolo Bonzini { 200baacf047SPaolo Bonzini Error *err_new; 201baacf047SPaolo Bonzini 202baacf047SPaolo Bonzini err_new = g_malloc0(sizeof(*err)); 203baacf047SPaolo Bonzini err_new->msg = g_strdup(err->msg); 204baacf047SPaolo Bonzini err_new->err_class = err->err_class; 20588e2ce29SEric Blake err_new->src = err->src; 20688e2ce29SEric Blake err_new->line = err->line; 20788e2ce29SEric Blake err_new->func = err->func; 20850b7b000SEric Blake if (err->hint) { 20950b7b000SEric Blake err_new->hint = g_string_new(err->hint->str); 21050b7b000SEric Blake } 211baacf047SPaolo Bonzini 212baacf047SPaolo Bonzini return err_new; 213baacf047SPaolo Bonzini } 214baacf047SPaolo Bonzini 215baacf047SPaolo Bonzini ErrorClass error_get_class(const Error *err) 216baacf047SPaolo Bonzini { 217baacf047SPaolo Bonzini return err->err_class; 218baacf047SPaolo Bonzini } 219baacf047SPaolo Bonzini 220baacf047SPaolo Bonzini const char *error_get_pretty(Error *err) 221baacf047SPaolo Bonzini { 222baacf047SPaolo Bonzini return err->msg; 223baacf047SPaolo Bonzini } 224baacf047SPaolo Bonzini 2252ee2f1e4SMarkus Armbruster void error_report_err(Error *err) 2262ee2f1e4SMarkus Armbruster { 2272ee2f1e4SMarkus Armbruster error_report("%s", error_get_pretty(err)); 22850b7b000SEric Blake if (err->hint) { 229543202c0SMarkus Armbruster error_printf_unless_qmp("%s", err->hint->str); 23050b7b000SEric Blake } 2312ee2f1e4SMarkus Armbruster error_free(err); 2322ee2f1e4SMarkus Armbruster } 2332ee2f1e4SMarkus Armbruster 2348277d2aaSMarkus Armbruster void error_reportf_err(Error *err, const char *fmt, ...) 2358277d2aaSMarkus Armbruster { 2368277d2aaSMarkus Armbruster va_list ap; 2378277d2aaSMarkus Armbruster 2388277d2aaSMarkus Armbruster va_start(ap, fmt); 2398277d2aaSMarkus Armbruster error_vprepend(&err, fmt, ap); 2408277d2aaSMarkus Armbruster va_end(ap); 2418277d2aaSMarkus Armbruster error_report_err(err); 2428277d2aaSMarkus Armbruster } 2438277d2aaSMarkus Armbruster 244baacf047SPaolo Bonzini void error_free(Error *err) 245baacf047SPaolo Bonzini { 246baacf047SPaolo Bonzini if (err) { 247baacf047SPaolo Bonzini g_free(err->msg); 24850b7b000SEric Blake if (err->hint) { 24950b7b000SEric Blake g_string_free(err->hint, true); 25050b7b000SEric Blake } 251baacf047SPaolo Bonzini g_free(err); 252baacf047SPaolo Bonzini } 253baacf047SPaolo Bonzini } 254baacf047SPaolo Bonzini 255a12a5a1aSEric Blake void error_free_or_abort(Error **errp) 256a12a5a1aSEric Blake { 257a12a5a1aSEric Blake assert(errp && *errp); 258a12a5a1aSEric Blake error_free(*errp); 259a12a5a1aSEric Blake *errp = NULL; 260a12a5a1aSEric Blake } 261a12a5a1aSEric Blake 26264dfefedSMarkus Armbruster void error_propagate(Error **dst_errp, Error *local_err) 263baacf047SPaolo Bonzini { 264a29a37b9SMarkus Armbruster if (!local_err) { 265a29a37b9SMarkus Armbruster return; 266a29a37b9SMarkus Armbruster } 267a29a37b9SMarkus Armbruster error_handle_fatal(dst_errp, local_err); 268a29a37b9SMarkus Armbruster if (dst_errp && !*dst_errp) { 26964dfefedSMarkus Armbruster *dst_errp = local_err; 270a29a37b9SMarkus Armbruster } else { 271baacf047SPaolo Bonzini error_free(local_err); 272baacf047SPaolo Bonzini } 273baacf047SPaolo Bonzini } 274