Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
2e7a3736
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,发现更多精彩内容 >>
提交
2e7a3736
编写于
8月 13, 2008
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Switch LXC driver over to generic domain XML processing APIs
上级
763dacda
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
224 addition
and
1263 deletion
+224
-1263
ChangeLog
ChangeLog
+9
-0
src/lxc_conf.c
src/lxc_conf.c
+30
-1022
src/lxc_conf.h
src/lxc_conf.h
+7
-114
src/lxc_container.c
src/lxc_container.c
+13
-10
src/lxc_container.h
src/lxc_container.h
+1
-1
src/lxc_controller.c
src/lxc_controller.c
+2
-2
src/lxc_controller.h
src/lxc_controller.h
+1
-1
src/lxc_driver.c
src/lxc_driver.c
+161
-113
未找到文件。
ChangeLog
浏览文件 @
2e7a3736
Wed Aug 13 13:40:36 BST 2008 Daniel Berrange <berrange@redhat.com>
* src/lxc_conf.c, src/lxc_conf.h: Remove all domain XML
parsing / formatting methods, and all helpers for loading
and saving files on disk. Added capabilities data object
* src/lxc_container.c, src/lxc_container.h, src/lxc_driver.c,
src/lxc_controller.h, src/lxc_controller.c: Switch over
to use generic domain XML processing APIs.
Wed Aug 13 11:48:36 BST 2008 Daniel Berrange <berrange@redhat.com>
* configure.in: Add check for termios.h
...
...
src/lxc_conf.c
浏览文件 @
2e7a3736
...
...
@@ -27,22 +27,8 @@
#ifdef WITH_LXC
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/uri.h>
#include <libxml/xpath.h>
#include "buf.h"
#include "util.h"
#include "uuid.h"
#include "xml.h"
#include "memory.h"
#include "lxc_conf.h"
/* debug macros */
...
...
@@ -54,12 +40,12 @@ void lxcError(virConnectPtr conn, virDomainPtr dom, int code,
const
char
*
fmt
,
...)
{
va_list
args
;
char
errorMessage
[
LXC_MAX_ERROR_LEN
];
char
errorMessage
[
1024
];
const
char
*
codeErrorMessage
;
if
(
fmt
)
{
va_start
(
args
,
fmt
);
vsnprintf
(
errorMessage
,
LXC_MAX_ERROR_LEN
-
1
,
fmt
,
args
);
vsnprintf
(
errorMessage
,
sizeof
(
errorMessage
)
-
1
,
fmt
,
args
);
va_end
(
args
);
}
else
{
errorMessage
[
0
]
=
'\0'
;
...
...
@@ -71,769 +57,40 @@ void lxcError(virConnectPtr conn, virDomainPtr dom, int code,
codeErrorMessage
,
errorMessage
);
}
/**
* lxcParseInterfaceXML:
* @conn: pointer to connection
* @nodePtr: pointer to xml node structure
* @vm: pointer to net definition structure to fill in
*
* Parses the XML for a network interface and places the configuration
* in the given structure.
*
* Returns 0 on success or -1 in case of error
*/
static
int
lxcParseInterfaceXML
(
virConnectPtr
conn
,
xmlNodePtr
nodePtr
,
lxc_net_def_t
*
netDef
)
{
int
rc
=
-
1
;
xmlNodePtr
cur
;
xmlChar
*
type
=
NULL
;
xmlChar
*
parentIfName
=
NULL
;
xmlChar
*
network
=
NULL
;
xmlChar
*
bridge
=
NULL
;
xmlChar
*
macaddr
=
NULL
;
netDef
->
type
=
LXC_NET_NETWORK
;
type
=
xmlGetProp
(
nodePtr
,
BAD_CAST
"type"
);
if
(
type
!=
NULL
)
{
if
(
xmlStrEqual
(
type
,
BAD_CAST
"network"
))
{
netDef
->
type
=
LXC_NET_NETWORK
;
}
else
if
(
xmlStrEqual
(
type
,
BAD_CAST
"bridge"
))
{
netDef
->
type
=
LXC_NET_BRIDGE
;
}
else
{
lxcError
(
conn
,
NULL
,
VIR_ERR_XML_ERROR
,
_
(
"invalid interface type: %s"
),
type
);
goto
error_out
;
}
}
cur
=
nodePtr
->
children
;
for
(
cur
=
nodePtr
->
children
;
cur
!=
NULL
;
cur
=
cur
->
next
)
{
if
(
cur
->
type
==
XML_ELEMENT_NODE
)
{
DEBUG
(
"cur->name: %s"
,
(
char
*
)(
cur
->
name
));
if
((
macaddr
==
NULL
)
&&
(
xmlStrEqual
(
cur
->
name
,
BAD_CAST
"mac"
)))
{
macaddr
=
xmlGetProp
(
cur
,
BAD_CAST
"address"
);
}
else
if
((
network
==
NULL
)
&&
(
netDef
->
type
==
LXC_NET_NETWORK
)
&&
(
xmlStrEqual
(
cur
->
name
,
BAD_CAST
"source"
)))
{
network
=
xmlGetProp
(
cur
,
BAD_CAST
"network"
);
parentIfName
=
xmlGetProp
(
cur
,
BAD_CAST
"dev"
);
}
else
if
((
bridge
==
NULL
)
&&
(
netDef
->
type
==
LXC_NET_BRIDGE
)
&&
(
xmlStrEqual
(
cur
->
name
,
BAD_CAST
"source"
)))
{
bridge
=
xmlGetProp
(
cur
,
BAD_CAST
"bridge"
);
}
else
if
((
parentIfName
==
NULL
)
&&
(
xmlStrEqual
(
cur
->
name
,
BAD_CAST
"target"
)))
{
parentIfName
=
xmlGetProp
(
cur
,
BAD_CAST
"dev"
);
}
}
}
if
(
netDef
->
type
==
LXC_NET_NETWORK
)
{
if
(
network
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_XML_ERROR
,
_
(
"No <source> 'network' attribute specified with <interface type='network'/>"
));
goto
error_out
;
}
netDef
->
txName
=
strdup
((
char
*
)
network
);
if
(
NULL
==
netDef
->
txName
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
_
(
"No storage for network name"
));
goto
error_out
;
}
}
else
if
(
netDef
->
type
==
LXC_NET_BRIDGE
)
{
if
(
bridge
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_XML_ERROR
,
_
(
"No <source> 'bridge' attribute specified with <interface type='bridge'/>"
));
goto
error_out
;
}
netDef
->
txName
=
strdup
((
char
*
)
bridge
);
if
(
NULL
==
netDef
->
txName
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
_
(
"No storage for bridge name"
));
goto
error_out
;
}
}
if
(
parentIfName
!=
NULL
)
{
DEBUG
(
"set netDef->parentVeth: %s"
,
netDef
->
parentVeth
);
netDef
->
parentVeth
=
strdup
((
char
*
)
parentIfName
);
if
(
NULL
==
netDef
->
parentVeth
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
_
(
"No storage for parent veth device name"
));
goto
error_out
;
}
}
else
{
netDef
->
parentVeth
=
NULL
;
DEBUG0
(
"set netDef->parentVeth: NULL"
);
}
rc
=
0
;
error_out:
xmlFree
(
macaddr
);
xmlFree
(
network
);
xmlFree
(
bridge
);
xmlFree
(
parentIfName
);
return
rc
;
}
/**
* lxcParseDomainInterfaces:
* @conn: pointer to connection
* @nets: on success, points to an list of net def structs
* @contextPtr: pointer to xml context
*
* Parses the domain network interfaces and returns the information in a list
*
* Returns 0 on success or -1 in case of error
*/
static
int
lxcParseDomainInterfaces
(
virConnectPtr
conn
,
lxc_net_def_t
**
nets
,
xmlXPathContextPtr
contextPtr
)
{
int
rc
=
-
1
;
int
i
;
lxc_net_def_t
*
netDef
;
lxc_net_def_t
*
prevDef
=
NULL
;
int
numNets
=
0
;
xmlNodePtr
*
list
;
int
res
;
DEBUG0
(
"parsing nets"
);
res
=
virXPathNodeSet
(
conn
,
"/domain/devices/interface"
,
contextPtr
,
&
list
);
if
(
res
>
0
)
{
for
(
i
=
0
;
i
<
res
;
++
i
)
{
netDef
=
calloc
(
1
,
sizeof
(
lxc_net_def_t
));
if
(
NULL
==
netDef
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
_
(
"No storage for net def structure"
));
free
(
list
);
goto
parse_complete
;
}
rc
=
lxcParseInterfaceXML
(
conn
,
list
[
i
],
netDef
);
if
(
0
>
rc
)
{
DEBUG
(
"failed parsing a net: %d"
,
rc
);
free
(
netDef
);
free
(
list
);
goto
parse_complete
;
}
DEBUG0
(
"parsed a net"
);
/* set the linked list pointers */
numNets
++
;
netDef
->
next
=
NULL
;
if
(
0
==
i
)
{
*
nets
=
netDef
;
}
else
{
prevDef
->
next
=
netDef
;
}
prevDef
=
netDef
;
}
free
(
list
);
}
rc
=
numNets
;
parse_complete:
DEBUG
(
"parsed %d nets"
,
rc
);
return
rc
;
}
static
int
lxcParseMountXML
(
virConnectPtr
conn
,
xmlNodePtr
nodePtr
,
lxc_mount_t
*
lxcMount
)
{
xmlChar
*
fsType
=
NULL
;
xmlNodePtr
curNode
;
xmlChar
*
mountSource
=
NULL
;
xmlChar
*
mountTarget
=
NULL
;
int
strLen
;
int
rc
=
-
1
;
fsType
=
xmlGetProp
(
nodePtr
,
BAD_CAST
"type"
);
if
(
NULL
==
fsType
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"missing filesystem type"
));
goto
error
;
}
if
(
xmlStrEqual
(
fsType
,
BAD_CAST
"mount"
)
==
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid filesystem type"
));
goto
error
;
}
for
(
curNode
=
nodePtr
->
children
;
NULL
!=
curNode
;
curNode
=
curNode
->
next
)
{
if
(
curNode
->
type
!=
XML_ELEMENT_NODE
)
{
continue
;
}
if
((
mountSource
==
NULL
)
&&
(
xmlStrEqual
(
curNode
->
name
,
BAD_CAST
"source"
)))
{
mountSource
=
xmlGetProp
(
curNode
,
BAD_CAST
"dir"
);
}
else
if
((
mountTarget
==
NULL
)
&&
(
xmlStrEqual
(
curNode
->
name
,
BAD_CAST
"target"
)))
{
mountTarget
=
xmlGetProp
(
curNode
,
BAD_CAST
"dir"
);
}
}
if
(
mountSource
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"missing mount source"
));
goto
error
;
}
strLen
=
xmlStrlen
(
mountSource
);
if
((
strLen
>
(
PATH_MAX
-
1
))
||
(
0
==
strLen
))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"empty or invalid mount source"
));
goto
error
;
}
strncpy
(
lxcMount
->
source
,
(
char
*
)
mountSource
,
strLen
);
lxcMount
->
source
[
strLen
]
=
'\0'
;
if
(
mountTarget
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"missing mount target"
));
goto
error
;
}
strLen
=
xmlStrlen
(
mountTarget
);
if
((
strLen
>
(
PATH_MAX
-
1
))
||
(
0
==
strLen
))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"empty or invalid mount target"
));
goto
error
;
}
strncpy
(
lxcMount
->
target
,
(
char
*
)
mountTarget
,
strLen
);
lxcMount
->
target
[
strLen
]
=
'\0'
;
rc
=
0
;
error:
xmlFree
(
fsType
);
xmlFree
(
mountSource
);
xmlFree
(
mountTarget
);
return
rc
;
}
static
int
lxcParseDomainName
(
virConnectPtr
conn
,
char
**
name
,
xmlXPathContextPtr
contextPtr
)
{
char
*
res
;
res
=
virXPathString
(
conn
,
"string(/domain/name[1])"
,
contextPtr
);
if
(
res
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_NAME
,
NULL
);
return
(
-
1
);
}
*
name
=
res
;
return
(
0
);
}
static
int
lxcParseDomainUUID
(
virConnectPtr
conn
,
unsigned
char
*
uuid
,
xmlXPathContextPtr
contextPtr
)
{
char
*
res
;
res
=
virXPathString
(
conn
,
"string(/domain/uuid[1])"
,
contextPtr
);
if
(
res
==
NULL
)
{
if
(
virUUIDGenerate
(
uuid
))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to generate uuid"
));
return
(
-
1
);
}
}
else
{
if
(
virUUIDParse
(
res
,
uuid
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid uuid element"
));
VIR_FREE
(
res
);
return
(
-
1
);
}
VIR_FREE
(
res
);
}
return
(
0
);
}
static
int
lxcParseDomainMounts
(
virConnectPtr
conn
,
lxc_mount_t
**
mounts
,
xmlXPathContextPtr
contextPtr
)
{
int
rc
=
-
1
;
int
i
;
lxc_mount_t
*
mountObj
;
lxc_mount_t
*
prevObj
=
NULL
;
int
nmounts
=
0
;
xmlNodePtr
*
list
;
int
res
;
res
=
virXPathNodeSet
(
conn
,
"/domain/devices/filesystem"
,
contextPtr
,
&
list
);
if
(
res
>
0
)
{
for
(
i
=
0
;
i
<
res
;
++
i
)
{
if
(
VIR_ALLOC
(
mountObj
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
"mount"
);
goto
parse_complete
;
}
rc
=
lxcParseMountXML
(
conn
,
list
[
i
],
mountObj
);
if
(
0
>
rc
)
{
VIR_FREE
(
mountObj
);
goto
parse_complete
;
}
/* set the linked list pointers */
nmounts
++
;
mountObj
->
next
=
NULL
;
if
(
0
==
i
)
{
*
mounts
=
mountObj
;
}
else
{
prevObj
->
next
=
mountObj
;
}
prevObj
=
mountObj
;
}
VIR_FREE
(
list
);
}
rc
=
nmounts
;
parse_complete:
return
rc
;
}
static
int
lxcParseDomainInit
(
virConnectPtr
conn
,
char
**
init
,
xmlXPathContextPtr
contextPtr
)
{
char
*
res
;
res
=
virXPathString
(
conn
,
"string(/domain/os/init[1])"
,
contextPtr
);
if
(
res
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid or missing init element"
));
return
(
-
1
);
}
if
(
strlen
(
res
)
>=
PATH_MAX
-
1
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"init string too long"
));
VIR_FREE
(
res
);
return
(
-
1
);
}
*
init
=
res
;
return
(
0
);
}
static
int
lxcParseDomainTty
(
virConnectPtr
conn
,
char
**
tty
,
xmlXPathContextPtr
contextPtr
)
virCapsPtr
lxcCapsInit
(
void
)
{
char
*
res
;
res
=
virXPathString
(
conn
,
"string(/domain/devices/console[1]/@tty)"
,
contextPtr
);
if
(
res
==
NULL
)
{
/* make sure the tty string is empty */
*
tty
=
strdup
(
""
);
if
(
*
tty
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
(
-
1
);
}
}
else
{
*
tty
=
res
;
}
struct
utsname
utsname
;
virCapsPtr
caps
;
virCapsGuestPtr
guest
;
return
(
0
);
}
static
int
lxcParseDomainMemory
(
virConnectPtr
conn
,
int
*
memory
,
xmlXPathContextPtr
contextPtr
)
{
long
res
;
int
rc
;
uname
(
&
utsname
);
rc
=
virXPathLong
(
conn
,
"string(/domain/memory[1])"
,
contextPtr
,
&
res
);
if
((
rc
==
-
2
)
||
((
rc
==
0
)
&&
(
res
<=
0
)))
{
*
memory
=
-
1
;
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid memory value"
));
}
else
if
(
rc
<
0
)
{
/* not an error, default to an invalid value so it's not used */
*
memory
=
-
1
;
}
else
{
*
memory
=
(
int
)
res
;
}
return
(
0
);
}
static
lxc_vm_def_t
*
lxcParseXML
(
virConnectPtr
conn
,
xmlDocPtr
docPtr
)
{
xmlNodePtr
rootNodePtr
=
NULL
;
xmlXPathContextPtr
contextPtr
=
NULL
;
xmlChar
*
xmlProp
=
NULL
;
lxc_vm_def_t
*
containerDef
;
if
(
VIR_ALLOC
(
containerDef
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
"containerDef"
);
return
NULL
;
}
/* Prepare parser / xpath context */
rootNodePtr
=
xmlDocGetRootElement
(
docPtr
);
if
((
rootNodePtr
==
NULL
)
||
(
!
xmlStrEqual
(
rootNodePtr
->
name
,
BAD_CAST
"domain"
)))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid root element"
));
goto
error
;
}
contextPtr
=
xmlXPathNewContext
(
docPtr
);
if
(
contextPtr
==
NULL
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
"context"
);
goto
error
;
}
/* Verify the domain type is linuxcontainer */
if
(
!
(
xmlProp
=
xmlGetProp
(
rootNodePtr
,
BAD_CAST
"type"
)))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"missing domain type"
));
goto
error
;
}
if
(
!
(
xmlStrEqual
(
xmlProp
,
BAD_CAST
LXC_DOMAIN_TYPE
)))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid domain type"
));
goto
error
;
}
VIR_FREE
(
xmlProp
);
if
((
xmlProp
=
xmlGetProp
(
rootNodePtr
,
BAD_CAST
"id"
)))
{
if
(
0
>
virStrToLong_i
((
char
*
)
xmlProp
,
NULL
,
10
,
&
(
containerDef
->
id
)))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid domain id"
));
goto
error
;
}
/* verify the container process still exists */
if
(
1
!=
lxcCheckContainerProcess
(
containerDef
))
{
containerDef
->
id
=
-
1
;
}
}
else
{
containerDef
->
id
=
-
1
;
}
VIR_FREE
(
xmlProp
);
if
(
lxcParseDomainName
(
conn
,
&
(
containerDef
->
name
),
contextPtr
)
<
0
)
{
goto
error
;
}
if
(
lxcParseDomainInit
(
conn
,
&
(
containerDef
->
init
),
contextPtr
)
<
0
)
{
goto
error
;
}
if
(
lxcParseDomainUUID
(
conn
,
containerDef
->
uuid
,
contextPtr
)
<
0
)
{
goto
error
;
}
containerDef
->
nmounts
=
lxcParseDomainMounts
(
conn
,
&
(
containerDef
->
mounts
),
contextPtr
);
if
(
0
>
containerDef
->
nmounts
)
{
goto
error
;
}
containerDef
->
numNets
=
lxcParseDomainInterfaces
(
conn
,
&
(
containerDef
->
nets
),
contextPtr
);
if
(
0
>
containerDef
->
numNets
)
{
goto
error
;
}
if
(
lxcParseDomainTty
(
conn
,
&
(
containerDef
->
tty
),
contextPtr
)
<
0
)
{
goto
error
;
}
if
(
lxcParseDomainMemory
(
conn
,
&
(
containerDef
->
maxMemory
),
contextPtr
)
<
0
)
{
goto
error
;
}
xmlXPathFreeContext
(
contextPtr
);
return
containerDef
;
error:
VIR_FREE
(
xmlProp
);
xmlXPathFreeContext
(
contextPtr
);
lxcFreeVMDef
(
containerDef
);
return
NULL
;
}
lxc_vm_def_t
*
lxcParseVMDef
(
virConnectPtr
conn
,
const
char
*
xmlString
,
const
char
*
fileName
)
{
xmlDocPtr
xml
;
lxc_vm_def_t
*
containerDef
;
xml
=
xmlReadDoc
(
BAD_CAST
xmlString
,
fileName
?
fileName
:
"domain.xml"
,
NULL
,
XML_PARSE_NOENT
|
XML_PARSE_NONET
|
XML_PARSE_NOERROR
|
XML_PARSE_NOWARNING
);
if
(
!
xml
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_XML_ERROR
,
NULL
);
return
NULL
;
}
containerDef
=
lxcParseXML
(
conn
,
xml
);
xmlFreeDoc
(
xml
);
return
containerDef
;
}
lxc_vm_t
*
lxcAssignVMDef
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_def_t
*
def
)
{
lxc_vm_t
*
vm
=
NULL
;
if
((
vm
=
lxcFindVMByName
(
driver
,
def
->
name
)))
{
if
(
!
lxcIsActiveVM
(
vm
))
{
lxcFreeVMDef
(
vm
->
def
);
vm
->
def
=
def
;
}
else
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Can't redefine active VM with name %s"
),
def
->
name
);
return
NULL
;
}
return
vm
;
}
if
(
VIR_ALLOC
(
vm
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
"vm"
);
return
NULL
;
}
vm
->
pid
=
-
1
;
vm
->
def
=
def
;
vm
->
next
=
driver
->
vms
;
driver
->
vms
=
vm
;
if
(
lxcIsActiveVM
(
vm
))
{
vm
->
state
=
VIR_DOMAIN_RUNNING
;
driver
->
nactivevms
++
;
}
else
{
vm
->
state
=
VIR_DOMAIN_SHUTOFF
;
driver
->
ninactivevms
++
;
}
return
vm
;
}
/**
* lxcCheckContainerProcess:
* @def: Ptr to VM definition
*
* Checks if the container process (stored at def->id is running
*
* Returns on success or -1 in case of error
* 0 - no process with id vm->def->id
* 1 - container process exists
* -1 - error
*/
int
lxcCheckContainerProcess
(
lxc_vm_def_t
*
def
)
{
int
rc
=
-
1
;
if
(
1
<
def
->
id
)
{
if
(
-
1
==
kill
(
def
->
id
,
0
))
{
if
(
ESRCH
==
errno
)
{
rc
=
0
;
DEBUG
(
"pid %d no longer exists"
,
def
->
id
);
goto
done
;
}
lxcError
(
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"error checking container process: %d %s"
),
def
->
id
,
strerror
(
errno
));
goto
done
;
}
DEBUG
(
"pid %d still exists"
,
def
->
id
);
rc
=
1
;
goto
done
;
}
rc
=
0
;
done:
return
rc
;
}
void
lxcRemoveInactiveVM
(
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
)
{
lxc_vm_t
*
prevVm
=
NULL
;
lxc_vm_t
*
curVm
;
for
(
curVm
=
driver
->
vms
;
(
curVm
!=
vm
)
&&
(
NULL
!=
curVm
);
curVm
=
curVm
->
next
)
{
prevVm
=
curVm
;
}
if
(
curVm
)
{
if
(
prevVm
)
{
prevVm
->
next
=
curVm
->
next
;
}
else
{
driver
->
vms
=
curVm
->
next
;
}
driver
->
ninactivevms
--
;
}
lxcFreeVM
(
vm
);
}
/* Save a container's config data into a persistent file */
int
lxcSaveConfig
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
,
lxc_vm_def_t
*
def
)
{
int
rc
=
-
1
;
char
*
xmlDef
;
int
fd
=
-
1
;
int
amtToWrite
;
if
(
!
(
xmlDef
=
lxcGenerateXML
(
conn
,
driver
,
vm
,
def
)))
{
return
-
1
;
}
if
((
fd
=
open
(
vm
->
configFile
,
O_WRONLY
|
O_CREAT
|
O_TRUNC
,
S_IRUSR
|
S_IWUSR
))
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot create config file %s: %s"
),
vm
->
configFile
,
strerror
(
errno
));
goto
cleanup
;
}
amtToWrite
=
strlen
(
xmlDef
);
if
(
safewrite
(
fd
,
xmlDef
,
amtToWrite
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot write config file %s: %s"
),
vm
->
configFile
,
strerror
(
errno
));
goto
cleanup
;
}
if
(
close
(
fd
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot save config file %s: %s"
),
vm
->
configFile
,
strerror
(
errno
));
goto
cleanup
;
}
rc
=
0
;
cleanup:
if
(
fd
!=
-
1
)
{
close
(
fd
);
}
VIR_FREE
(
xmlDef
);
return
rc
;
}
int
lxcSaveVMDef
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
,
lxc_vm_def_t
*
def
)
{
int
rc
=
-
1
;
if
(
vm
->
configFile
[
0
]
==
'\0'
)
{
if
((
rc
=
virFileMakePath
(
driver
->
configDir
)))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot create config directory %s: %s"
),
driver
->
configDir
,
strerror
(
rc
));
goto
save_complete
;
}
if
(
virFileBuildPath
(
driver
->
configDir
,
vm
->
def
->
name
,
".xml"
,
vm
->
configFile
,
PATH_MAX
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot construct config file path"
));
goto
save_complete
;
}
strncpy
(
vm
->
configFileBase
,
vm
->
def
->
name
,
PATH_MAX
-
1
);
strncat
(
vm
->
configFileBase
,
".xml"
,
PATH_MAX
-
strlen
(
vm
->
def
->
name
)
-
1
);
}
rc
=
lxcSaveConfig
(
conn
,
driver
,
vm
,
def
);
save_complete:
return
rc
;
}
static
lxc_vm_t
*
lxcLoadConfig
(
lxc_driver_t
*
driver
,
const
char
*
file
,
const
char
*
fullFilePath
,
const
char
*
xmlData
)
{
lxc_vm_def_t
*
containerDef
;
lxc_vm_t
*
vm
;
if
((
caps
=
virCapabilitiesNew
(
utsname
.
machine
,
0
,
0
))
==
NULL
)
goto
no_memory
;
containerDef
=
lxcParseVMDef
(
NULL
,
xmlData
,
file
);
if
(
NULL
==
containerDef
)
{
DEBUG0
(
"Error parsing container config"
);
return
NULL
;
}
if
((
guest
=
virCapabilitiesAddGuest
(
caps
,
"exe"
,
utsname
.
machine
,
sizeof
(
int
)
==
4
?
32
:
8
,
NULL
,
NULL
,
0
,
NULL
))
==
NULL
)
goto
no_memory
;
if
(
!
virFileMatchesNameSuffix
(
file
,
containerDef
->
name
,
".xml"
))
{
DEBUG0
(
"Container name does not match config file name"
);
lxcFreeVMDef
(
containerDef
);
return
NULL
;
}
if
(
virCapabilitiesAddGuestDomain
(
guest
,
"lxc"
,
NULL
,
NULL
,
0
,
NULL
)
==
NULL
)
goto
no_memory
;
return
caps
;
vm
=
lxcAssignVMDef
(
NULL
,
driver
,
containerDef
);
if
(
NULL
==
vm
)
{
DEBUG0
(
"Failed to load container config"
);
lxcFreeVMDef
(
containerDef
);
no_memory:
virCapabilitiesFree
(
caps
);
return
NULL
;
}
strncpy
(
vm
->
configFile
,
fullFilePath
,
PATH_MAX
);
vm
->
configFile
[
PATH_MAX
-
1
]
=
'\0'
;
strncpy
(
vm
->
configFileBase
,
file
,
PATH_MAX
);
vm
->
configFile
[
PATH_MAX
-
1
]
=
'\0'
;
return
vm
;
}
int
lxcLoadDriverConfig
(
lxc_driver_t
*
driver
)
...
...
@@ -853,254 +110,5 @@ no_memory:
return
-
1
;
}
int
lxcLoadContainerConfigFile
(
lxc_driver_t
*
driver
,
const
char
*
file
)
{
int
rc
=
-
1
;
char
tempPath
[
PATH_MAX
];
char
*
xmlData
;
rc
=
virFileBuildPath
(
driver
->
configDir
,
file
,
NULL
,
tempPath
,
PATH_MAX
);
if
(
0
>
rc
)
{
DEBUG0
(
"config file name too long"
);
goto
load_complete
;
}
if
((
rc
=
virFileReadAll
(
tempPath
,
LXC_MAX_XML_LENGTH
,
&
xmlData
))
<
0
)
{
goto
load_complete
;
}
lxcLoadConfig
(
driver
,
file
,
tempPath
,
xmlData
);
VIR_FREE
(
xmlData
);
load_complete:
return
rc
;
}
int
lxcLoadContainerInfo
(
lxc_driver_t
*
driver
)
{
int
rc
=
-
1
;
DIR
*
dir
;
struct
dirent
*
dirEntry
;
if
(
!
(
dir
=
opendir
(
driver
->
configDir
)))
{
if
(
ENOENT
==
errno
)
{
/* no config dir => no containers */
rc
=
0
;
}
else
{
lxcError
(
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to open config directory %s: %s"
),
driver
->
configDir
,
strerror
(
errno
));
}
goto
load_complete
;
}
while
((
dirEntry
=
readdir
(
dir
)))
{
if
(
dirEntry
->
d_name
[
0
]
==
'.'
)
{
continue
;
}
if
(
!
virFileHasSuffix
(
dirEntry
->
d_name
,
".xml"
))
{
continue
;
}
lxcLoadContainerConfigFile
(
driver
,
dirEntry
->
d_name
);
}
closedir
(
dir
);
rc
=
0
;
load_complete:
return
rc
;
}
/* Generate an XML document describing the vm's configuration */
char
*
lxcGenerateXML
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
ATTRIBUTE_UNUSED
,
lxc_vm_t
*
vm
,
lxc_vm_def_t
*
def
)
{
virBuffer
buf
=
VIR_BUFFER_INITIALIZER
;
unsigned
char
*
uuid
;
char
uuidstr
[
VIR_UUID_STRING_BUFLEN
];
lxc_mount_t
*
mount
;
lxc_net_def_t
*
net
;
if
(
lxcIsActiveVM
(
vm
))
virBufferVSprintf
(
&
buf
,
"<domain type='%s' id='%d'>
\n
"
,
LXC_DOMAIN_TYPE
,
vm
->
def
->
id
);
else
virBufferVSprintf
(
&
buf
,
"<domain type='%s'>
\n
"
,
LXC_DOMAIN_TYPE
);
virBufferVSprintf
(
&
buf
,
" <name>%s</name>
\n
"
,
def
->
name
);
uuid
=
def
->
uuid
;
virUUIDFormat
(
uuid
,
uuidstr
);
virBufferVSprintf
(
&
buf
,
" <uuid>%s</uuid>
\n
"
,
uuidstr
);
virBufferAddLit
(
&
buf
,
" <os>
\n
"
);
virBufferVSprintf
(
&
buf
,
" <init>%s</init>
\n
"
,
def
->
init
);
virBufferAddLit
(
&
buf
,
" </os>
\n
"
);
virBufferVSprintf
(
&
buf
,
" <memory>%d</memory>
\n
"
,
def
->
maxMemory
);
virBufferAddLit
(
&
buf
,
" <devices>
\n
"
);
/* loop adding mounts */
for
(
mount
=
def
->
mounts
;
mount
;
mount
=
mount
->
next
)
{
virBufferAddLit
(
&
buf
,
" <filesystem type='mount'>
\n
"
);
virBufferVSprintf
(
&
buf
,
" <source dir='%s'/>
\n
"
,
mount
->
source
);
virBufferVSprintf
(
&
buf
,
" <target dir='%s'/>
\n
"
,
mount
->
target
);
virBufferAddLit
(
&
buf
,
" </filesystem>
\n
"
);
}
/* loop adding nets */
for
(
net
=
def
->
nets
;
net
;
net
=
net
->
next
)
{
if
(
net
->
type
==
LXC_NET_NETWORK
)
{
virBufferAddLit
(
&
buf
,
" <interface type='network'>
\n
"
);
virBufferVSprintf
(
&
buf
,
" <source network='%s'/>
\n
"
,
net
->
txName
);
}
else
{
virBufferAddLit
(
&
buf
,
" <interface type='bridge'>
\n
"
);
virBufferVSprintf
(
&
buf
,
" <source bridge='%s'/>
\n
"
,
net
->
txName
);
}
if
(
NULL
!=
net
->
parentVeth
)
{
virBufferVSprintf
(
&
buf
,
" <target dev='%s'/>
\n
"
,
net
->
parentVeth
);
}
virBufferAddLit
(
&
buf
,
" </interface>
\n
"
);
}
virBufferVSprintf
(
&
buf
,
" <console tty='%s'/>
\n
"
,
def
->
tty
);
virBufferAddLit
(
&
buf
,
" </devices>
\n
"
);
virBufferAddLit
(
&
buf
,
"</domain>
\n
"
);
if
(
virBufferError
(
&
buf
))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
_
(
"allocate buffer"
));
return
NULL
;
}
return
virBufferContentAndReset
(
&
buf
);
}
void
lxcFreeVMDef
(
lxc_vm_def_t
*
vmdef
)
{
lxc_mount_t
*
curMount
;
lxc_mount_t
*
nextMount
;
lxc_net_def_t
*
curNet
;
lxc_net_def_t
*
nextNet
;
if
(
vmdef
==
NULL
)
return
;
curMount
=
vmdef
->
mounts
;
while
(
curMount
)
{
nextMount
=
curMount
->
next
;
VIR_FREE
(
curMount
);
curMount
=
nextMount
;
}
curNet
=
vmdef
->
nets
;
while
(
curNet
)
{
nextNet
=
curNet
->
next
;
VIR_FREE
(
curNet
->
parentVeth
);
VIR_FREE
(
curNet
->
txName
);
VIR_FREE
(
curNet
);
curNet
=
nextNet
;
}
VIR_FREE
(
vmdef
->
name
);
VIR_FREE
(
vmdef
->
init
);
VIR_FREE
(
vmdef
->
tty
);
VIR_FREE
(
vmdef
);
}
void
lxcFreeVMs
(
lxc_vm_t
*
vms
)
{
lxc_vm_t
*
curVm
=
vms
;
lxc_vm_t
*
nextVm
;
while
(
curVm
)
{
nextVm
=
curVm
->
next
;
lxcFreeVM
(
curVm
);
curVm
=
nextVm
;
}
}
void
lxcFreeVM
(
lxc_vm_t
*
vm
)
{
lxcFreeVMDef
(
vm
->
def
);
VIR_FREE
(
vm
);
}
lxc_vm_t
*
lxcFindVMByID
(
const
lxc_driver_t
*
driver
,
int
id
)
{
lxc_vm_t
*
vm
;
for
(
vm
=
driver
->
vms
;
vm
;
vm
=
vm
->
next
)
{
if
(
lxcIsActiveVM
(
vm
)
&&
(
vm
->
def
->
id
==
id
))
{
return
vm
;
}
}
return
NULL
;
}
lxc_vm_t
*
lxcFindVMByUUID
(
const
lxc_driver_t
*
driver
,
const
unsigned
char
*
uuid
)
{
lxc_vm_t
*
vm
;
for
(
vm
=
driver
->
vms
;
vm
;
vm
=
vm
->
next
)
{
if
(
!
memcmp
(
vm
->
def
->
uuid
,
uuid
,
VIR_UUID_BUFLEN
))
{
return
vm
;
}
}
return
NULL
;
}
lxc_vm_t
*
lxcFindVMByName
(
const
lxc_driver_t
*
driver
,
const
char
*
name
)
{
lxc_vm_t
*
vm
;
for
(
vm
=
driver
->
vms
;
vm
;
vm
=
vm
->
next
)
{
if
(
STREQ
(
vm
->
def
->
name
,
name
))
{
return
vm
;
}
}
return
NULL
;
}
int
lxcDeleteConfig
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
ATTRIBUTE_UNUSED
,
const
char
*
configFile
,
const
char
*
name
)
{
if
(
!
configFile
[
0
])
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"no config file for %s"
),
name
);
return
-
1
;
}
if
(
unlink
(
configFile
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot remove config for %s"
),
name
);
return
-
1
;
}
return
0
;
}
#endif
/* WITH_LXC */
src/lxc_conf.h
浏览文件 @
2e7a3736
...
...
@@ -29,130 +29,23 @@
#ifdef WITH_LXC
#include "internal.h"
/* Defines */
#define LXC_MAX_TTY_NAME 32
#define LXC_MAX_XML_LENGTH 16384
#define LXC_MAX_ERROR_LEN 1024
#define LXC_DOMAIN_TYPE "lxc"
/* types of networks for containers */
enum
lxc_net_type
{
LXC_NET_NETWORK
,
LXC_NET_BRIDGE
};
typedef
struct
__lxc_net_def
lxc_net_def_t
;
struct
__lxc_net_def
{
int
type
;
char
*
parentVeth
;
/* veth device in parent namespace */
char
*
txName
;
/* bridge or network name */
lxc_net_def_t
*
next
;
};
typedef
struct
__lxc_mount
lxc_mount_t
;
struct
__lxc_mount
{
char
source
[
PATH_MAX
];
/* user's directory */
char
target
[
PATH_MAX
];
lxc_mount_t
*
next
;
};
typedef
struct
__lxc_vm_def
lxc_vm_def_t
;
struct
__lxc_vm_def
{
unsigned
char
uuid
[
VIR_UUID_BUFLEN
];
char
*
name
;
int
id
;
/* init command string */
char
*
init
;
int
maxMemory
;
/* mounts - list of mount structs */
int
nmounts
;
lxc_mount_t
*
mounts
;
/* tty device */
char
*
tty
;
/* network devices */
int
numNets
;
lxc_net_def_t
*
nets
;
};
typedef
struct
__lxc_vm
lxc_vm_t
;
struct
__lxc_vm
{
int
pid
;
int
state
;
int
monitor
;
char
configFile
[
PATH_MAX
];
char
configFileBase
[
PATH_MAX
];
lxc_vm_def_t
*
def
;
lxc_vm_t
*
next
;
};
#include "domain_conf.h"
#include "capabilities.h"
typedef
struct
__lxc_driver
lxc_driver_t
;
struct
__lxc_driver
{
lxc_vm_t
*
vm
s
;
int
nactivevms
;
int
ninactivevm
s
;
virCapsPtr
cap
s
;
virDomainObjPtr
domain
s
;
char
*
configDir
;
char
*
autostartDir
;
char
*
stateDir
;
char
*
logDir
;
int
have_netns
;
};
/* Types and structs */
/* Inline Functions */
static
inline
int
lxcIsActiveVM
(
lxc_vm_t
*
vm
)
{
return
vm
->
def
->
id
!=
-
1
;
}
/* Function declarations */
lxc_vm_def_t
*
lxcParseVMDef
(
virConnectPtr
conn
,
const
char
*
xmlString
,
const
char
*
fileName
);
int
lxcSaveVMDef
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
,
lxc_vm_def_t
*
def
);
int
lxcLoadDriverConfig
(
lxc_driver_t
*
driver
);
int
lxcSaveConfig
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
,
lxc_vm_def_t
*
def
);
int
lxcLoadContainerInfo
(
lxc_driver_t
*
driver
);
int
lxcLoadContainerConfigFile
(
lxc_driver_t
*
driver
,
const
char
*
file
);
lxc_vm_t
*
lxcAssignVMDef
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_def_t
*
def
);
char
*
lxcGenerateXML
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
,
lxc_vm_def_t
*
def
);
lxc_vm_t
*
lxcFindVMByID
(
const
lxc_driver_t
*
driver
,
int
id
);
lxc_vm_t
*
lxcFindVMByUUID
(
const
lxc_driver_t
*
driver
,
const
unsigned
char
*
uuid
);
lxc_vm_t
*
lxcFindVMByName
(
const
lxc_driver_t
*
driver
,
const
char
*
name
);
int
lxcCheckContainerProcess
(
lxc_vm_def_t
*
vm
);
void
lxcRemoveInactiveVM
(
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
);
void
lxcFreeVMs
(
lxc_vm_t
*
vms
);
void
lxcFreeVM
(
lxc_vm_t
*
vm
);
void
lxcFreeVMDef
(
lxc_vm_def_t
*
vmdef
);
int
lxcDeleteConfig
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
const
char
*
configFile
,
const
char
*
name
);
virCapsPtr
lxcCapsInit
(
void
);
void
lxcError
(
virConnectPtr
conn
,
virDomainPtr
dom
,
...
...
src/lxc_container.c
浏览文件 @
2e7a3736
...
...
@@ -68,7 +68,7 @@ typedef char lxc_message_t;
typedef
struct
__lxc_child_argv
lxc_child_argv_t
;
struct
__lxc_child_argv
{
lxc_vm_def_t
*
config
;
virDomainDefPtr
config
;
unsigned
int
nveths
;
char
**
veths
;
int
monitor
;
...
...
@@ -85,10 +85,10 @@ struct __lxc_child_argv {
*
* Does not return
*/
static
int
lxcContainerExecInit
(
const
lxc_vm_def_t
*
vmDef
)
static
int
lxcContainerExecInit
(
virDomainDefPtr
vmDef
)
{
const
char
*
const
argv
[]
=
{
vmDef
->
init
,
vmDef
->
os
.
init
,
NULL
,
};
...
...
@@ -269,8 +269,8 @@ static int lxcContainerChild( void *data )
{
int
rc
=
-
1
;
lxc_child_argv_t
*
argv
=
data
;
lxc_vm_def_t
*
vmDef
=
argv
->
config
;
lxc_mount_t
*
curMount
;
virDomainDefPtr
vmDef
=
argv
->
config
;
virDomainFSDefPtr
curMount
;
int
i
;
if
(
NULL
==
vmDef
)
{
...
...
@@ -281,17 +281,20 @@ static int lxcContainerChild( void *data )
/* handle the bind mounts first before doing anything else that may */
/* then access those mounted dirs */
curMount
=
vmDef
->
mount
s
;
curMount
=
vmDef
->
fs
s
;
for
(
i
=
0
;
curMount
;
curMount
=
curMount
->
next
)
{
rc
=
mount
(
curMount
->
source
,
curMount
->
target
,
// XXX fix
if
(
curMount
->
type
!=
VIR_DOMAIN_FS_TYPE_MOUNT
)
continue
;
rc
=
mount
(
curMount
->
src
,
curMount
->
dst
,
NULL
,
MS_BIND
,
NULL
);
if
(
0
!=
rc
)
{
lxcError
(
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to mount %s at %s for container: %s"
),
curMount
->
s
ource
,
curMount
->
targe
t
,
strerror
(
errno
));
curMount
->
s
rc
,
curMount
->
ds
t
,
strerror
(
errno
));
return
-
1
;
}
}
...
...
@@ -329,7 +332,7 @@ static int lxcContainerChild( void *data )
*
* Returns PID of container on success or -1 in case of error
*/
int
lxcContainerStart
(
lxc_vm_def_t
*
def
,
int
lxcContainerStart
(
virDomainDefPtr
def
,
unsigned
int
nveths
,
char
**
veths
,
int
control
,
...
...
src/lxc_container.h
浏览文件 @
2e7a3736
...
...
@@ -34,7 +34,7 @@ enum {
int
lxcContainerSendContinue
(
int
control
);
int
lxcContainerStart
(
lxc_vm_def_t
*
def
,
int
lxcContainerStart
(
virDomainDefPtr
def
,
unsigned
int
nveths
,
char
**
veths
,
int
control
,
...
...
src/lxc_controller.c
浏览文件 @
2e7a3736
...
...
@@ -306,7 +306,7 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths,
static
int
lxcControllerRun
(
const
char
*
stateDir
,
lxc_vm_def_t
*
def
,
virDomainDefPtr
def
,
unsigned
int
nveths
,
char
**
veths
,
int
monitor
,
...
...
@@ -368,7 +368,7 @@ cleanup:
int
lxcControllerStart
(
const
char
*
stateDir
,
lxc_vm_def_t
*
def
,
virDomainDefPtr
def
,
unsigned
int
nveths
,
char
**
veths
,
int
monitor
,
...
...
src/lxc_controller.h
浏览文件 @
2e7a3736
...
...
@@ -29,7 +29,7 @@
#include "lxc_conf.h"
int
lxcControllerStart
(
const
char
*
stateDir
,
lxc_vm_def_t
*
def
,
virDomainDefPtr
def
,
unsigned
int
nveths
,
char
**
veths
,
int
monitor
,
...
...
src/lxc_driver.c
浏览文件 @
2e7a3736
...
...
@@ -37,7 +37,6 @@
#include <unistd.h>
#include <wait.h>
#include "internal.h"
#include "lxc_conf.h"
#include "lxc_container.h"
#include "lxc_driver.h"
...
...
@@ -111,7 +110,7 @@ static virDomainPtr lxcDomainLookupByID(virConnectPtr conn,
int
id
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByID
(
driver
,
id
);
virDomainObjPtr
vm
=
virDomainFindByID
(
driver
->
domains
,
id
);
virDomainPtr
dom
;
if
(
!
vm
)
{
...
...
@@ -131,7 +130,7 @@ static virDomainPtr lxcDomainLookupByUUID(virConnectPtr conn,
const
unsigned
char
*
uuid
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByUUID
(
driver
,
uuid
);
virDomainObjPtr
vm
=
virDomainFindByUUID
(
driver
->
domains
,
uuid
);
virDomainPtr
dom
;
if
(
!
vm
)
{
...
...
@@ -151,7 +150,7 @@ static virDomainPtr lxcDomainLookupByName(virConnectPtr conn,
const
char
*
name
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByName
(
driver
,
name
);
virDomainObjPtr
vm
=
virDomainFindByName
(
driver
->
domains
,
name
);
virDomainPtr
dom
;
if
(
!
vm
)
{
...
...
@@ -167,90 +166,96 @@ static virDomainPtr lxcDomainLookupByName(virConnectPtr conn,
return
dom
;
}
static
int
lxcListDomains
(
virConnectPtr
conn
,
int
*
ids
,
int
nids
)
{
static
int
lxcListDomains
(
virConnectPtr
conn
,
int
*
ids
,
int
nids
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
lxc_vm_t
*
vm
;
int
numDoms
=
0
;
for
(
vm
=
driver
->
vms
;
vm
&&
(
numDoms
<
nids
);
vm
=
vm
->
next
)
{
if
(
lxcIsActiveVM
(
vm
))
{
ids
[
numDoms
]
=
vm
->
def
->
id
;
numDoms
++
;
virDomainObjPtr
vm
=
driver
->
domains
;
int
got
=
0
;
while
(
vm
&&
got
<
nids
)
{
if
(
virDomainIsActive
(
vm
))
{
ids
[
got
]
=
vm
->
def
->
id
;
got
++
;
}
vm
=
vm
->
next
;
}
return
numDoms
;
return
got
;
}
static
int
lxcNumDomains
(
virConnectPtr
conn
)
{
static
int
lxcNumDomains
(
virConnectPtr
conn
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
return
driver
->
nactivevms
;
int
n
=
0
;
virDomainObjPtr
dom
=
driver
->
domains
;
while
(
dom
)
{
if
(
virDomainIsActive
(
dom
))
n
++
;
dom
=
dom
->
next
;
}
return
n
;
}
static
int
lxcListDefinedDomains
(
virConnectPtr
conn
,
char
**
const
names
,
int
nnames
)
{
char
**
const
names
,
int
nnames
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
lxc_vm_t
*
vm
;
int
numDoms
=
0
;
int
i
;
for
(
vm
=
driver
->
vms
;
vm
&&
(
numDoms
<
nnames
);
vm
=
vm
->
next
)
{
if
(
!
lxcIsActiveVM
(
vm
))
{
if
(
!
(
names
[
numDoms
]
=
strdup
(
vm
->
def
->
name
)))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
"names"
);
virDomainObjPtr
vm
=
driver
->
domains
;
int
got
=
0
,
i
;
while
(
vm
&&
got
<
nnames
)
{
if
(
!
virDomainIsActive
(
vm
))
{
if
(
!
(
names
[
got
]
=
strdup
(
vm
->
def
->
name
)))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
goto
cleanup
;
}
numDoms
++
;
got
++
;
}
vm
=
vm
->
next
;
}
return
numDoms
;
return
got
;
cleanup:
for
(
i
=
0
;
i
<
numDoms
;
i
++
)
{
for
(
i
=
0
;
i
<
got
;
i
++
)
VIR_FREE
(
names
[
i
]);
}
return
-
1
;
}
static
int
lxcNumDefinedDomains
(
virConnectPtr
conn
)
{
static
int
lxcNumDefinedDomains
(
virConnectPtr
conn
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
return
driver
->
ninactivevms
;
int
n
=
0
;
virDomainObjPtr
dom
=
driver
->
domains
;
while
(
dom
)
{
if
(
!
virDomainIsActive
(
dom
))
n
++
;
dom
=
dom
->
next
;
}
return
n
;
}
static
virDomainPtr
lxcDomainDefine
(
virConnectPtr
conn
,
const
char
*
xml
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
lxc_vm_def_t
*
def
;
lxc_vm_t
*
vm
;
virDomainDefPtr
def
;
virDomainObjPtr
vm
;
virDomainPtr
dom
;
if
(
!
(
def
=
lxcParseVMDef
(
conn
,
xml
,
NULL
)))
{
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
return
NULL
;
}
if
((
def
->
nets
!=
NULL
)
&&
!
(
driver
->
have_netns
))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_SUPPORT
,
_
(
"System lacks NETNS support"
));
lxcFreeVMDef
(
def
);
virDomainDefFree
(
def
);
return
NULL
;
}
if
(
!
(
vm
=
lxcAssignVMDef
(
conn
,
driver
,
def
)))
{
lxcFreeVMDef
(
def
);
if
(
!
(
vm
=
virDomainAssignDef
(
conn
,
&
driver
->
domains
,
def
)))
{
virDomainDefFree
(
def
);
return
NULL
;
}
if
(
lxcSaveVMDef
(
conn
,
driver
,
vm
,
def
)
<
0
)
{
lxcRemoveInactiveVM
(
driver
,
vm
);
if
(
virDomainSaveConfig
(
conn
,
driver
->
configDir
,
driver
->
autostartDir
,
vm
)
<
0
)
{
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
return
NULL
;
}
...
...
@@ -265,7 +270,7 @@ static virDomainPtr lxcDomainDefine(virConnectPtr conn, const char *xml)
static
int
lxcDomainUndefine
(
virDomainPtr
dom
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
dom
->
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByUUID
(
driver
,
dom
->
uuid
);
virDomainObjPtr
vm
=
virDomainFindByUUID
(
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
lxcError
(
dom
->
conn
,
dom
,
VIR_ERR_INVALID_DOMAIN
,
...
...
@@ -273,19 +278,18 @@ static int lxcDomainUndefine(virDomainPtr dom)
return
-
1
;
}
if
(
lxcIsActiveVM
(
vm
))
{
if
(
virDomainIsActive
(
vm
))
{
lxcError
(
dom
->
conn
,
dom
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot delete active domain"
));
return
-
1
;
}
if
(
lxcDeleteConfig
(
dom
->
conn
,
driver
,
vm
->
configFile
,
vm
->
def
->
name
)
<
0
)
{
if
(
virDomainDeleteConfig
(
dom
->
conn
,
vm
)
<
0
)
return
-
1
;
}
vm
->
configFile
[
0
]
=
'\0'
;
lxcRemoveInactiveVM
(
driver
,
vm
);
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
return
0
;
}
...
...
@@ -294,7 +298,7 @@ static int lxcDomainGetInfo(virDomainPtr dom,
virDomainInfoPtr
info
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
dom
->
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByUUID
(
driver
,
dom
->
uuid
);
virDomainObjPtr
vm
=
virDomainFindByUUID
(
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
lxcError
(
dom
->
conn
,
dom
,
VIR_ERR_INVALID_DOMAIN
,
...
...
@@ -304,30 +308,38 @@ static int lxcDomainGetInfo(virDomainPtr dom,
info
->
state
=
vm
->
state
;
if
(
!
lxcIsActiveVM
(
vm
))
{
if
(
!
virDomainIsActive
(
vm
))
{
info
->
cpuTime
=
0
;
}
else
{
info
->
cpuTime
=
0
;
}
info
->
maxMem
=
vm
->
def
->
max
Memory
;
info
->
memory
=
vm
->
def
->
m
axM
emory
;
info
->
maxMem
=
vm
->
def
->
max
mem
;
info
->
memory
=
vm
->
def
->
memory
;
info
->
nrVirtCpu
=
1
;
return
0
;
}
static
char
*
lxcGetOSType
(
virDomainPtr
dom
ATTRIBUTE_UNUSED
)
static
char
*
lxcGetOSType
(
virDomainPtr
dom
)
{
/* Linux containers only run on Linux */
return
strdup
(
"linux"
);
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
dom
->
conn
->
privateData
;
virDomainObjPtr
vm
=
virDomainFindByUUID
(
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
lxcError
(
dom
->
conn
,
dom
,
VIR_ERR_INVALID_DOMAIN
,
_
(
"no domain with matching uuid"
));
return
NULL
;
}
return
strdup
(
vm
->
def
->
os
.
type
);
}
static
char
*
lxcDomainDumpXML
(
virDomainPtr
dom
,
int
flags
ATTRIBUTE_UNUSED
)
int
flags
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
dom
->
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByUUID
(
driver
,
dom
->
uuid
);
virDomainObjPtr
vm
=
virDomainFindByUUID
(
driver
->
domains
,
dom
->
uuid
);
if
(
!
vm
)
{
lxcError
(
dom
->
conn
,
dom
,
VIR_ERR_INVALID_DOMAIN
,
...
...
@@ -335,7 +347,10 @@ static char *lxcDomainDumpXML(virDomainPtr dom,
return
NULL
;
}
return
lxcGenerateXML
(
dom
->
conn
,
driver
,
vm
,
vm
->
def
);
return
virDomainDefFormat
(
dom
->
conn
,
(
flags
&
VIR_DOMAIN_XML_INACTIVE
)
&&
vm
->
newDef
?
vm
->
newDef
:
vm
->
def
,
flags
);
}
...
...
@@ -351,7 +366,7 @@ static char *lxcDomainDumpXML(virDomainPtr dom,
*/
static
int
lxcVMCleanup
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
)
virDomainObjPtr
vm
)
{
int
rc
=
-
1
;
int
waitRc
;
...
...
@@ -383,8 +398,6 @@ static int lxcVMCleanup(virConnectPtr conn,
vm
->
pid
=
-
1
;
vm
->
def
->
id
=
-
1
;
vm
->
monitor
=
-
1
;
driver
->
nactivevms
--
;
driver
->
ninactivevms
++
;
return
rc
;
}
...
...
@@ -400,12 +413,12 @@ static int lxcVMCleanup(virConnectPtr conn,
* Returns 0 on success or -1 in case of error
*/
static
int
lxcSetupInterfaces
(
virConnectPtr
conn
,
lxc_vm_def_t
*
def
,
virDomainDefPtr
def
,
unsigned
int
*
nveths
,
char
***
veths
)
{
int
rc
=
-
1
;
lxc_net_def_t
*
net
;
virDomainNetDefPtr
net
;
char
*
bridge
=
NULL
;
char
parentVeth
[
PATH_MAX
]
=
""
;
char
containerVeth
[
PATH_MAX
]
=
""
;
...
...
@@ -415,8 +428,11 @@ static int lxcSetupInterfaces(virConnectPtr conn,
return
-
1
;
for
(
net
=
def
->
nets
;
net
;
net
=
net
->
next
)
{
if
(
LXC_NET_NETWORK
==
net
->
type
)
{
virNetworkPtr
network
=
virNetworkLookupByName
(
conn
,
net
->
txName
);
switch
(
net
->
type
)
{
case
VIR_DOMAIN_NET_TYPE_NETWORK
:
{
virNetworkPtr
network
=
virNetworkLookupByName
(
conn
,
net
->
data
.
network
.
name
);
if
(
!
network
)
{
goto
error_exit
;
}
...
...
@@ -424,8 +440,11 @@ static int lxcSetupInterfaces(virConnectPtr conn,
bridge
=
virNetworkGetBridgeName
(
network
);
virNetworkFree
(
network
);
}
else
{
bridge
=
net
->
txName
;
break
;
}
case
VIR_DOMAIN_NET_TYPE_BRIDGE
:
bridge
=
net
->
data
.
bridge
.
brname
;
break
;
}
DEBUG
(
"bridge: %s"
,
bridge
);
...
...
@@ -436,8 +455,8 @@ static int lxcSetupInterfaces(virConnectPtr conn,
}
DEBUG0
(
"calling vethCreate()"
);
if
(
NULL
!=
net
->
parentVeth
)
{
strcpy
(
parentVeth
,
net
->
parentVeth
);
if
(
NULL
!=
net
->
ifname
)
{
strcpy
(
parentVeth
,
net
->
ifname
);
}
DEBUG
(
"parentVeth: %s, containerVeth: %s"
,
parentVeth
,
containerVeth
);
if
(
0
!=
(
rc
=
vethCreate
(
parentVeth
,
PATH_MAX
,
containerVeth
,
PATH_MAX
)))
{
...
...
@@ -445,15 +464,15 @@ static int lxcSetupInterfaces(virConnectPtr conn,
_
(
"failed to create veth device pair: %d"
),
rc
);
goto
error_exit
;
}
if
(
NULL
==
net
->
parentVeth
)
{
net
->
parentVeth
=
strdup
(
parentVeth
);
if
(
NULL
==
net
->
ifname
)
{
net
->
ifname
=
strdup
(
parentVeth
);
}
if
(
VIR_REALLOC_N
(
*
veths
,
(
*
nveths
)
+
1
)
<
0
)
goto
error_exit
;
if
(((
*
veths
)[(
*
nveths
)
++
]
=
strdup
(
containerVeth
))
==
NULL
)
goto
error_exit
;
if
(
NULL
==
net
->
parentVeth
)
{
if
(
NULL
==
net
->
ifname
)
{
lxcError
(
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to allocate veth names"
));
goto
error_exit
;
...
...
@@ -485,7 +504,7 @@ error_exit:
static
int
lxcMonitorServer
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
)
virDomainObjPtr
vm
)
{
char
*
sockpath
=
NULL
;
int
fd
;
...
...
@@ -535,7 +554,7 @@ error:
static
int
lxcMonitorClient
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
)
virDomainObjPtr
vm
)
{
char
*
sockpath
=
NULL
;
int
fd
;
...
...
@@ -578,7 +597,7 @@ error:
static
int
lxcVmTerminate
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
,
virDomainObjPtr
vm
,
int
signum
)
{
if
(
signum
==
0
)
...
...
@@ -603,7 +622,7 @@ static void lxcMonitorEvent(int fd,
void
*
data
)
{
lxc_driver_t
*
driver
=
data
;
lxc_vm_t
*
vm
=
driver
->
vm
s
;
virDomainObjPtr
vm
=
driver
->
domain
s
;
while
(
vm
)
{
if
(
vm
->
monitor
==
fd
)
...
...
@@ -632,12 +651,13 @@ static void lxcMonitorEvent(int fd,
*/
static
int
lxcVmStart
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
lxc_vm_t
*
vm
)
virDomainObjPtr
vm
)
{
int
rc
=
-
1
;
unsigned
int
i
;
int
monitor
;
int
parentTty
;
char
*
parentTtyPath
=
NULL
;
char
*
logfile
=
NULL
;
int
logfd
=
-
1
;
unsigned
int
nveths
=
0
;
...
...
@@ -660,13 +680,19 @@ static int lxcVmStart(virConnectPtr conn,
goto
cleanup
;
/* open parent tty */
VIR_FREE
(
vm
->
def
->
tty
);
if
(
virFileOpenTty
(
&
parentTty
,
&
vm
->
def
->
tty
,
1
)
<
0
)
{
if
(
virFileOpenTty
(
&
parentTty
,
&
parentTtyPath
,
1
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to allocate tty: %s"
),
strerror
(
errno
));
goto
cleanup
;
}
if
(
vm
->
def
->
console
&&
vm
->
def
->
console
->
type
==
VIR_DOMAIN_CHR_TYPE_PTY
)
{
VIR_FREE
(
vm
->
def
->
console
->
data
.
file
.
path
);
vm
->
def
->
console
->
data
.
file
.
path
=
parentTtyPath
;
}
else
{
VIR_FREE
(
parentTtyPath
);
}
if
(
lxcSetupInterfaces
(
conn
,
vm
->
def
,
&
nveths
,
&
veths
)
!=
0
)
goto
cleanup
;
...
...
@@ -705,8 +731,6 @@ static int lxcVmStart(virConnectPtr conn,
vm
->
def
->
id
=
vm
->
pid
;
vm
->
state
=
VIR_DOMAIN_RUNNING
;
driver
->
ninactivevms
--
;
driver
->
nactivevms
++
;
if
(
virEventAddHandle
(
vm
->
monitor
,
POLLERR
|
POLLHUP
,
...
...
@@ -751,7 +775,7 @@ static int lxcDomainStart(virDomainPtr dom)
int
rc
=
-
1
;
virConnectPtr
conn
=
dom
->
conn
;
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)(
conn
->
privateData
);
lxc_vm_t
*
vm
=
lxcFindVMByName
(
driver
,
dom
->
name
);
virDomainObjPtr
vm
=
virDomainFindByName
(
driver
->
domains
,
dom
->
name
);
if
(
!
vm
)
{
lxcError
(
conn
,
dom
,
VIR_ERR_INVALID_DOMAIN
,
...
...
@@ -759,6 +783,12 @@ static int lxcDomainStart(virDomainPtr dom)
goto
cleanup
;
}
if
((
vm
->
def
->
nets
!=
NULL
)
&&
!
(
driver
->
have_netns
))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_SUPPORT
,
_
(
"System lacks NETNS support"
));
goto
cleanup
;
}
rc
=
lxcVmStart
(
conn
,
driver
,
vm
);
cleanup:
...
...
@@ -780,26 +810,28 @@ lxcDomainCreateAndStart(virConnectPtr conn,
const
char
*
xml
,
unsigned
int
flags
ATTRIBUTE_UNUSED
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
conn
->
privateData
;
lxc_vm_t
*
vm
;
lxc_vm_def_t
*
def
;
virDomainObjPtr
vm
;
virDomainDefPtr
def
;
virDomainPtr
dom
=
NULL
;
if
(
!
(
def
=
lxcParseVMDef
(
conn
,
xml
,
NULL
)))
{
if
(
!
(
def
=
virDomainDefParseString
(
conn
,
driver
->
caps
,
xml
)))
goto
return_point
;
}
if
(
!
(
vm
=
lxcAssignVMDef
(
conn
,
driver
,
def
)))
{
lxcFreeVMDef
(
def
);
if
((
def
->
nets
!=
NULL
)
&&
!
(
driver
->
have_netns
))
{
virDomainDefFree
(
def
);
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_SUPPORT
,
_
(
"System lacks NETNS support"
));
goto
return_point
;
}
if
(
lxcSaveVMDef
(
conn
,
driver
,
vm
,
def
)
<
0
)
{
lxcRemoveInactiveVM
(
driver
,
vm
);
return
NULL
;
if
(
!
(
vm
=
virDomainAssignDef
(
conn
,
&
driver
->
domains
,
def
)))
{
virDomainDefFree
(
def
);
goto
return_point
;
}
if
(
lxcVmStart
(
conn
,
driver
,
vm
)
<
0
)
{
lxcRemoveInactiveVM
(
driver
,
vm
);
virDomainRemoveInactive
(
&
driver
->
domains
,
vm
);
goto
return_point
;
}
...
...
@@ -823,7 +855,7 @@ return_point:
static
int
lxcDomainShutdown
(
virDomainPtr
dom
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
dom
->
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByID
(
driver
,
dom
->
id
);
virDomainObjPtr
vm
=
virDomainFindByID
(
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
lxcError
(
dom
->
conn
,
dom
,
VIR_ERR_INVALID_DOMAIN
,
...
...
@@ -846,7 +878,7 @@ static int lxcDomainShutdown(virDomainPtr dom)
static
int
lxcDomainDestroy
(
virDomainPtr
dom
)
{
lxc_driver_t
*
driver
=
(
lxc_driver_t
*
)
dom
->
conn
->
privateData
;
lxc_vm_t
*
vm
=
lxcFindVMByID
(
driver
,
dom
->
id
);
virDomainObjPtr
vm
=
virDomainFindByID
(
driver
->
domains
,
dom
->
id
);
if
(
!
vm
)
{
lxcError
(
dom
->
conn
,
dom
,
VIR_ERR_INVALID_DOMAIN
,
...
...
@@ -875,7 +907,7 @@ static int lxcCheckNetNsSupport(void)
static
int
lxcStartup
(
void
)
{
uid_t
uid
=
getuid
();
lxc_vm_t
*
vm
;
virDomainObjPtr
vm
;
/* Check that the user is root */
if
(
0
!=
uid
)
{
...
...
@@ -898,13 +930,21 @@ static int lxcStartup(void)
return
-
1
;
}
/* Call function to load the container configuration files */
if
(
lxcLoadContainerInfo
(
lxc_driver
)
<
0
)
{
if
((
lxc_driver
->
caps
=
lxcCapsInit
())
==
NULL
)
{
lxcShutdown
();
return
-
1
;
}
if
(
virDomainLoadAllConfigs
(
NULL
,
lxc_driver
->
caps
,
&
lxc_driver
->
domains
,
lxc_driver
->
configDir
,
lxc_driver
->
autostartDir
)
<
0
)
{
lxcShutdown
();
return
-
1
;
}
vm
=
lxc_driver
->
vm
s
;
vm
=
lxc_driver
->
domain
s
;
while
(
vm
)
{
int
rc
;
if
((
vm
->
monitor
=
lxcMonitorClient
(
NULL
,
lxc_driver
,
vm
))
<
0
)
{
...
...
@@ -923,8 +963,6 @@ static int lxcStartup(void)
if
(
vm
->
pid
!=
0
)
{
vm
->
def
->
id
=
vm
->
pid
;
vm
->
state
=
VIR_DOMAIN_RUNNING
;
lxc_driver
->
ninactivevms
--
;
lxc_driver
->
nactivevms
++
;
}
else
{
vm
->
def
->
id
=
-
1
;
close
(
vm
->
monitor
);
...
...
@@ -940,6 +978,7 @@ static int lxcStartup(void)
static
void
lxcFreeDriver
(
lxc_driver_t
*
driver
)
{
VIR_FREE
(
driver
->
configDir
);
VIR_FREE
(
driver
->
autostartDir
);
VIR_FREE
(
driver
->
stateDir
);
VIR_FREE
(
driver
->
logDir
);
VIR_FREE
(
driver
);
...
...
@@ -947,10 +986,15 @@ static void lxcFreeDriver(lxc_driver_t *driver)
static
int
lxcShutdown
(
void
)
{
virDomainObjPtr
vm
;
if
(
lxc_driver
==
NULL
)
return
(
-
1
);
lxcFreeVMs
(
lxc_driver
->
vms
);
lxc_driver
->
vms
=
NULL
;
vm
=
lxc_driver
->
domains
;
while
(
vm
)
{
virDomainObjPtr
next
=
vm
->
next
;
virDomainObjFree
(
vm
);
vm
=
next
;
}
lxcFreeDriver
(
lxc_driver
);
lxc_driver
=
NULL
;
...
...
@@ -966,13 +1010,17 @@ static int lxcShutdown(void)
*/
static
int
lxcActive
(
void
)
{
virDomainObjPtr
dom
;
if
(
lxc_driver
==
NULL
)
return
(
0
);
/* If we've any active networks or guests, then we
* mark this driver as active
*/
if
(
lxc_driver
->
nactivevms
)
dom
=
lxc_driver
->
domains
;
while
(
dom
)
{
if
(
virDomainIsActive
(
dom
)
)
return
1
;
dom
=
dom
->
next
;
}
/* Otherwise we're happy to deal with a shutdown */
return
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录