/** * virDispatchError: * @conn: pointer to the hypervisor connection * * Internal helper to do final stage of error * reporting in public APIs. * * - Copy the global error to per-connection error if needed * - Set a generic error message if none is already set * - Invoke the error callback functions */ void virDispatchError(virConnectPtr conn) { virErrorPtr err = virLastErrorObject(); virErrorFunc handler = virErrorHandler; void *userData = virUserData; /* Can only happen on OOM. */ if (!err) return; /* Set a generic error message if none is already set */ if (err->code == VIR_ERR_OK) virErrorGenericFailure(err); /* Copy the global error to per-connection error if needed */ if (conn) { virMutexLock(&conn->lock); virCopyError(err, &conn->err); if (conn->handler != NULL) { handler = conn->handler; userData = conn->userData; } virMutexUnlock(&conn->lock); } /* Invoke the error callback functions */ if (handler != NULL) { (handler)(userData, err); } else { virDefaultErrorFunc(err); } }
/** * virCopyLastError: * @to: target to receive the copy * * Copy the content of the last error caught at the library level * * The error object is kept in thread local storage, so separate * threads can safely access this concurrently. * * One will need to free the result with virResetError() * * Returns 0 if no error was found and the error code otherwise and -1 in case * of parameter error. */ int virCopyLastError(virErrorPtr to) { virErrorPtr err = virLastErrorObject(); /* We can't guarantee caller has initialized it to zero */ memset(to, 0, sizeof(*to)); if (err) virCopyError(err, to); else virResetError(to); return to->code; }
virErrorPtr virErrorCopyNew(virErrorPtr err) { virErrorPtr ret; if (VIR_ALLOC_QUIET(ret) < 0) return NULL; if (virCopyError(err, ret) < 0) VIR_FREE(ret); return ret; }
/** * virConnCopyLastError: * @conn: pointer to the hypervisor connection * @to: target to receive the copy * * Copy the content of the last error caught on that connection * * This method is not protected against access from multiple * threads. In a multi-threaded application, always use the * global virGetLastError() API which is backed by thread * local storage. * * If the connection object was discovered to be invalid by * an API call, then the error will be reported against the * global error object. * * Since 0.6.0, all errors reported in the per-connection object * are also duplicated in the global error object. As such an * application can always use virGetLastError(). This method * remains for backwards compatibility. * * One will need to free the result with virResetError() * * Returns 0 if no error was found and the error code otherwise and -1 in case * of parameter error. */ int virConnCopyLastError(virConnectPtr conn, virErrorPtr to) { /* We can't guarantee caller has initialized it to zero */ memset(to, 0, sizeof(*to)); if (conn == NULL) return -1; virMutexLock(&conn->lock); if (conn->err.code == VIR_ERR_OK) virResetError(to); else virCopyError(&conn->err, to); virMutexUnlock(&conn->lock); return to->code; }
/** * virSetError: * @newerr: previously saved error object * * Set the current error from a previously saved error object * * Can be used to re-set an old error, which may have been squashed by * other functions (like cleanup routines). * * Returns 0 on success, -1 on failure. Leaves errno unchanged. */ int virSetError(virErrorPtr newerr) { virErrorPtr err; int saved_errno = errno; int ret = -1; err = virLastErrorObject(); if (!err) goto cleanup; virResetError(err); ret = virCopyError(newerr, err); cleanup: errno = saved_errno; return ret; }
/** * virCopyLastError: * @to: target to receive the copy * * Copy the content of the last error caught at the library level * * The error object is kept in thread local storage, so separate * threads can safely access this concurrently. * * One will need to free the result with virResetError() * * Returns error code or -1 in case of parameter error. */ int virCopyLastError(virErrorPtr to) { virErrorPtr err = virLastErrorObject(); if (!to) return -1; /* We can't guarantee caller has initialized it to zero */ memset(to, 0, sizeof(*to)); if (err) { virCopyError(err, to); } else { virResetError(to); to->code = VIR_ERR_NO_MEMORY; to->domain = VIR_FROM_NONE; to->level = VIR_ERR_ERROR; } return to->code; }