Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
ead04dcb
L
libvirt
项目概览
openeuler
/
libvirt
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
libvirt
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ead04dcb
编写于
1月 20, 2009
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Thread local error reporting
上级
c790f6d2
变更
6
展开全部
隐藏空白更改
内联
并排
Showing
6 changed file
with
1934 addition
and
508 deletion
+1934
-508
ChangeLog
ChangeLog
+17
-0
src/datatypes.c
src/datatypes.c
+10
-21
src/datatypes.h
src/datatypes.h
+10
-5
src/libvirt.c
src/libvirt.c
+1668
-448
src/virterror.c
src/virterror.c
+225
-33
src/virterror_internal.h
src/virterror_internal.h
+4
-1
未找到文件。
ChangeLog
浏览文件 @
ead04dcb
Tue Jan 20 12:01:53 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Thread local error handling
* src/datatypes.c: Don't reference global error object directly
now that it is thread-local. Avoid passing 'conn' arg to error
routines if we just determined that the pointer is invalid
* src/datatypes.h: Add note about rules for locking when using
virConnectPtr members
* src/libvirt.c: Initialize error handling routines at startup.
Adapt driver API methods to reset last error upon entry, and
copy the global thread local error to the per-connection error
upon exit
* src/virterror.c, src/virterror_internal.h: Store the global
error object in a thread local variable. Provide a API to copy
the global error into a per-connection error object. Add an
initialization routine to setup the thread local
Tue Jan 20 11:43:53 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Tue Jan 20 11:43:53 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
* src/remote_internal.c: Disable event watch when doing an
* src/remote_internal.c: Disable event watch when doing an
...
...
src/datatypes.c
浏览文件 @
ead04dcb
...
@@ -195,8 +195,6 @@ virReleaseConnect(virConnectPtr conn) {
...
@@ -195,8 +195,6 @@ virReleaseConnect(virConnectPtr conn) {
virHashFree
(
conn
->
nodeDevices
,
(
virHashDeallocator
)
virNodeDeviceFree
);
virHashFree
(
conn
->
nodeDevices
,
(
virHashDeallocator
)
virNodeDeviceFree
);
virResetError
(
&
conn
->
err
);
virResetError
(
&
conn
->
err
);
if
(
virLastErr
.
conn
==
conn
)
virLastErr
.
conn
=
NULL
;
xmlFreeURI
(
conn
->
uri
);
xmlFreeURI
(
conn
->
uri
);
...
@@ -219,7 +217,7 @@ virUnrefConnect(virConnectPtr conn) {
...
@@ -219,7 +217,7 @@ virUnrefConnect(virConnectPtr conn) {
int
refs
;
int
refs
;
if
((
!
VIR_IS_CONNECT
(
conn
)))
{
if
((
!
VIR_IS_CONNECT
(
conn
)))
{
virLibConnError
(
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
-
1
);
return
(
-
1
);
}
}
virMutexLock
(
&
conn
->
lock
);
virMutexLock
(
&
conn
->
lock
);
...
@@ -253,7 +251,7 @@ virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
...
@@ -253,7 +251,7 @@ virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
virDomainPtr
ret
=
NULL
;
virDomainPtr
ret
=
NULL
;
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
uuid
==
NULL
))
{
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
uuid
==
NULL
))
{
virLibConnError
(
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
NULL
);
return
(
NULL
);
}
}
virMutexLock
(
&
conn
->
lock
);
virMutexLock
(
&
conn
->
lock
);
...
@@ -323,10 +321,6 @@ virReleaseDomain(virDomainPtr domain) {
...
@@ -323,10 +321,6 @@ virReleaseDomain(virDomainPtr domain) {
virLibConnError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
virLibConnError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"domain missing from connection hash table"
));
_
(
"domain missing from connection hash table"
));
if
(
conn
->
err
.
dom
==
domain
)
conn
->
err
.
dom
=
NULL
;
if
(
virLastErr
.
dom
==
domain
)
virLastErr
.
dom
=
NULL
;
domain
->
magic
=
-
1
;
domain
->
magic
=
-
1
;
domain
->
id
=
-
1
;
domain
->
id
=
-
1
;
VIR_FREE
(
domain
->
name
);
VIR_FREE
(
domain
->
name
);
...
@@ -358,7 +352,7 @@ virUnrefDomain(virDomainPtr domain) {
...
@@ -358,7 +352,7 @@ virUnrefDomain(virDomainPtr domain) {
int
refs
;
int
refs
;
if
(
!
VIR_IS_CONNECTED_DOMAIN
(
domain
))
{
if
(
!
VIR_IS_CONNECTED_DOMAIN
(
domain
))
{
virLibConnError
(
domain
->
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
-
1
);
return
(
-
1
);
}
}
virMutexLock
(
&
domain
->
conn
->
lock
);
virMutexLock
(
&
domain
->
conn
->
lock
);
...
@@ -393,7 +387,7 @@ virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
...
@@ -393,7 +387,7 @@ virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
virNetworkPtr
ret
=
NULL
;
virNetworkPtr
ret
=
NULL
;
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
uuid
==
NULL
))
{
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
uuid
==
NULL
))
{
virLibConnError
(
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
NULL
);
return
(
NULL
);
}
}
virMutexLock
(
&
conn
->
lock
);
virMutexLock
(
&
conn
->
lock
);
...
@@ -459,11 +453,6 @@ virReleaseNetwork(virNetworkPtr network) {
...
@@ -459,11 +453,6 @@ virReleaseNetwork(virNetworkPtr network) {
virLibConnError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
virLibConnError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"network missing from connection hash table"
));
_
(
"network missing from connection hash table"
));
if
(
conn
->
err
.
net
==
network
)
conn
->
err
.
net
=
NULL
;
if
(
virLastErr
.
net
==
network
)
virLastErr
.
net
=
NULL
;
network
->
magic
=
-
1
;
network
->
magic
=
-
1
;
VIR_FREE
(
network
->
name
);
VIR_FREE
(
network
->
name
);
VIR_FREE
(
network
);
VIR_FREE
(
network
);
...
@@ -494,7 +483,7 @@ virUnrefNetwork(virNetworkPtr network) {
...
@@ -494,7 +483,7 @@ virUnrefNetwork(virNetworkPtr network) {
int
refs
;
int
refs
;
if
(
!
VIR_IS_CONNECTED_NETWORK
(
network
))
{
if
(
!
VIR_IS_CONNECTED_NETWORK
(
network
))
{
virLibConnError
(
network
->
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
-
1
);
return
(
-
1
);
}
}
virMutexLock
(
&
network
->
conn
->
lock
);
virMutexLock
(
&
network
->
conn
->
lock
);
...
@@ -530,7 +519,7 @@ virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *uui
...
@@ -530,7 +519,7 @@ virGetStoragePool(virConnectPtr conn, const char *name, const unsigned char *uui
virStoragePoolPtr
ret
=
NULL
;
virStoragePoolPtr
ret
=
NULL
;
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
uuid
==
NULL
))
{
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
uuid
==
NULL
))
{
virLibConnError
(
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
NULL
);
return
(
NULL
);
}
}
virMutexLock
(
&
conn
->
lock
);
virMutexLock
(
&
conn
->
lock
);
...
@@ -627,7 +616,7 @@ virUnrefStoragePool(virStoragePoolPtr pool) {
...
@@ -627,7 +616,7 @@ virUnrefStoragePool(virStoragePoolPtr pool) {
int
refs
;
int
refs
;
if
(
!
VIR_IS_CONNECTED_STORAGE_POOL
(
pool
))
{
if
(
!
VIR_IS_CONNECTED_STORAGE_POOL
(
pool
))
{
virLibConnError
(
pool
->
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
-
1
);
return
(
-
1
);
}
}
virMutexLock
(
&
pool
->
conn
->
lock
);
virMutexLock
(
&
pool
->
conn
->
lock
);
...
@@ -664,7 +653,7 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const c
...
@@ -664,7 +653,7 @@ virGetStorageVol(virConnectPtr conn, const char *pool, const char *name, const c
virStorageVolPtr
ret
=
NULL
;
virStorageVolPtr
ret
=
NULL
;
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
key
==
NULL
))
{
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
)
||
(
key
==
NULL
))
{
virLibConnError
(
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
NULL
);
return
(
NULL
);
}
}
virMutexLock
(
&
conn
->
lock
);
virMutexLock
(
&
conn
->
lock
);
...
@@ -765,7 +754,7 @@ virUnrefStorageVol(virStorageVolPtr vol) {
...
@@ -765,7 +754,7 @@ virUnrefStorageVol(virStorageVolPtr vol) {
int
refs
;
int
refs
;
if
(
!
VIR_IS_CONNECTED_STORAGE_VOL
(
vol
))
{
if
(
!
VIR_IS_CONNECTED_STORAGE_VOL
(
vol
))
{
virLibConnError
(
vol
->
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
-
1
);
return
(
-
1
);
}
}
virMutexLock
(
&
vol
->
conn
->
lock
);
virMutexLock
(
&
vol
->
conn
->
lock
);
...
@@ -801,7 +790,7 @@ virGetNodeDevice(virConnectPtr conn, const char *name)
...
@@ -801,7 +790,7 @@ virGetNodeDevice(virConnectPtr conn, const char *name)
virNodeDevicePtr
ret
=
NULL
;
virNodeDevicePtr
ret
=
NULL
;
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
))
{
if
((
!
VIR_IS_CONNECT
(
conn
))
||
(
name
==
NULL
))
{
virLibConnError
(
conn
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
virLibConnError
(
NULL
,
VIR_ERR_INVALID_ARG
,
__FUNCTION__
);
return
(
NULL
);
return
(
NULL
);
}
}
virMutexLock
(
&
conn
->
lock
);
virMutexLock
(
&
conn
->
lock
);
...
...
src/datatypes.h
浏览文件 @
ead04dcb
...
@@ -95,6 +95,10 @@
...
@@ -95,6 +95,10 @@
* Internal structure associated to a connection
* Internal structure associated to a connection
*/
*/
struct
_virConnect
{
struct
_virConnect
{
/* All the variables from here, until the 'lock' declaration
* are setup at time of connection open, and never changed
* since. Thus no need to lock when accessing them
*/
unsigned
int
magic
;
/* specific value to check */
unsigned
int
magic
;
/* specific value to check */
int
flags
;
/* a set of connection flags */
int
flags
;
/* a set of connection flags */
xmlURIPtr
uri
;
/* connection URI */
xmlURIPtr
uri
;
/* connection URI */
...
@@ -114,11 +118,6 @@ struct _virConnect {
...
@@ -114,11 +118,6 @@ struct _virConnect {
void
*
storagePrivateData
;
void
*
storagePrivateData
;
void
*
devMonPrivateData
;
void
*
devMonPrivateData
;
/* Per-connection error. */
virError
err
;
/* the last error */
virErrorFunc
handler
;
/* associated handlet */
void
*
userData
;
/* the user data */
/*
/*
* The lock mutex must be acquired before accessing/changing
* The lock mutex must be acquired before accessing/changing
* any of members following this point, or changing the ref
* any of members following this point, or changing the ref
...
@@ -126,6 +125,12 @@ struct _virConnect {
...
@@ -126,6 +125,12 @@ struct _virConnect {
* this connection
* this connection
*/
*/
virMutex
lock
;
virMutex
lock
;
/* Per-connection error. */
virError
err
;
/* the last error */
virErrorFunc
handler
;
/* associated handlet */
void
*
userData
;
/* the user data */
virHashTablePtr
domains
;
/* hash table for known domains */
virHashTablePtr
domains
;
/* hash table for known domains */
virHashTablePtr
networks
;
/* hash table for known domains */
virHashTablePtr
networks
;
/* hash table for known domains */
virHashTablePtr
storagePools
;
/* hash table for known storage pools */
virHashTablePtr
storagePools
;
/* hash table for known storage pools */
...
...
src/libvirt.c
浏览文件 @
ead04dcb
此差异已折叠。
点击以展开。
src/virterror.c
浏览文件 @
ead04dcb
...
@@ -18,11 +18,11 @@
...
@@ -18,11 +18,11 @@
#include "virterror_internal.h"
#include "virterror_internal.h"
#include "datatypes.h"
#include "datatypes.h"
#include "logging.h"
#include "logging.h"
#include "memory.h"
#include "threads.h"
virThreadLocal
virLastErr
;
virError
virLastErr
=
/* the last error */
{
.
code
=
0
,
.
domain
=
0
,
.
message
=
NULL
,
.
level
=
VIR_ERR_NONE
,
.
conn
=
NULL
,
.
dom
=
NULL
,
.
str1
=
NULL
,
.
str2
=
NULL
,
.
str3
=
NULL
,
.
int1
=
0
,
.
int2
=
0
,
.
net
=
NULL
};
virErrorFunc
virErrorHandler
=
NULL
;
/* global error handler */
virErrorFunc
virErrorHandler
=
NULL
;
/* global error handler */
void
*
virUserData
=
NULL
;
/* associated data */
void
*
virUserData
=
NULL
;
/* associated data */
...
@@ -154,28 +154,118 @@ static const char *virErrorDomainName(virErrorDomain domain) {
...
@@ -154,28 +154,118 @@ static const char *virErrorDomainName(virErrorDomain domain) {
return
(
dom
);
return
(
dom
);
}
}
/*
* Internal helper that is called when a thread exits, to
* release the error object stored in the thread local
*/
static
void
virLastErrFreeData
(
void
*
data
)
{
virErrorPtr
err
=
data
;
if
(
!
err
)
return
;
virResetError
(
err
);
VIR_FREE
(
err
);
}
int
virErrorInitialize
(
void
)
{
return
virThreadLocalInit
(
&
virLastErr
,
virLastErrFreeData
);
}
/*
* Internal helper to ensure a generic error code is stored
* in case where API returns failure, but forgot to set an
* error
*/
static
void
virErrorGenericFailure
(
virErrorPtr
err
)
{
err
->
code
=
VIR_ERR_INTERNAL_ERROR
;
err
->
domain
=
VIR_FROM_NONE
;
err
->
level
=
VIR_ERR_ERROR
;
err
->
message
=
strdup
(
_
(
"Unknown failure"
));
}
/*
/*
* Internal helper to perform a deep copy of the an error
*/
static
int
virCopyError
(
virErrorPtr
from
,
virErrorPtr
to
)
{
int
ret
=
0
;
if
(
!
to
)
return
0
;
virResetError
(
to
);
if
(
!
from
)
return
0
;
to
->
code
=
from
->
code
;
to
->
domain
=
from
->
domain
;
to
->
level
=
from
->
level
;
if
(
from
->
message
&&
!
(
to
->
message
=
strdup
(
from
->
message
)))
ret
=
-
1
;
if
(
from
->
str1
&&
!
(
to
->
str1
=
strdup
(
from
->
str1
)))
ret
=
-
1
;
if
(
from
->
str2
&&
!
(
to
->
str2
=
strdup
(
from
->
str2
)))
ret
=
-
1
;
if
(
from
->
str3
&&
!
(
to
->
str3
=
strdup
(
from
->
str3
)))
ret
=
-
1
;
to
->
int1
=
from
->
int1
;
to
->
int2
=
from
->
int2
;
/*
* Delibrately not setting 'conn', 'dom', 'net' references
*/
return
ret
;
}
static
virErrorPtr
virLastErrorObject
(
void
)
{
virErrorPtr
err
;
err
=
virThreadLocalGet
(
&
virLastErr
);
if
(
!
err
)
{
if
(
VIR_ALLOC
(
err
)
<
0
)
return
NULL
;
virThreadLocalSet
(
&
virLastErr
,
err
);
}
return
err
;
}
/**
* virGetLastError:
* virGetLastError:
*
*
* Provide a pointer to the last error caught at the library level
* Provide a pointer to the last error caught at the library level
* Simpler but may not be suitable for multithreaded accesses, in which
*
* case use virCopyLastError()
* The error object is kept in thread local storage, so separate
* threads can safely access this concurrently.
*
*
* Returns a pointer to the last error or NULL if none occurred.
* Returns a pointer to the last error or NULL if none occurred.
*/
*/
virErrorPtr
virErrorPtr
virGetLastError
(
void
)
virGetLastError
(
void
)
{
{
if
(
virLastErr
.
code
==
VIR_ERR_OK
)
virErrorPtr
err
=
virLastErrorObject
();
return
(
NULL
);
if
(
!
err
||
err
->
code
==
VIR_ERR_OK
)
return
(
&
virLastErr
);
return
NULL
;
return
err
;
}
}
/*
/*
*
* virCopyLastError:
* virCopyLastError:
* @to: target to receive the copy
* @to: target to receive the copy
*
*
* Copy the content of the last error caught at the library level
* 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()
* 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
* Returns 0 if no error was found and the error code otherwise and -1 in case
...
@@ -184,12 +274,14 @@ virGetLastError(void)
...
@@ -184,12 +274,14 @@ virGetLastError(void)
int
int
virCopyLastError
(
virErrorPtr
to
)
virCopyLastError
(
virErrorPtr
to
)
{
{
if
(
to
==
NULL
)
virErrorPtr
err
=
virLastErrorObject
();
return
(
-
1
);
/* We can't guarentee caller has initialized it to zero */
if
(
virLastErr
.
code
==
VIR_ERR_OK
)
memset
(
to
,
0
,
sizeof
(
*
to
));
return
(
0
);
if
(
err
)
memcpy
(
to
,
&
virLastErr
,
sizeof
(
virError
));
virCopyError
(
err
,
to
);
return
(
virLastErr
.
code
);
else
virResetError
(
to
);
return
to
->
code
;
}
}
/**
/**
...
@@ -210,15 +302,22 @@ virResetError(virErrorPtr err)
...
@@ -210,15 +302,22 @@ virResetError(virErrorPtr err)
memset
(
err
,
0
,
sizeof
(
virError
));
memset
(
err
,
0
,
sizeof
(
virError
));
}
}
/**
/**
* virResetLastError:
* virResetLastError:
*
*
* Reset the last error caught at the library level.
* Reset 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, only resetting
* their own error object.
*/
*/
void
void
virResetLastError
(
void
)
virResetLastError
(
void
)
{
{
virResetError
(
&
virLastErr
);
virErrorPtr
err
=
virLastErrorObject
();
if
(
err
)
virResetError
(
err
);
}
}
/**
/**
...
@@ -226,8 +325,20 @@ virResetLastError(void)
...
@@ -226,8 +325,20 @@ virResetLastError(void)
* @conn: pointer to the hypervisor connection
* @conn: pointer to the hypervisor connection
*
*
* Provide a pointer to the last error caught on that connection
* Provide a pointer to the last error caught on that connection
* Simpler but may not be suitable for multithreaded accesses, in which
*
* case use virConnCopyLastError()
* 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 compatability.
*
*
* Returns a pointer to the last error or NULL if none occurred.
* Returns a pointer to the last error or NULL if none occurred.
*/
*/
...
@@ -235,8 +346,8 @@ virErrorPtr
...
@@ -235,8 +346,8 @@ virErrorPtr
virConnGetLastError
(
virConnectPtr
conn
)
virConnGetLastError
(
virConnectPtr
conn
)
{
{
if
(
conn
==
NULL
)
if
(
conn
==
NULL
)
return
(
NULL
)
;
return
NULL
;
return
(
&
conn
->
err
)
;
return
&
conn
->
err
;
}
}
/**
/**
...
@@ -245,6 +356,21 @@ virConnGetLastError(virConnectPtr conn)
...
@@ -245,6 +356,21 @@ virConnGetLastError(virConnectPtr conn)
* @to: target to receive the copy
* @to: target to receive the copy
*
*
* Copy the content of the last error caught on that connection
* 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 compatability.
*
* One will need to free the result with virResetError()
* 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
* Returns 0 if no error was found and the error code otherwise and -1 in case
...
@@ -253,20 +379,27 @@ virConnGetLastError(virConnectPtr conn)
...
@@ -253,20 +379,27 @@ virConnGetLastError(virConnectPtr conn)
int
int
virConnCopyLastError
(
virConnectPtr
conn
,
virErrorPtr
to
)
virConnCopyLastError
(
virConnectPtr
conn
,
virErrorPtr
to
)
{
{
/* We can't guarentee caller has initialized it to zero */
memset
(
to
,
0
,
sizeof
(
*
to
));
if
(
conn
==
NULL
)
if
(
conn
==
NULL
)
return
(
-
1
);
return
-
1
;
if
(
to
==
NULL
)
virMutexLock
(
&
conn
->
lock
);
return
(
-
1
);
if
(
conn
->
err
.
code
==
VIR_ERR_OK
)
if
(
conn
->
err
.
code
==
VIR_ERR_OK
)
return
(
0
);
virResetError
(
to
);
memcpy
(
to
,
&
conn
->
err
,
sizeof
(
virError
));
else
return
(
conn
->
err
.
code
);
virCopyError
(
&
conn
->
err
,
to
);
virMutexUnlock
(
&
conn
->
lock
);
return
to
->
code
;
}
}
/**
/**
* virConnResetLastError:
* virConnResetLastError:
* @conn: pointer to the hypervisor connection
* @conn: pointer to the hypervisor connection
*
*
* The error object is kept in thread local storage, so separate
* threads can safely access this concurrently.
*
* Reset the last error caught on that connection
* Reset the last error caught on that connection
*/
*/
void
void
...
@@ -274,7 +407,9 @@ virConnResetLastError(virConnectPtr conn)
...
@@ -274,7 +407,9 @@ virConnResetLastError(virConnectPtr conn)
{
{
if
(
conn
==
NULL
)
if
(
conn
==
NULL
)
return
;
return
;
virMutexLock
(
&
conn
->
lock
);
virResetError
(
&
conn
->
err
);
virResetError
(
&
conn
->
err
);
virMutexUnlock
(
&
conn
->
lock
);
}
}
/**
/**
...
@@ -309,8 +444,10 @@ virConnSetErrorFunc(virConnectPtr conn, void *userData,
...
@@ -309,8 +444,10 @@ virConnSetErrorFunc(virConnectPtr conn, void *userData,
{
{
if
(
conn
==
NULL
)
if
(
conn
==
NULL
)
return
;
return
;
virMutexLock
(
&
conn
->
lock
);
conn
->
handler
=
handler
;
conn
->
handler
=
handler
;
conn
->
userData
=
userData
;
conn
->
userData
=
userData
;
virMutexUnlock
(
&
conn
->
lock
);
}
}
/**
/**
...
@@ -357,6 +494,44 @@ virDefaultErrorFunc(virErrorPtr err)
...
@@ -357,6 +494,44 @@ virDefaultErrorFunc(virErrorPtr err)
dom
,
lvl
,
domain
,
network
,
err
->
message
);
dom
,
lvl
,
domain
,
network
,
err
->
message
);
}
}
/*
* Internal helper to ensure the global error object
* is initialized with a generic message if not already
* set.
*/
void
virSetGlobalError
(
void
)
{
virErrorPtr
err
=
virLastErrorObject
();
if
(
err
&&
err
->
code
==
VIR_ERR_OK
)
virErrorGenericFailure
(
err
);
}
/*
* Internal helper to ensure the connection error object
* is initialized from the global object.
*/
void
virSetConnError
(
virConnectPtr
conn
)
{
virErrorPtr
err
=
virLastErrorObject
();
if
(
err
&&
err
->
code
==
VIR_ERR_OK
)
virErrorGenericFailure
(
err
);
if
(
conn
)
{
virMutexLock
(
&
conn
->
lock
);
if
(
err
)
virCopyError
(
err
,
&
conn
->
err
);
else
virErrorGenericFailure
(
&
conn
->
err
);
virMutexUnlock
(
&
conn
->
lock
);
}
}
/**
/**
* virRaiseError:
* virRaiseError:
* @conn: the connection to the hypervisor if available
* @conn: the connection to the hypervisor if available
...
@@ -377,16 +552,29 @@ virDefaultErrorFunc(virErrorPtr err)
...
@@ -377,16 +552,29 @@ virDefaultErrorFunc(virErrorPtr err)
* immediately if a callback is found and store it for later handling.
* immediately if a callback is found and store it for later handling.
*/
*/
void
void
virRaiseError
(
virConnectPtr
conn
,
virDomainPtr
dom
,
virNetworkPtr
net
,
virRaiseError
(
virConnectPtr
conn
,
virDomainPtr
dom
ATTRIBUTE_UNUSED
,
virNetworkPtr
net
ATTRIBUTE_UNUSED
,
int
domain
,
int
code
,
virErrorLevel
level
,
int
domain
,
int
code
,
virErrorLevel
level
,
const
char
*
str1
,
const
char
*
str2
,
const
char
*
str3
,
const
char
*
str1
,
const
char
*
str2
,
const
char
*
str3
,
int
int1
,
int
int2
,
const
char
*
msg
,
...)
int
int1
,
int
int2
,
const
char
*
msg
,
...)
{
{
virErrorPtr
to
=
&
virLastErr
;
virErrorPtr
to
;
void
*
userData
=
virUserData
;
void
*
userData
=
virUserData
;
virErrorFunc
handler
=
virErrorHandler
;
virErrorFunc
handler
=
virErrorHandler
;
char
*
str
;
char
*
str
;
/*
* All errors are recorded in thread local storage
* For compatability, public API calls will copy them
* to the per-connection error object when neccessary
*/
to
=
virLastErrorObject
();
if
(
!
to
)
return
;
/* Hit OOM allocating thread error object, sod all we can do now */
virResetError
(
to
);
if
(
code
==
VIR_ERR_OK
)
if
(
code
==
VIR_ERR_OK
)
return
;
return
;
...
@@ -394,11 +582,12 @@ virRaiseError(virConnectPtr conn, virDomainPtr dom, virNetworkPtr net,
...
@@ -394,11 +582,12 @@ virRaiseError(virConnectPtr conn, virDomainPtr dom, virNetworkPtr net,
* try to find the best place to save and report the error
* try to find the best place to save and report the error
*/
*/
if
(
conn
!=
NULL
)
{
if
(
conn
!=
NULL
)
{
to
=
&
conn
->
err
;
virMutexLock
(
&
conn
->
lock
)
;
if
(
conn
->
handler
!=
NULL
)
{
if
(
conn
->
handler
!=
NULL
)
{
handler
=
conn
->
handler
;
handler
=
conn
->
handler
;
userData
=
conn
->
userData
;
userData
=
conn
->
userData
;
}
}
virMutexUnlock
(
&
conn
->
lock
);
}
}
/*
/*
...
@@ -421,9 +610,10 @@ virRaiseError(virConnectPtr conn, virDomainPtr dom, virNetworkPtr net,
...
@@ -421,9 +610,10 @@ virRaiseError(virConnectPtr conn, virDomainPtr dom, virNetworkPtr net,
* Save the information about the error
* Save the information about the error
*/
*/
virResetError
(
to
);
virResetError
(
to
);
to
->
conn
=
conn
;
/*
to
->
dom
=
dom
;
* Delibrately not setting conn, dom & net fields since
to
->
net
=
net
;
* they're utterly unsafe
*/
to
->
domain
=
domain
;
to
->
domain
=
domain
;
to
->
code
=
code
;
to
->
code
=
code
;
to
->
message
=
str
;
to
->
message
=
str
;
...
@@ -813,3 +1003,5 @@ void virReportErrorHelper(virConnectPtr conn, int domcode, int errcode,
...
@@ -813,3 +1003,5 @@ void virReportErrorHelper(virConnectPtr conn, int domcode, int errcode,
virerr
,
errorMessage
,
NULL
,
-
1
,
-
1
,
virerr
,
errorMessage
);
virerr
,
errorMessage
,
NULL
,
-
1
,
-
1
,
virerr
,
errorMessage
);
}
}
src/virterror_internal.h
浏览文件 @
ead04dcb
...
@@ -24,7 +24,6 @@
...
@@ -24,7 +24,6 @@
#include "internal.h"
#include "internal.h"
extern
virError
virLastErr
;
extern
virErrorFunc
virErrorHandler
;
extern
virErrorFunc
virErrorHandler
;
extern
void
*
virUserData
;
extern
void
*
virUserData
;
...
@@ -33,6 +32,7 @@ extern void *virUserData;
...
@@ -33,6 +32,7 @@ extern void *virUserData;
* API for error handling *
* API for error handling *
* *
* *
************************************************************************/
************************************************************************/
int
virErrorInitialize
(
void
);
void
virRaiseError
(
virConnectPtr
conn
,
void
virRaiseError
(
virConnectPtr
conn
,
virDomainPtr
dom
,
virDomainPtr
dom
,
virNetworkPtr
net
,
virNetworkPtr
net
,
...
@@ -53,4 +53,7 @@ void virReportErrorHelper(virConnectPtr conn, int domcode, int errcode,
...
@@ -53,4 +53,7 @@ void virReportErrorHelper(virConnectPtr conn, int domcode, int errcode,
ATTRIBUTE_FORMAT
(
printf
,
7
,
8
);
ATTRIBUTE_FORMAT
(
printf
,
7
,
8
);
void
virSetGlobalError
(
void
);
void
virSetConnError
(
virConnectPtr
conn
);
#endif
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录