Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
56a46886
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看板
提交
56a46886
编写于
6月 12, 2009
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix re-detection of transient VMs after libvirtd restart
上级
3bdda17a
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
444 addition
and
325 deletion
+444
-325
ChangeLog
ChangeLog
+19
-3
src/domain_conf.c
src/domain_conf.c
+285
-24
src/domain_conf.h
src/domain_conf.h
+16
-1
src/libvirt_private.syms
src/libvirt_private.syms
+1
-0
src/lxc_driver.c
src/lxc_driver.c
+1
-1
src/qemu_conf.c
src/qemu_conf.c
+0
-190
src/qemu_conf.h
src/qemu_conf.h
+0
-18
src/qemu_driver.c
src/qemu_driver.c
+78
-86
src/security.h
src/security.h
+3
-0
src/security_selinux.c
src/security_selinux.c
+39
-0
src/uml_driver.c
src/uml_driver.c
+2
-2
未找到文件。
ChangeLog
浏览文件 @
56a46886
Thu Jun 12 12:26:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Fix re-detection of transient VMs after libvirtd restart
* src/domain_conf.c, src/domain_conf.h, src/libvirt_private.syms:
Extend virDomainLoadAllConfigs to allow for loading of live
state info from XML files. Add APIs to format/parse state info
from virDomainObjPtr to XML.
* src/lxc_driver.c, src/uml_driver.c: Adapt for API change in
virDomainLoadAllConfigs.
* src/qemu_driver.c, src/qemu_conf.c, src/qemu_conf.h: Remove
all code for loading live state files, and use standard APIs
from domain_conf.h.
* src/security.h, src/security_selinux.c: Add API for reserving
an existing in-use MCS context from a running VM detected at
daemon startup.
Thu Jun 11 17:33:43 CEST 2009 Daniel Veillard <veillard@redhat.com>
* qemud/remote.c: fixing a typo pointed out by Runa Bhattacharjee
...
...
@@ -6,9 +22,9 @@ Thu Jun 11 16:22:22 CEST 2009 Daniel Veillard <veillard@redhat.com>
* src/node_device_hal.c src/node_device_conf.[ch]: add support
for serial number in HAL storage backend, patch by Dave Allan
* docs/schemas/nodedev.rng
tests/nodedevschemadata/storage_serial_3600c0ff000d7a2a5d463ff4902000000.xml:
update the schemas and add a test case, also by Dave Allan
* docs/schemas/nodedev.rng
,
tests/nodedevschemadata/storage_serial_3600c0ff000d7a2a5d463ff4902000000.xml:
update the schemas and add a test case, also by Dave Allan
Thu Jun 11 15:18:44 GMT 2009 Mark McLoughlin <markmc@redhat.com>
...
...
src/domain_conf.c
浏览文件 @
56a46886
...
...
@@ -39,6 +39,7 @@
#include "util.h"
#include "buf.h"
#include "c-ctype.h"
#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
...
...
@@ -511,6 +512,31 @@ void virDomainObjListFree(virDomainObjListPtr vms)
vms
->
count
=
0
;
}
static
virDomainObjPtr
virDomainObjNew
(
virConnectPtr
conn
)
{
virDomainObjPtr
domain
;
if
(
VIR_ALLOC
(
domain
)
<
0
)
{
virReportOOMError
(
conn
);
return
NULL
;
}
if
(
virMutexInit
(
&
domain
->
lock
)
<
0
)
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot initialize mutex"
));
VIR_FREE
(
domain
);
return
NULL
;
}
virDomainObjLock
(
domain
);
domain
->
state
=
VIR_DOMAIN_SHUTOFF
;
domain
->
monitorWatch
=
-
1
;
domain
->
monitor
=
-
1
;
return
domain
;
}
virDomainObjPtr
virDomainAssignDef
(
virConnectPtr
conn
,
virDomainObjListPtr
doms
,
const
virDomainDefPtr
def
)
...
...
@@ -530,29 +556,15 @@ virDomainObjPtr virDomainAssignDef(virConnectPtr conn,
return
domain
;
}
if
(
VIR_
ALLOC
(
domain
)
<
0
)
{
if
(
VIR_
REALLOC_N
(
doms
->
objs
,
doms
->
count
+
1
)
<
0
)
{
virReportOOMError
(
conn
);
return
NULL
;
}
if
(
virMutexInit
(
&
domain
->
lock
)
<
0
)
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"cannot initialize mutex"
));
VIR_FREE
(
domain
);
if
(
!
(
domain
=
virDomainObjNew
(
conn
)))
return
NULL
;
}
virDomainObjLock
(
domain
);
domain
->
state
=
VIR_DOMAIN_SHUTOFF
;
domain
->
def
=
def
;
domain
->
monitorWatch
=
-
1
;
domain
->
monitor
=
-
1
;
if
(
VIR_REALLOC_N
(
doms
->
objs
,
doms
->
count
+
1
)
<
0
)
{
virReportOOMError
(
conn
);
VIR_FREE
(
domain
);
return
NULL
;
}
doms
->
objs
[
doms
->
count
]
=
domain
;
doms
->
count
++
;
...
...
@@ -2623,6 +2635,68 @@ no_memory:
return
NULL
;
}
static
virDomainObjPtr
virDomainObjParseXML
(
virConnectPtr
conn
,
virCapsPtr
caps
,
xmlXPathContextPtr
ctxt
)
{
char
*
tmp
=
NULL
;
long
val
;
xmlNodePtr
config
;
xmlNodePtr
oldnode
;
virDomainObjPtr
obj
;
if
(
!
(
obj
=
virDomainObjNew
(
conn
)))
return
NULL
;
if
(
!
(
config
=
virXPathNode
(
conn
,
"./domain"
,
ctxt
)))
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no domain config"
));
goto
error
;
}
oldnode
=
ctxt
->
node
;
ctxt
->
node
=
config
;
obj
->
def
=
virDomainDefParseXML
(
conn
,
caps
,
ctxt
,
0
);
ctxt
->
node
=
oldnode
;
if
(
!
obj
->
def
)
goto
error
;
if
(
!
(
tmp
=
virXPathString
(
conn
,
"string(./@state)"
,
ctxt
)))
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"missing domain state"
));
goto
error
;
}
if
((
obj
->
state
=
virDomainStateTypeFromString
(
tmp
))
<
0
)
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid domain state '%s'"
),
tmp
);
VIR_FREE
(
tmp
);
goto
error
;
}
VIR_FREE
(
tmp
);
if
((
virXPathLong
(
conn
,
"string(./@pid)"
,
ctxt
,
&
val
))
<
0
)
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"invalid pid"
));
goto
error
;
}
obj
->
pid
=
(
pid_t
)
val
;
if
(
!
(
obj
->
monitorpath
=
virXPathString
(
conn
,
"string(./monitor[1]/@path)"
,
ctxt
)))
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no monitor path"
));
goto
error
;
}
return
obj
;
error:
virDomainObjFree
(
obj
);
return
NULL
;
}
/* Called from SAX on parsing errors in the XML. */
static
void
catchXMLError
(
void
*
ctx
,
const
char
*
msg
ATTRIBUTE_UNUSED
,
...)
...
...
@@ -2755,6 +2829,78 @@ cleanup:
xmlXPathFreeContext
(
ctxt
);
return
def
;
}
virDomainObjPtr
virDomainObjParseFile
(
virConnectPtr
conn
,
virCapsPtr
caps
,
const
char
*
filename
)
{
xmlParserCtxtPtr
pctxt
;
xmlDocPtr
xml
=
NULL
;
xmlNodePtr
root
;
virDomainObjPtr
obj
=
NULL
;
/* Set up a parser context so we can catch the details of XML errors. */
pctxt
=
xmlNewParserCtxt
();
if
(
!
pctxt
||
!
pctxt
->
sax
)
goto
cleanup
;
pctxt
->
sax
->
error
=
catchXMLError
;
pctxt
->
_private
=
conn
;
if
(
conn
)
virResetError
(
&
conn
->
err
);
xml
=
xmlCtxtReadFile
(
pctxt
,
filename
,
NULL
,
XML_PARSE_NOENT
|
XML_PARSE_NONET
|
XML_PARSE_NOWARNING
);
if
(
!
xml
)
{
if
(
virGetLastError
()
==
NULL
)
virDomainReportError
(
conn
,
VIR_ERR_XML_ERROR
,
"%s"
,
_
(
"failed to parse xml document"
));
goto
cleanup
;
}
if
((
root
=
xmlDocGetRootElement
(
xml
))
==
NULL
)
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"missing root element"
));
goto
cleanup
;
}
obj
=
virDomainObjParseNode
(
conn
,
caps
,
xml
,
root
);
cleanup:
xmlFreeParserCtxt
(
pctxt
);
xmlFreeDoc
(
xml
);
return
obj
;
}
virDomainObjPtr
virDomainObjParseNode
(
virConnectPtr
conn
,
virCapsPtr
caps
,
xmlDocPtr
xml
,
xmlNodePtr
root
)
{
xmlXPathContextPtr
ctxt
=
NULL
;
virDomainObjPtr
obj
=
NULL
;
if
(
!
xmlStrEqual
(
root
->
name
,
BAD_CAST
"domstatus"
))
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"incorrect root element"
));
goto
cleanup
;
}
ctxt
=
xmlXPathNewContext
(
xml
);
if
(
ctxt
==
NULL
)
{
virReportOOMError
(
conn
);
goto
cleanup
;
}
ctxt
->
node
=
root
;
obj
=
virDomainObjParseXML
(
conn
,
caps
,
ctxt
);
cleanup:
xmlXPathFreeContext
(
ctxt
);
return
obj
;
}
#endif
/* ! PROXY */
/************************************************************************
...
...
@@ -3707,6 +3853,40 @@ char *virDomainDefFormat(virConnectPtr conn,
return
NULL
;
}
char
*
virDomainObjFormat
(
virConnectPtr
conn
,
virDomainObjPtr
obj
,
int
flags
)
{
char
*
config_xml
=
NULL
,
*
xml
=
NULL
;
virBuffer
buf
=
VIR_BUFFER_INITIALIZER
;
virBufferVSprintf
(
&
buf
,
"<domstatus state='%s' pid='%d'>
\n
"
,
virDomainStateTypeToString
(
obj
->
state
),
obj
->
pid
);
virBufferEscapeString
(
&
buf
,
" <monitor path='%s'/>
\n
"
,
obj
->
monitorpath
);
if
(
!
(
config_xml
=
virDomainDefFormat
(
conn
,
obj
->
def
,
flags
)))
goto
error
;
virBufferAdd
(
&
buf
,
config_xml
,
strlen
(
config_xml
));
VIR_FREE
(
config_xml
);
virBufferAddLit
(
&
buf
,
"</domstatus>
\n
"
);
if
(
virBufferError
(
&
buf
))
goto
no_memory
;
return
virBufferContentAndReset
(
&
buf
);
no_memory:
virReportOOMError
(
conn
);
error:
xml
=
virBufferContentAndReset
(
&
buf
);
VIR_FREE
(
xml
);
return
NULL
;
}
#ifndef PROXY
...
...
@@ -3782,6 +3962,27 @@ cleanup:
return
ret
;
}
int
virDomainSaveStatus
(
virConnectPtr
conn
,
const
char
*
statusDir
,
virDomainObjPtr
obj
)
{
int
ret
=
-
1
;
char
*
xml
;
if
(
!
(
xml
=
virDomainObjFormat
(
conn
,
obj
,
VIR_DOMAIN_XML_SECURE
)))
goto
cleanup
;
if
(
virDomainSaveXML
(
conn
,
statusDir
,
obj
->
def
,
xml
))
goto
cleanup
;
ret
=
0
;
cleanup:
VIR_FREE
(
xml
);
return
ret
;
}
virDomainObjPtr
virDomainLoadConfig
(
virConnectPtr
conn
,
virCapsPtr
caps
,
...
...
@@ -3835,17 +4036,67 @@ error:
return
NULL
;
}
static
virDomainObjPtr
virDomainLoadStatus
(
virConnectPtr
conn
,
virCapsPtr
caps
,
virDomainObjListPtr
doms
,
const
char
*
statusDir
,
const
char
*
name
,
virDomainLoadConfigNotify
notify
,
void
*
opaque
)
{
char
*
statusFile
=
NULL
;
virDomainObjPtr
obj
=
NULL
;
virDomainObjPtr
tmp
=
NULL
;
if
((
statusFile
=
virDomainConfigFile
(
conn
,
statusDir
,
name
))
==
NULL
)
goto
error
;
if
(
!
(
obj
=
virDomainObjParseFile
(
conn
,
caps
,
statusFile
)))
goto
error
;
tmp
=
virDomainFindByName
(
doms
,
obj
->
def
->
name
);
if
(
tmp
)
{
virDomainObjUnlock
(
obj
);
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"unexpected domain %s already exists"
),
obj
->
def
->
name
);
goto
error
;
}
if
(
VIR_REALLOC_N
(
doms
->
objs
,
doms
->
count
+
1
)
<
0
)
{
virReportOOMError
(
conn
);
goto
error
;
}
doms
->
objs
[
doms
->
count
]
=
obj
;
doms
->
count
++
;
if
(
notify
)
(
*
notify
)(
obj
,
1
,
opaque
);
VIR_FREE
(
statusFile
);
return
obj
;
error:
virDomainObjFree
(
obj
);
VIR_FREE
(
statusFile
);
return
NULL
;
}
int
virDomainLoadAllConfigs
(
virConnectPtr
conn
,
virCapsPtr
caps
,
virDomainObjListPtr
doms
,
const
char
*
configDir
,
const
char
*
autostartDir
,
int
liveStatus
,
virDomainLoadConfigNotify
notify
,
void
*
opaque
)
{
DIR
*
dir
;
struct
dirent
*
entry
;
VIR_INFO
(
"Scanning for configs in %s"
,
configDir
);
if
(
!
(
dir
=
opendir
(
configDir
)))
{
if
(
errno
==
ENOENT
)
return
0
;
...
...
@@ -3866,14 +4117,24 @@ int virDomainLoadAllConfigs(virConnectPtr conn,
/* NB: ignoring errors, so one malformed config doesn't
kill the whole process */
dom
=
virDomainLoadConfig
(
conn
,
caps
,
doms
,
configDir
,
autostartDir
,
entry
->
d_name
,
notify
,
opaque
);
VIR_INFO
(
"Loading config file '%s.xml'"
,
entry
->
d_name
);
if
(
liveStatus
)
dom
=
virDomainLoadStatus
(
conn
,
caps
,
doms
,
configDir
,
entry
->
d_name
,
notify
,
opaque
);
else
dom
=
virDomainLoadConfig
(
conn
,
caps
,
doms
,
configDir
,
autostartDir
,
entry
->
d_name
,
notify
,
opaque
);
if
(
dom
)
{
virDomainObjUnlock
(
dom
);
dom
->
persistent
=
1
;
...
...
src/domain_conf.h
浏览文件 @
56a46886
...
...
@@ -515,7 +515,6 @@ struct _virDomainObj {
int
monitor
;
char
*
monitorpath
;
int
monitorWatch
;
int
logfile
;
int
pid
;
int
state
;
...
...
@@ -589,10 +588,22 @@ virDomainDefPtr virDomainDefParseNode(virConnectPtr conn,
xmlDocPtr
doc
,
xmlNodePtr
root
,
int
flags
);
virDomainObjPtr
virDomainObjParseFile
(
virConnectPtr
conn
,
virCapsPtr
caps
,
const
char
*
filename
);
virDomainObjPtr
virDomainObjParseNode
(
virConnectPtr
conn
,
virCapsPtr
caps
,
xmlDocPtr
xml
,
xmlNodePtr
root
);
#endif
char
*
virDomainDefFormat
(
virConnectPtr
conn
,
virDomainDefPtr
def
,
int
flags
);
char
*
virDomainObjFormat
(
virConnectPtr
conn
,
virDomainObjPtr
obj
,
int
flags
);
int
virDomainCpuSetParse
(
virConnectPtr
conn
,
const
char
**
str
,
...
...
@@ -615,6 +626,9 @@ int virDomainSaveXML(virConnectPtr conn,
int
virDomainSaveConfig
(
virConnectPtr
conn
,
const
char
*
configDir
,
virDomainDefPtr
def
);
int
virDomainSaveStatus
(
virConnectPtr
conn
,
const
char
*
statusDir
,
virDomainObjPtr
obj
);
typedef
void
(
*
virDomainLoadConfigNotify
)(
virDomainObjPtr
dom
,
int
newDomain
,
...
...
@@ -634,6 +648,7 @@ int virDomainLoadAllConfigs(virConnectPtr conn,
virDomainObjListPtr
doms
,
const
char
*
configDir
,
const
char
*
autostartDir
,
int
liveStatus
,
virDomainLoadConfigNotify
notify
,
void
*
opaque
);
...
...
src/libvirt_private.syms
浏览文件 @
56a46886
...
...
@@ -94,6 +94,7 @@ virDomainObjListFree;
virDomainRemoveInactive;
virDomainSaveXML;
virDomainSaveConfig;
virDomainSaveStatus;
virDomainSoundDefFree;
virDomainSoundModelTypeFromString;
virDomainSoundModelTypeToString;
...
...
src/lxc_driver.c
浏览文件 @
56a46886
...
...
@@ -1190,7 +1190,7 @@ static int lxcStartup(void)
&
lxc_driver
->
domains
,
lxc_driver
->
configDir
,
lxc_driver
->
autostartDir
,
NULL
,
NULL
)
<
0
)
0
,
NULL
,
NULL
)
<
0
)
goto
cleanup
;
for
(
i
=
0
;
i
<
lxc_driver
->
domains
.
count
;
i
++
)
{
...
...
src/qemu_conf.c
浏览文件 @
56a46886
...
...
@@ -2888,193 +2888,3 @@ cleanup:
return
def
;
}
/* Called from SAX on parsing errors in the XML. */
static
void
catchXMLError
(
void
*
ctx
,
const
char
*
msg
ATTRIBUTE_UNUSED
,
...)
{
xmlParserCtxtPtr
ctxt
=
(
xmlParserCtxtPtr
)
ctx
;
if
(
ctxt
)
{
virConnectPtr
conn
=
ctxt
->
_private
;
if
(
ctxt
->
lastError
.
level
==
XML_ERR_FATAL
&&
ctxt
->
lastError
.
message
!=
NULL
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_XML_DETAIL
,
_
(
"at line %d: %s"
),
ctxt
->
lastError
.
line
,
ctxt
->
lastError
.
message
);
}
}
}
/**
* qemudDomainStatusParseFile
*
* read the last known status of a domain
*
* Returns 0 on success
*/
qemudDomainStatusPtr
qemudDomainStatusParseFile
(
virConnectPtr
conn
,
virCapsPtr
caps
,
const
char
*
filename
,
int
flags
)
{
xmlParserCtxtPtr
pctxt
=
NULL
;
xmlXPathContextPtr
ctxt
=
NULL
;
xmlDocPtr
xml
=
NULL
;
xmlNodePtr
root
,
config_root
;
virDomainDefPtr
def
=
NULL
;
char
*
tmp
=
NULL
;
long
val
;
qemudDomainStatusPtr
status
=
NULL
;
if
(
VIR_ALLOC
(
status
)
<
0
)
{
virReportOOMError
(
conn
);
goto
error
;
}
/* Set up a parser context so we can catch the details of XML errors. */
pctxt
=
xmlNewParserCtxt
();
if
(
!
pctxt
||
!
pctxt
->
sax
)
goto
error
;
pctxt
->
sax
->
error
=
catchXMLError
;
pctxt
->
_private
=
conn
;
if
(
conn
)
virResetError
(
&
conn
->
err
);
xml
=
xmlCtxtReadFile
(
pctxt
,
filename
,
NULL
,
XML_PARSE_NOENT
|
XML_PARSE_NONET
|
XML_PARSE_NOWARNING
);
if
(
!
xml
)
{
if
(
conn
&&
conn
->
err
.
code
==
VIR_ERR_NONE
)
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_XML_ERROR
,
"%s"
,
_
(
"failed to parse xml document"
));
goto
error
;
}
if
((
root
=
xmlDocGetRootElement
(
xml
))
==
NULL
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"missing root element"
));
goto
error
;
}
ctxt
=
xmlXPathNewContext
(
xml
);
if
(
ctxt
==
NULL
)
{
virReportOOMError
(
conn
);
goto
error
;
}
if
(
!
xmlStrEqual
(
root
->
name
,
BAD_CAST
"domstatus"
))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"incorrect root element"
));
goto
error
;
}
ctxt
->
node
=
root
;
if
(
!
(
tmp
=
virXPathString
(
conn
,
"string(./@state)"
,
ctxt
)))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"invalid domain state"
));
goto
error
;
}
else
{
status
->
state
=
virDomainStateTypeFromString
(
tmp
);
VIR_FREE
(
tmp
);
}
if
((
virXPathLong
(
conn
,
"string(./@pid)"
,
ctxt
,
&
val
))
<
0
)
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"invalid pid"
));
goto
error
;
}
else
status
->
pid
=
(
pid_t
)
val
;
if
(
!
(
tmp
=
virXPathString
(
conn
,
"string(./monitor[1]/@path)"
,
ctxt
)))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no monitor path"
));
goto
error
;
}
else
status
->
monitorpath
=
tmp
;
if
(
!
(
config_root
=
virXPathNode
(
conn
,
"./domain"
,
ctxt
)))
{
qemudReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"no domain config"
));
goto
error
;
}
if
(
!
(
def
=
virDomainDefParseNode
(
conn
,
caps
,
xml
,
config_root
,
flags
)))
goto
error
;
else
status
->
def
=
def
;
cleanup:
xmlFreeParserCtxt
(
pctxt
);
xmlXPathFreeContext
(
ctxt
);
xmlFreeDoc
(
xml
);
return
status
;
error:
VIR_FREE
(
tmp
);
VIR_FREE
(
status
);
goto
cleanup
;
}
/**
* qemudDomainStatusFormat
*
* Get the state of a running domain as XML
*
* Returns xml on success
*/
static
char
*
qemudDomainStatusFormat
(
virConnectPtr
conn
,
virDomainObjPtr
vm
)
{
char
*
config_xml
=
NULL
,
*
xml
=
NULL
;
virBuffer
buf
=
VIR_BUFFER_INITIALIZER
;
virBufferVSprintf
(
&
buf
,
"<domstatus state='%s' pid='%d'>
\n
"
,
virDomainStateTypeToString
(
vm
->
state
),
vm
->
pid
);
virBufferEscapeString
(
&
buf
,
" <monitor path='%s'/>
\n
"
,
vm
->
monitorpath
);
if
(
!
(
config_xml
=
virDomainDefFormat
(
conn
,
vm
->
def
,
VIR_DOMAIN_XML_SECURE
)))
goto
cleanup
;
virBufferAdd
(
&
buf
,
config_xml
,
strlen
(
config_xml
));
virBufferAddLit
(
&
buf
,
"</domstatus>
\n
"
);
xml
=
virBufferContentAndReset
(
&
buf
);
cleanup:
VIR_FREE
(
config_xml
);
return
xml
;
}
/**
* qemudSaveDomainStatus
*
* Save the current status of a running domain
*
* Returns 0 on success
*/
int
qemudSaveDomainStatus
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
)
{
int
ret
=
-
1
;
char
*
xml
=
NULL
;
if
(
!
(
xml
=
qemudDomainStatusFormat
(
conn
,
vm
)))
goto
cleanup
;
if
((
ret
=
virDomainSaveXML
(
conn
,
driver
->
stateDir
,
vm
->
def
,
xml
)))
goto
cleanup
;
ret
=
0
;
cleanup:
VIR_FREE
(
xml
);
return
ret
;
}
src/qemu_conf.h
浏览文件 @
56a46886
...
...
@@ -92,15 +92,6 @@ struct qemud_driver {
virSecurityDriverPtr
securityDriver
;
};
/* Status needed to reconenct to running VMs */
typedef
struct
_qemudDomainStatus
qemudDomainStatus
;
typedef
qemudDomainStatus
*
qemudDomainStatusPtr
;
struct
_qemudDomainStatus
{
char
*
monitorpath
;
pid_t
pid
;
int
state
;
virDomainDefPtr
def
;
};
/* Port numbers used for KVM migration. */
#define QEMUD_MIGRATION_FIRST_PORT 49152
...
...
@@ -149,13 +140,4 @@ virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn,
virCapsPtr
caps
,
const
char
*
args
);
const
char
*
qemudVirtTypeToString
(
int
type
);
qemudDomainStatusPtr
qemudDomainStatusParseFile
(
virConnectPtr
conn
,
virCapsPtr
caps
,
const
char
*
filename
,
int
flags
);
int
qemudSaveDomainStatus
(
virConnectPtr
conn
,
struct
qemud_driver
*
driver
,
virDomainObjPtr
vm
);
#endif
/* __QEMUD_CONF_H */
src/qemu_driver.c
浏览文件 @
56a46886
...
...
@@ -120,6 +120,8 @@ static int qemudMonitorCommandExtra(const virDomainObjPtr vm,
static
int
qemudDomainSetMemoryBalloon
(
virConnectPtr
conn
,
virDomainObjPtr
vm
,
unsigned
long
newmem
);
static
int
qemudDetectVcpuPIDs
(
virConnectPtr
conn
,
virDomainObjPtr
vm
);
static
struct
qemud_driver
*
qemu_driver
=
NULL
;
...
...
@@ -282,79 +284,65 @@ static int qemudOpenMonitor(virConnectPtr conn,
const
char
*
monitor
,
int
reconnect
);
/**
* qemudReconnectVMs
*
*
Reconnect running vms to the daemon process
/*
*
Open an existing VM's monitor, re-detect VCPU threads
*
and re-reserve the security labels in use
*/
static
int
qemudReconnectVMs
(
struct
qemud_driver
*
driver
)
qemuReconnectDomain
(
struct
qemud_driver
*
driver
,
virDomainObjPtr
obj
)
{
int
i
;
int
rc
;
for
(
i
=
0
;
i
<
driver
->
domains
.
count
;
i
++
)
{
virDomainObjPtr
vm
=
driver
->
domains
.
objs
[
i
];
qemudDomainStatusPtr
status
=
NULL
;
char
*
config
=
NULL
;
int
rc
;
virDomainObjLock
(
vm
);
if
((
rc
=
virFileReadPid
(
driver
->
stateDir
,
vm
->
def
->
name
,
&
vm
->
pid
))
==
0
)
DEBUG
(
"Found pid %d for '%s'"
,
vm
->
pid
,
vm
->
def
->
name
);
else
goto
next
;
if
((
rc
=
qemudOpenMonitor
(
NULL
,
driver
,
obj
,
obj
->
monitorpath
,
1
))
!=
0
)
{
VIR_ERROR
(
_
(
"Failed to reconnect monitor for %s: %d
\n
"
),
obj
->
def
->
name
,
rc
);
goto
error
;
}
if
((
config
=
virDomainConfigFile
(
NULL
,
driver
->
stateDir
,
vm
->
def
->
name
))
==
NULL
)
{
VIR_ERROR
(
_
(
"Failed to read domain status for %s
\n
"
),
vm
->
def
->
name
);
goto
next_error
;
}
if
(
qemudDetectVcpuPIDs
(
NULL
,
obj
)
<
0
)
{
goto
error
;
}
status
=
qemudDomainStatusParseFile
(
NULL
,
driver
->
caps
,
config
,
0
);
if
(
status
)
{
vm
->
newDef
=
vm
->
def
;
vm
->
def
=
status
->
def
;
}
else
{
VIR_ERROR
(
_
(
"Failed to parse domain status for %s
\n
"
),
vm
->
def
->
name
);
goto
next_error
;
}
if
(
obj
->
def
->
seclabel
.
type
==
VIR_DOMAIN_SECLABEL_DYNAMIC
&&
driver
->
securityDriver
&&
driver
->
securityDriver
->
domainReserveSecurityLabel
&&
driver
->
securityDriver
->
domainReserveSecurityLabel
(
NULL
,
obj
)
<
0
)
return
-
1
;
if
((
rc
=
qemudOpenMonitor
(
NULL
,
driver
,
vm
,
status
->
monitorpath
,
1
))
!=
0
)
{
VIR_ERROR
(
_
(
"Failed to reconnect monitor for %s: %d
\n
"
),
vm
->
def
->
name
,
rc
);
goto
next_error
;
}
if
(
obj
->
def
->
id
>=
driver
->
nextvmid
)
driver
->
nextvmid
=
obj
->
def
->
id
+
1
;
if
((
vm
->
logfile
=
qemudLogFD
(
NULL
,
driver
->
logDir
,
vm
->
def
->
name
))
<
0
)
goto
next_error
;
return
0
;
if
(
vm
->
def
->
id
>=
driver
->
nextvmid
)
driver
->
nextvmid
=
vm
->
def
->
id
+
1
;
error:
return
-
1
;
}
vm
->
state
=
status
->
state
;
goto
next
;
/**
* qemudReconnectVMs
*
* Try to re-open the resources for live VMs that we care
* about.
*/
static
void
qemuReconnectDomains
(
struct
qemud_driver
*
driver
)
{
int
i
;
next_error:
/* we failed to reconnect the vm so remove it's traces */
vm
->
def
->
id
=
-
1
;
qemudRemoveDomainStatus
(
NULL
,
driver
,
vm
);
/* Restore orignal def, if we'd loaded a live one */
if
(
vm
->
newDef
)
{
virDomainDefFree
(
vm
->
def
);
vm
->
def
=
vm
->
newDef
;
vm
->
newDef
=
NULL
;
for
(
i
=
0
;
i
<
driver
->
domains
.
count
;
i
++
)
{
virDomainObjPtr
obj
=
driver
->
domains
.
objs
[
i
];
virDomainObjLock
(
obj
);
if
(
qemuReconnectDomain
(
driver
,
obj
)
<
0
)
{
/* If we can't get the monitor back, then kill the VM
* so user has ability to start it again later without
* danger of ending up running twice */
qemudShutdownVMDaemon
(
NULL
,
driver
,
obj
)
;
}
next:
virDomainObjUnlock
(
vm
);
if
(
status
)
VIR_FREE
(
status
->
monitorpath
);
VIR_FREE
(
status
);
VIR_FREE
(
config
);
virDomainObjUnlock
(
obj
);
}
return
0
;
}
static
int
...
...
@@ -508,14 +496,25 @@ qemudStartup(void) {
goto
error
;
}
/* Get all the running persistent or transient configs first */
if
(
virDomainLoadAllConfigs
(
NULL
,
qemu_driver
->
caps
,
&
qemu_driver
->
domains
,
qemu_driver
->
stateDir
,
NULL
,
1
,
NULL
,
NULL
)
<
0
)
goto
error
;
qemuReconnectDomains
(
qemu_driver
);
/* Then inactive persistent configs */
if
(
virDomainLoadAllConfigs
(
NULL
,
qemu_driver
->
caps
,
&
qemu_driver
->
domains
,
qemu_driver
->
configDir
,
qemu_driver
->
autostartDir
,
NULL
,
NULL
)
<
0
)
0
,
NULL
,
NULL
)
<
0
)
goto
error
;
qemudReconnectVMs
(
qemu_driver
);
qemuDriverUnlock
(
qemu_driver
);
qemudAutostartConfigs
(
qemu_driver
);
...
...
@@ -564,7 +563,7 @@ qemudReload(void) {
&
qemu_driver
->
domains
,
qemu_driver
->
configDir
,
qemu_driver
->
autostartDir
,
qemudNotifyLoadDomain
,
qemu_driver
);
0
,
qemudNotifyLoadDomain
,
qemu_driver
);
qemuDriverUnlock
(
qemu_driver
);
qemudAutostartConfigs
(
qemu_driver
);
...
...
@@ -1329,6 +1328,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
int
pos
=
-
1
;
char
ebuf
[
1024
];
char
*
pidfile
=
NULL
;
int
logfile
;
struct
gemudHookData
hookData
;
hookData
.
conn
=
conn
;
...
...
@@ -1370,7 +1370,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
goto
cleanup
;
}
if
((
vm
->
logfile
=
qemudLogFD
(
conn
,
driver
->
logDir
,
vm
->
def
->
name
))
<
0
)
if
((
logfile
=
qemudLogFD
(
conn
,
driver
->
logDir
,
vm
->
def
->
name
))
<
0
)
goto
cleanup
;
emulator
=
vm
->
def
->
emulator
;
...
...
@@ -1419,29 +1419,29 @@ static int qemudStartVMDaemon(virConnectPtr conn,
tmp
=
progenv
;
while
(
*
tmp
)
{
if
(
safewrite
(
vm
->
logfile
,
*
tmp
,
strlen
(
*
tmp
))
<
0
)
if
(
safewrite
(
logfile
,
*
tmp
,
strlen
(
*
tmp
))
<
0
)
VIR_WARN
(
_
(
"Unable to write envv to logfile: %s
\n
"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
if
(
safewrite
(
vm
->
logfile
,
" "
,
1
)
<
0
)
if
(
safewrite
(
logfile
,
" "
,
1
)
<
0
)
VIR_WARN
(
_
(
"Unable to write envv to logfile: %s
\n
"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
tmp
++
;
}
tmp
=
argv
;
while
(
*
tmp
)
{
if
(
safewrite
(
vm
->
logfile
,
*
tmp
,
strlen
(
*
tmp
))
<
0
)
if
(
safewrite
(
logfile
,
*
tmp
,
strlen
(
*
tmp
))
<
0
)
VIR_WARN
(
_
(
"Unable to write argv to logfile: %s
\n
"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
if
(
safewrite
(
vm
->
logfile
,
" "
,
1
)
<
0
)
if
(
safewrite
(
logfile
,
" "
,
1
)
<
0
)
VIR_WARN
(
_
(
"Unable to write argv to logfile: %s
\n
"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
tmp
++
;
}
if
(
safewrite
(
vm
->
logfile
,
"
\n
"
,
1
)
<
0
)
if
(
safewrite
(
logfile
,
"
\n
"
,
1
)
<
0
)
VIR_WARN
(
_
(
"Unable to write argv to logfile: %s
\n
"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
if
((
pos
=
lseek
(
vm
->
logfile
,
0
,
SEEK_END
))
<
0
)
if
((
pos
=
lseek
(
logfile
,
0
,
SEEK_END
))
<
0
)
VIR_WARN
(
_
(
"Unable to seek to end of logfile: %s
\n
"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
...
...
@@ -1449,7 +1449,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
FD_SET
(
tapfds
[
i
],
&
keepfd
);
ret
=
virExecDaemonize
(
conn
,
argv
,
progenv
,
&
keepfd
,
&
child
,
stdin_fd
,
&
vm
->
logfile
,
&
vm
->
logfile
,
stdin_fd
,
&
logfile
,
&
logfile
,
VIR_EXEC_NONBLOCK
,
qemudSecurityHook
,
&
hookData
,
pidfile
);
...
...
@@ -1499,7 +1499,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
(
qemudInitCpus
(
conn
,
vm
,
migrateFrom
)
<
0
)
||
(
qemudInitPasswords
(
conn
,
driver
,
vm
)
<
0
)
||
(
qemudDomainSetMemoryBalloon
(
conn
,
vm
,
vm
->
def
->
memory
)
<
0
)
||
(
qemudSaveDomainStatus
(
conn
,
qemu_drive
r
,
vm
)
<
0
))
{
(
virDomainSaveStatus
(
conn
,
driver
->
stateDi
r
,
vm
)
<
0
))
{
qemudShutdownVMDaemon
(
conn
,
driver
,
vm
);
ret
=
-
1
;
/* No need for 'goto cleanup' now since qemudShutdownVMDaemon does enough */
...
...
@@ -1517,10 +1517,8 @@ cleanup:
vm
->
def
->
graphics
[
0
]
->
type
==
VIR_DOMAIN_GRAPHICS_TYPE_VNC
&&
vm
->
def
->
graphics
[
0
]
->
data
.
vnc
.
autoport
)
vm
->
def
->
graphics
[
0
]
->
data
.
vnc
.
port
=
-
1
;
if
(
vm
->
logfile
!=
-
1
)
{
close
(
vm
->
logfile
);
vm
->
logfile
=
-
1
;
}
if
(
logfile
!=
-
1
)
close
(
logfile
);
vm
->
def
->
id
=
-
1
;
return
-
1
;
}
...
...
@@ -1547,14 +1545,8 @@ static void qemudShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
vm
->
monitorWatch
=
-
1
;
}
if
(
close
(
vm
->
logfile
)
<
0
)
{
char
ebuf
[
1024
];
VIR_WARN
(
_
(
"Unable to close logfile: %s
\n
"
),
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
}
if
(
vm
->
monitor
!=
-
1
)
close
(
vm
->
monitor
);
vm
->
logfile
=
-
1
;
vm
->
monitor
=
-
1
;
/* shut it off for sure */
...
...
@@ -2183,7 +2175,7 @@ static int qemudDomainSuspend(virDomainPtr dom) {
VIR_DOMAIN_EVENT_SUSPENDED_PAUSED
);
VIR_FREE
(
info
);
}
if
(
qemudSaveDomainStatus
(
dom
->
conn
,
drive
r
,
vm
)
<
0
)
if
(
virDomainSaveStatus
(
dom
->
conn
,
driver
->
stateDi
r
,
vm
)
<
0
)
goto
cleanup
;
ret
=
0
;
...
...
@@ -2233,7 +2225,7 @@ static int qemudDomainResume(virDomainPtr dom) {
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED
);
VIR_FREE
(
info
);
}
if
(
qemudSaveDomainStatus
(
dom
->
conn
,
drive
r
,
vm
)
<
0
)
if
(
virDomainSaveStatus
(
dom
->
conn
,
driver
->
stateDi
r
,
vm
)
<
0
)
goto
cleanup
;
ret
=
0
;
...
...
@@ -4116,7 +4108,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
goto
cleanup
;
}
if
(
!
ret
&&
qemudSaveDomainStatus
(
dom
->
conn
,
drive
r
,
vm
)
<
0
)
if
(
!
ret
&&
virDomainSaveStatus
(
dom
->
conn
,
driver
->
stateDi
r
,
vm
)
<
0
)
ret
=
-
1
;
cleanup:
...
...
@@ -4238,7 +4230,7 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
qemudReportError
(
dom
->
conn
,
dom
,
NULL
,
VIR_ERR_NO_SUPPORT
,
"%s"
,
_
(
"only SCSI or virtio disk device can be detached dynamically"
));
if
(
!
ret
&&
qemudSaveDomainStatus
(
dom
->
conn
,
drive
r
,
vm
)
<
0
)
if
(
!
ret
&&
virDomainSaveStatus
(
dom
->
conn
,
driver
->
stateDi
r
,
vm
)
<
0
)
ret
=
-
1
;
cleanup:
...
...
src/security.h
浏览文件 @
56a46886
...
...
@@ -38,6 +38,8 @@ typedef int (*virSecurityDomainSetImageLabel) (virConnectPtr conn,
virDomainDiskDefPtr
disk
);
typedef
int
(
*
virSecurityDomainGenLabel
)
(
virConnectPtr
conn
,
virDomainObjPtr
sec
);
typedef
int
(
*
virSecurityDomainReserveLabel
)
(
virConnectPtr
conn
,
virDomainObjPtr
sec
);
typedef
int
(
*
virSecurityDomainGetLabel
)
(
virConnectPtr
conn
,
virDomainObjPtr
vm
,
virSecurityLabelPtr
sec
);
...
...
@@ -57,6 +59,7 @@ struct _virSecurityDriver {
virSecurityDomainRestoreImageLabel
domainRestoreSecurityImageLabel
;
virSecurityDomainSetImageLabel
domainSetSecurityImageLabel
;
virSecurityDomainGenLabel
domainGenSecurityLabel
;
virSecurityDomainReserveLabel
domainReserveSecurityLabel
;
virSecurityDomainGetLabel
domainGetSecurityLabel
;
virSecurityDomainSetLabel
domainSetSecurityLabel
;
virSecurityDomainRestoreLabel
domainRestoreSecurityLabel
;
...
...
src/security_selinux.c
浏览文件 @
56a46886
...
...
@@ -215,6 +215,44 @@ done:
return
rc
;
}
static
int
SELinuxReserveSecurityLabel
(
virConnectPtr
conn
,
virDomainObjPtr
vm
)
{
security_context_t
pctx
;
context_t
ctx
=
NULL
;
const
char
*
mcs
;
if
(
getpidcon
(
vm
->
pid
,
&
pctx
)
==
-
1
)
{
char
ebuf
[
1024
];
virSecurityReportError
(
conn
,
VIR_ERR_ERROR
,
_
(
"%s: error calling "
"getpidcon(): %s"
),
__func__
,
virStrerror
(
errno
,
ebuf
,
sizeof
ebuf
));
return
-
1
;
}
ctx
=
context_new
(
pctx
);
VIR_FREE
(
pctx
);
if
(
!
ctx
)
goto
err
;
mcs
=
context_range_get
(
ctx
);
if
(
!
mcs
)
goto
err
;
mcsAdd
(
mcs
);
context_free
(
ctx
);
return
0
;
err:
context_free
(
ctx
);
return
-
1
;
}
static
int
SELinuxSecurityDriverProbe
(
void
)
{
...
...
@@ -422,6 +460,7 @@ virSecurityDriver virSELinuxSecurityDriver = {
.
domainSetSecurityImageLabel
=
SELinuxSetSecurityImageLabel
,
.
domainRestoreSecurityImageLabel
=
SELinuxRestoreSecurityImageLabel
,
.
domainGenSecurityLabel
=
SELinuxGenSecurityLabel
,
.
domainReserveSecurityLabel
=
SELinuxReserveSecurityLabel
,
.
domainGetSecurityLabel
=
SELinuxGetSecurityLabel
,
.
domainRestoreSecurityLabel
=
SELinuxRestoreSecurityLabel
,
.
domainSetSecurityLabel
=
SELinuxSetSecurityLabel
,
...
...
src/uml_driver.c
浏览文件 @
56a46886
...
...
@@ -394,7 +394,7 @@ umlStartup(void) {
&
uml_driver
->
domains
,
uml_driver
->
configDir
,
uml_driver
->
autostartDir
,
NULL
,
NULL
)
<
0
)
0
,
NULL
,
NULL
)
<
0
)
goto
error
;
umlAutostartConfigs
(
uml_driver
);
...
...
@@ -433,7 +433,7 @@ umlReload(void) {
&
uml_driver
->
domains
,
uml_driver
->
configDir
,
uml_driver
->
autostartDir
,
NULL
,
NULL
);
0
,
NULL
,
NULL
);
umlAutostartConfigs
(
uml_driver
);
umlDriverUnlock
(
uml_driver
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录