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(a)redhat.com>
---
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