If error reporting is disabled, RaiseFullError will log the passed message, but it will not wipe out the previous error and won't trigger the error callback. Signed-off-by: Cole Robinson <crobinso@xxxxxxxxxx> --- src/util/virterror.c | 82 ++++++++++++++++++++++++++++++++++------- src/util/virterror_internal.h | 2 + 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/util/virterror.c b/src/util/virterror.c index 7b7543b..58b3086 100644 --- a/src/util/virterror.c +++ b/src/util/virterror.c @@ -26,6 +26,7 @@ virThreadLocal virThreadErrorStateIdx; typedef struct virThreadErrorState { virErrorPtr lastError; + unsigned int enableErrors; } virThreadErrorState; typedef virThreadErrorState *virThreadErrorStatePtr; @@ -274,6 +275,8 @@ virThreadErrorStateObject(void) return NULL; if (VIR_ALLOC(state->lastError) < 0) return NULL; + + state->enableErrors = 1; virThreadLocalSet(&virThreadErrorStateIdx, state); } return state; @@ -289,6 +292,49 @@ virLastErrorObject(void) return state->lastError; } +static unsigned int +virGetEnableErrors(void) +{ + virThreadErrorStatePtr state = virThreadErrorStateObject(); + if (!state) + return 1; + + return state->enableErrors; +} + +static void +virSetEnableErrors(unsigned int val) +{ + virThreadErrorStatePtr state = virThreadErrorStateObject(); + if (!state) + return; + + state->enableErrors = val ? 1 : 0; +} + +/* + * Enable error reporting and error callback launching (on by default) + */ +void +virEnableErrors(void) +{ + virSetEnableErrors(1); +} + +/* + * Disable error reporting and error callback launching. Calls to + * ReportFullError will log the message, but the previous error will remain + * intact. + * + * This is useful when we want to ensure that some clean up path will + * not stomp all over the original error report. + */ +void +virDisableErrors(void) +{ + virSetEnableErrors(0); +} + /** * virGetLastError: * @@ -669,21 +715,10 @@ virRaiseErrorFull(virConnectPtr conn, if (!to) return; /* Hit OOM allocating thread error object, sod all we can do now */ - virResetError(to); - - if (code == VIR_ERR_OK) + /* If code is OK, clear the previous error and return. */ + if (code == VIR_ERR_OK) { + virResetError(to); return; - - /* - * try to find the best place to save and report the error - */ - if (conn != NULL) { - virMutexLock(&conn->lock); - if (conn->handler != NULL) { - handler = conn->handler; - userData = conn->userData; - } - virMutexUnlock(&conn->lock); } /* @@ -702,6 +737,25 @@ virRaiseErrorFull(virConnectPtr conn, virLogMessage(virErrorDomainName(domain), virErrorLevelPriority(level), funcname, linenr, 1, "%s", str); + /* Error reporting has been deliberately disabled, don't wipe out the + * previous error, just log what was passed and return. */ + if (!virGetEnableErrors()) { + VIR_FREE(str); + return; + } + + /* + * try to find the best place to save and report the error + */ + if (conn != NULL) { + virMutexLock(&conn->lock); + if (conn->handler != NULL) { + handler = conn->handler; + userData = conn->userData; + } + virMutexUnlock(&conn->lock); + } + /* * Save the information about the error */ diff --git a/src/util/virterror_internal.h b/src/util/virterror_internal.h index da89de7..2f0e327 100644 --- a/src/util/virterror_internal.h +++ b/src/util/virterror_internal.h @@ -89,6 +89,8 @@ void virReportOOMErrorFull(virConnectPtr conn, virReportOOMErrorFull((conn), VIR_FROM_THIS, \ __FILE__, __FUNCTION__, __LINE__) +void virEnableErrors(void); +void virDisableErrors(void); void virSetGlobalError(void); void virSetConnError(virConnectPtr conn); -- 1.6.5.1 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list