Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
177c74b1
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看板
提交
177c74b1
编写于
8月 20, 2008
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Create lxc_controller standalone binary
上级
bb16f4a2
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
372 addition
and
186 deletion
+372
-186
ChangeLog
ChangeLog
+9
-0
src/Makefile.am
src/Makefile.am
+24
-2
src/domain_conf.c
src/domain_conf.c
+2
-4
src/lxc_conf.c
src/lxc_conf.c
+4
-4
src/lxc_conf.h
src/lxc_conf.h
+4
-0
src/lxc_controller.c
src/lxc_controller.c
+201
-113
src/lxc_driver.c
src/lxc_driver.c
+128
-63
未找到文件。
ChangeLog
浏览文件 @
177c74b1
Wed Aug 20 21:50:09 BST 2008 Daniel P. Berrange <berrange@redhat.com>
* src/domain_conf.c: Include PTY name if available
* src/Makefile.am: Add lxc_controller binary
* src/lxc_conf.c, src/lxc_conf.h, src/lxc_controller.c,
src/lxc_controller.h, src/lxc_driver.c: Move LXC controller
into a properly exec'd binary, instead of fork'd child of
libvirtd daemon
Wed Aug 20 21:05:09 BST 2008 Daniel P. Berrange <berrange@redhat.com>
* configure.in, qemud/Makefile.am, src/Makefile.am: Use automake
...
...
src/Makefile.am
浏览文件 @
177c74b1
...
...
@@ -88,10 +88,15 @@ XEN_DRIVER_SOURCES = \
LXC_DRIVER_SOURCES
=
\
lxc_conf.c lxc_conf.h
\
lxc_container.c lxc_container.h
\
lxc_controller.c lxc_controller.h
\
lxc_driver.c lxc_driver.h
\
veth.c veth.h
LXC_CONTROLLER_SOURCES
=
\
lxc_conf.c lxc_conf.h
\
lxc_container.c lxc_container.h
\
lxc_controller.c
\
veth.c veth.h
OPENVZ_DRIVER_SOURCES
=
\
openvz_conf.c openvz_conf.h
\
openvz_driver.c openvz_driver.h
...
...
@@ -272,9 +277,11 @@ virsh-pool-edit.c: virsh.c Makefile.am
rm
-f
$@
mv
$@
-tmp
$@
libexec_PROGRAMS
=
if
WITH_STORAGE_DISK
if
WITH_LIBVIRTD
libexec_PROGRAMS
=
libvirt_parthelper
libexec_PROGRAMS
+
=
libvirt_parthelper
libvirt_parthelper_SOURCES
=
$(STORAGE_HELPER_DISK_SOURCES)
libvirt_parthelper_LDFLAGS
=
$(WARN_CFLAGS)
$(COVERAGE_LDCFLAGS)
...
...
@@ -285,6 +292,21 @@ endif
EXTRA_DIST
+=
$(STORAGE_HELPER_DISK_SOURCES)
if
WITH_LXC
if
WITH_LIBVIRTD
libexec_PROGRAMS
+=
libvirt_lxc
libvirt_lxc_SOURCES
=
\
$(LXC_CONTROLLER_SOURCES)
\
$(GENERIC_LIB_SOURCES)
\
$(DOMAIN_CONF_SOURCES)
libvirt_lxc_LDFLAGS
=
$(WARN_CFLAGS)
$(COVERAGE_LDCFLAGS)
libvirt_lxc_LDADD
=
$(LIBXML_LIBS)
../gnulib/lib/libgnu.la
libvirt_lxc_CFLAGS
=
$(LIBPARTED_CFLAGS)
endif
endif
EXTRA_DIST
+=
$(LXC_CONTROLLER_SOURCES)
# Create the /var/cache/libvirt directory when installing.
install-exec-local
:
$(MKDIR_P)
$(DESTDIR)$(localstatedir)
/cache/libvirt
...
...
src/domain_conf.c
浏览文件 @
177c74b1
...
...
@@ -1109,13 +1109,11 @@ virDomainChrDefParseXML(virConnectPtr conn,
break
;
case
VIR_DOMAIN_CHR_TYPE_PTY
:
/* @path attribute is an output only property - pty is auto-allocted */
break
;
case
VIR_DOMAIN_CHR_TYPE_DEV
:
case
VIR_DOMAIN_CHR_TYPE_FILE
:
case
VIR_DOMAIN_CHR_TYPE_PIPE
:
if
(
path
==
NULL
)
{
if
(
path
==
NULL
&&
def
->
type
!=
VIR_DOMAIN_CHR_TYPE_PTY
)
{
virDomainReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"Missing source path attribute for char device"
));
goto
error
;
...
...
src/lxc_conf.c
浏览文件 @
177c74b1
...
...
@@ -71,7 +71,7 @@ virCapsPtr lxcCapsInit(void)
"exe"
,
utsname
.
machine
,
sizeof
(
int
)
==
4
?
32
:
8
,
NULL
,
BINDIR
"/libvirt_lxc"
,
NULL
,
0
,
NULL
))
==
NULL
)
...
...
@@ -94,11 +94,11 @@ no_memory:
int
lxcLoadDriverConfig
(
lxc_driver_t
*
driver
)
{
/* Set the container configuration directory */
if
((
driver
->
configDir
=
strdup
(
SYSCONF_DIR
"/libvirt/lxc"
))
==
NULL
)
if
((
driver
->
configDir
=
strdup
(
LXC_CONFIG_DIR
))
==
NULL
)
goto
no_memory
;
if
((
driver
->
stateDir
=
strdup
(
L
OCAL_STATE_DIR
"/run/libvirt/lxc"
))
==
NULL
)
if
((
driver
->
stateDir
=
strdup
(
L
XC_STATE_DIR
))
==
NULL
)
goto
no_memory
;
if
((
driver
->
logDir
=
strdup
(
L
OCAL_STATE_DIR
"/log/libvirt/lxc"
))
==
NULL
)
if
((
driver
->
logDir
=
strdup
(
L
XC_LOG_DIR
))
==
NULL
)
goto
no_memory
;
return
0
;
...
...
src/lxc_conf.h
浏览文件 @
177c74b1
...
...
@@ -30,6 +30,10 @@
#include "domain_conf.h"
#include "capabilities.h"
#define LXC_CONFIG_DIR SYSCONF_DIR "/libvirt/lxc"
#define LXC_STATE_DIR LOCAL_STATE_DIR "/run/libvirt/lxc"
#define LXC_LOG_DIR LOCAL_STATE_DIR "/log/libvirt/lxc"
typedef
struct
__lxc_driver
lxc_driver_t
;
struct
__lxc_driver
{
virCapsPtr
caps
;
...
...
src/lxc_controller.c
浏览文件 @
177c74b1
...
...
@@ -23,22 +23,22 @@
#include <config.h>
#ifdef WITH_LXC
#include <sys/epoll.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <paths.h>
#include <fcntl.h>
#include <signal.h>
#include <getopt.h>
#include "internal.h"
#include "util.h"
#include "lxc_conf.h"
#include "lxc_container.h"
#include "lxc_controller.h"
#include "veth.h"
#include "memory.h"
#include "util.h"
...
...
@@ -47,6 +47,56 @@
#define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__)
#define DEBUG0(msg) VIR_DEBUG(__FILE__, "%s", msg)
int
debugFlag
=
0
;
static
char
*
lxcMonitorPath
(
virDomainDefPtr
def
)
{
char
*
sockpath
;
if
(
asprintf
(
&
sockpath
,
"%s/%s.sock"
,
LXC_STATE_DIR
,
def
->
name
)
<
0
)
{
lxcError
(
NULL
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
NULL
;
}
return
sockpath
;
}
static
int
lxcMonitorServer
(
const
char
*
sockpath
)
{
int
fd
;
struct
sockaddr_un
addr
;
if
((
fd
=
socket
(
PF_UNIX
,
SOCK_STREAM
,
0
))
<
0
)
{
lxcError
(
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to create server socket %s: %s"
),
sockpath
,
strerror
(
errno
));
goto
error
;
}
unlink
(
sockpath
);
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sun_family
=
AF_UNIX
;
strncpy
(
addr
.
sun_path
,
sockpath
,
sizeof
(
addr
.
sun_path
));
if
(
bind
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
<
0
)
{
lxcError
(
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to bind server socket %s: %s"
),
sockpath
,
strerror
(
errno
));
goto
error
;
}
if
(
listen
(
fd
,
30
/* backlog */
)
<
0
)
{
lxcError
(
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to listen server socket %s: %s"
),
sockpath
,
strerror
(
errno
));
goto
error
;
}
return
fd
;
error:
if
(
fd
!=
-
1
)
close
(
fd
);
return
-
1
;
}
/**
* lxcFdForward:
...
...
@@ -305,8 +355,7 @@ static int lxcControllerCleanupInterfaces(unsigned int nveths,
static
int
lxcControllerRun
(
const
char
*
stateDir
,
virDomainDefPtr
def
,
lxcControllerRun
(
virDomainDefPtr
def
,
unsigned
int
nveths
,
char
**
veths
,
int
monitor
,
...
...
@@ -359,148 +408,187 @@ cleanup:
if
(
containerPty
!=
-
1
)
close
(
containerPty
);
kill
(
container
,
SIGTERM
);
waitpid
(
container
,
NULL
,
0
);
lxcControllerCleanupInterfaces
(
nveths
,
veths
);
virFileDeletePid
(
stateDir
,
def
->
name
);
if
(
container
>
1
)
{
kill
(
container
,
SIGTERM
);
waitpid
(
container
,
NULL
,
0
);
}
return
rc
;
}
int
lxcControllerStart
(
const
char
*
stateDir
,
virDomainDefPtr
def
,
unsigned
int
nveths
,
char
**
veths
,
int
monitor
,
int
appPty
,
int
logfd
)
int
main
(
int
argc
,
char
*
argv
[])
{
pid_t
pid
;
int
rc
;
int
status
,
null
;
int
open_max
,
i
;
int
rc
=
1
;
int
client
;
struct
sigaction
sig_action
;
char
*
name
=
NULL
;
int
nveths
=
0
;
char
**
veths
=
NULL
;
int
monitor
=
-
1
;
int
appPty
=
-
1
;
int
bg
=
0
;
virCapsPtr
caps
=
NULL
;
virDomainDefPtr
def
=
NULL
;
int
nnets
=
0
;
virDomainNetDefPtr
nets
=
NULL
;
char
*
configFile
=
NULL
;
char
*
sockpath
=
NULL
;
const
struct
option
const
options
[]
=
{
{
"background"
,
0
,
NULL
,
'b'
},
{
"name"
,
1
,
NULL
,
'n'
},
{
"veth"
,
1
,
NULL
,
'v'
},
{
"console"
,
1
,
NULL
,
'c'
},
{
"help"
,
0
,
NULL
,
'h'
},
{
0
,
0
,
0
,
0
},
};
if
((
pid
=
fork
())
<
0
)
return
-
1
;
while
(
1
)
{
int
c
;
if
(
pid
>
0
)
{
/* Original caller waits for first child to exit */
while
(
1
)
{
rc
=
waitpid
(
pid
,
&
status
,
0
);
if
(
rc
<
0
)
{
if
(
errno
==
EINTR
)
continue
;
return
-
1
;
c
=
getopt_long
(
argc
,
argv
,
"dn:v:m:c:h"
,
options
,
NULL
);
if
(
c
==
-
1
)
break
;
switch
(
c
)
{
case
'b'
:
bg
=
1
;
break
;
case
'n'
:
if
((
name
=
strdup
(
optarg
))
==
NULL
)
{
fprintf
(
stderr
,
"%s"
,
strerror
(
errno
));
goto
cleanup
;
}
if
(
rc
!=
pid
)
{
fprintf
(
stderr
,
_
(
"Unexpected pid %d != %d from waitpid
\n
"
),
rc
,
pid
);
return
-
1
;
break
;
case
'v'
:
if
(
VIR_REALLOC_N
(
veths
,
nveths
+
1
)
<
0
)
{
fprintf
(
stderr
,
"cannot allocate veths %s"
,
strerror
(
errno
));
goto
cleanup
;
}
if
(
WIFEXITED
(
status
)
&&
WEXITSTATUS
(
status
)
==
0
)
return
0
;
else
{
fprintf
(
stderr
,
_
(
"Unexpected status %d from pid %d
\n
"
),
status
,
pid
);
return
-
1
;
if
((
veths
[
nveths
++
]
=
strdup
(
optarg
))
==
NULL
)
{
fprintf
(
stderr
,
"cannot allocate veth name %s"
,
strerror
(
errno
));
goto
cleanup
;
}
break
;
case
'c'
:
if
(
virStrToLong_i
(
optarg
,
NULL
,
10
,
&
appPty
)
<
0
)
{
fprintf
(
stderr
,
"malformed --console argument '%s'"
,
optarg
);
goto
cleanup
;
}
break
;
case
'h'
:
case
'?'
:
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
"syntax: %s [OPTIONS]
\n
"
,
argv
[
0
]);
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
"Options
\n
"
);
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
" -b, --background
\n
"
);
fprintf
(
stderr
,
" -n NAME, --name NAME
\n
"
);
fprintf
(
stderr
,
" -c FD, --console FD
\n
"
);
fprintf
(
stderr
,
" -v VETH, --veth VETH
\n
"
);
fprintf
(
stderr
,
" -h, --help
\n
"
);
fprintf
(
stderr
,
"
\n
"
);
goto
cleanup
;
}
}
/* First child is running here */
/* Clobber all libvirtd's signal handlers so they
* don't affect us
*/
sig_action
.
sa_handler
=
SIG_DFL
;
sig_action
.
sa_flags
=
0
;
sigemptyset
(
&
sig_action
.
sa_mask
);
if
(
name
==
NULL
)
{
fprintf
(
stderr
,
"%s: missing --name argument for configuration
\n
"
,
argv
[
0
]);
goto
cleanup
;
}
if
(
appPty
<
0
)
{
fprintf
(
stderr
,
"%s: missing --console argument for container PTY
\n
"
,
argv
[
0
]);
goto
cleanup
;
}
if
(
getuid
()
&&
0
)
{
fprintf
(
stderr
,
"%s: must be run as the 'root' user
\n
"
,
argv
[
0
]);
goto
cleanup
;
}
sigaction
(
SIGHUP
,
&
sig_action
,
NULL
);
sigaction
(
SIGINT
,
&
sig_action
,
NULL
);
sigaction
(
SIGQUIT
,
&
sig_action
,
NULL
);
sigaction
(
SIGTERM
,
&
sig_action
,
NULL
);
sigaction
(
SIGCHLD
,
&
sig_action
,
NULL
);
if
((
caps
=
lxcCapsInit
())
==
NULL
)
goto
cleanup
;
sig_action
.
sa_handler
=
SIG_IGN
;
sigaction
(
SIGPIPE
,
&
sig_action
,
NULL
);
if
((
configFile
=
virDomainConfigFile
(
NULL
,
LXC_STATE_DIR
,
name
))
==
NULL
)
goto
cleanup
;
if
((
def
=
virDomainDefParseFile
(
NULL
,
caps
,
configFile
))
==
NULL
)
goto
cleanup
;
/* Don't hold onto any cwd we inherit from libvirtd either */
if
(
chdir
(
"/"
)
<
0
)
{
fprintf
(
stderr
,
_
(
"Unable to change to root dir: %s
\n
"
),
strerror
(
errno
));
_exit
(
-
1
);
nets
=
def
->
nets
;
while
(
nets
)
{
nnets
++
;
nets
=
nets
->
next
;
}
if
(
setsid
()
<
0
)
{
fprintf
(
stderr
,
_
(
"Unable to become session leader: %s
\n
"
),
strerror
(
errno
));
_exit
(
-
1
);
if
(
nnets
!=
nveths
)
{
fprintf
(
stderr
,
"%s: expecting %d veths, but got %d
\n
"
,
argv
[
0
],
nnets
,
nveths
);
goto
cleanup
;
}
if
((
null
=
open
(
_PATH_DEVNULL
,
O_RDONLY
))
<
0
)
{
fprintf
(
stderr
,
_
(
"Unable to open %s: %s
\n
"
),
_PATH_DEVNULL
,
strerror
(
errno
));
_exit
(
-
1
);
}
if
((
sockpath
=
lxcMonitorPath
(
def
))
==
NULL
)
goto
cleanup
;
open_max
=
sysconf
(
_SC_OPEN_MAX
);
for
(
i
=
0
;
i
<
open_max
;
i
++
)
if
(
i
!=
appPty
&&
i
!=
monitor
&&
i
!=
logfd
&&
i
!=
null
)
close
(
i
);
if
(
dup2
(
null
,
STDIN_FILENO
)
<
0
||
dup2
(
logfd
,
STDOUT_FILENO
)
<
0
||
dup2
(
logfd
,
STDERR_FILENO
)
<
0
)
{
fprintf
(
stderr
,
_
(
"Unable to redirect stdio: %s
\n
"
),
strerror
(
errno
));
_exit
(
-
1
);
}
if
((
monitor
=
lxcMonitorServer
(
sockpath
))
<
0
)
goto
cleanup
;
close
(
null
);
close
(
logfd
);
if
(
bg
)
{
if
((
pid
=
fork
())
<
0
)
goto
cleanup
;
/* Now fork the real controller process */
if
((
pid
=
fork
())
<
0
)
{
fprintf
(
stderr
,
_
(
"Unable to fork controller
: %s
\n
"
),
strerror
(
errno
));
_exit
(
-
1
);
}
if
(
pid
>
0
)
{
if
((
rc
=
virFileWritePid
(
LXC_STATE_DIR
,
name
,
pid
))
!=
0
)
{
fprintf
(
stderr
,
_
(
"Unable to write pid file
: %s
\n
"
),
strerror
(
rc
));
_exit
(
1
);
}
if
(
pid
>
0
)
{
if
((
rc
=
virFileWritePid
(
stateDir
,
def
->
name
,
pid
))
!=
0
)
{
fprintf
(
stderr
,
_
(
"Unable to write pid file: %s
\n
"
),
strerror
(
rc
));
_exit
(
-
1
);
/* First child now exits, allowing original caller
* (ie libvirtd's LXC driver to complete their
* waitpid & continue */
_exit
(
0
);
}
/* First child now exits, allowing originall caller to
* complete their waitpid & continue */
_exit
(
0
);
}
/* This is real controller running finally... */
/* Don't hold onto any cwd we inherit from libvirtd either */
if
(
chdir
(
"/"
)
<
0
)
{
fprintf
(
stderr
,
_
(
"Unable to change to root dir: %s
\n
"
),
strerror
(
errno
));
goto
cleanup
;
}
if
(
setsid
()
<
0
)
{
fprintf
(
stderr
,
_
(
"Unable to become session leader: %s
\n
"
),
strerror
(
errno
));
goto
cleanup
;
}
}
/* Accept initial client which is the libvirtd daemon */
if
((
client
=
accept
(
monitor
,
NULL
,
0
)))
{
if
((
client
=
accept
(
monitor
,
NULL
,
0
))
<
0
)
{
fprintf
(
stderr
,
_
(
"Failed connection from LXC driver: %s
\n
"
),
strerror
(
errno
));
_exit
(
-
1
)
;
goto
cleanup
;
}
/* Controlling libvirtd LXC driver now knows
what our PID is, and is able to cleanup after
us from now on */
_exit
(
lxcControllerRun
(
stateDir
,
def
,
nveths
,
veths
,
monitor
,
client
,
appPty
));
}
rc
=
lxcControllerRun
(
def
,
nveths
,
veths
,
monitor
,
client
,
appPty
);
#endif
cleanup:
virFileDeletePid
(
LXC_STATE_DIR
,
def
->
name
);
lxcControllerCleanupInterfaces
(
nveths
,
veths
);
unlink
(
sockpath
);
VIR_FREE
(
sockpath
);
return
rc
;
}
src/lxc_driver.c
浏览文件 @
177c74b1
...
...
@@ -38,7 +38,6 @@
#include "lxc_conf.h"
#include "lxc_container.h"
#include "lxc_driver.h"
#include "lxc_controller.h"
#include "memory.h"
#include "util.h"
#include "bridge.h"
...
...
@@ -398,6 +397,7 @@ static int lxcVMCleanup(virConnectPtr conn,
close
(
vm
->
monitor
);
virFileDeletePid
(
driver
->
stateDir
,
vm
->
def
->
name
);
virDomainDeleteConfig
(
conn
,
driver
->
stateDir
,
NULL
,
vm
);
vm
->
state
=
VIR_DOMAIN_SHUTOFF
;
vm
->
pid
=
-
1
;
...
...
@@ -507,55 +507,6 @@ error_exit:
return
rc
;
}
static
int
lxcMonitorServer
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
virDomainObjPtr
vm
)
{
char
*
sockpath
=
NULL
;
int
fd
;
struct
sockaddr_un
addr
;
if
(
asprintf
(
&
sockpath
,
"%s/%s.sock"
,
driver
->
stateDir
,
vm
->
def
->
name
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
return
-
1
;
}
if
((
fd
=
socket
(
PF_UNIX
,
SOCK_STREAM
,
0
))
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to create server socket: %s"
),
strerror
(
errno
));
goto
error
;
}
unlink
(
sockpath
);
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sun_family
=
AF_UNIX
;
strncpy
(
addr
.
sun_path
,
sockpath
,
sizeof
(
addr
.
sun_path
));
if
(
bind
(
fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to bind server socket: %s"
),
strerror
(
errno
));
goto
error
;
}
if
(
listen
(
fd
,
30
/* backlog */
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to listen server socket: %s"
),
strerror
(
errno
));
goto
error
;
return
(
-
1
);
}
VIR_FREE
(
sockpath
);
return
fd
;
error:
VIR_FREE
(
sockpath
);
if
(
fd
!=
-
1
)
close
(
fd
);
return
-
1
;
}
static
int
lxcMonitorClient
(
virConnectPtr
conn
,
lxc_driver_t
*
driver
,
...
...
@@ -608,6 +559,12 @@ static int lxcVmTerminate(virConnectPtr conn,
if
(
signum
==
0
)
signum
=
SIGINT
;
if
(
vm
->
pid
<=
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"invalid PID %d for container"
),
vm
->
pid
);
return
-
1
;
}
if
(
kill
(
vm
->
pid
,
signum
)
<
0
)
{
if
(
errno
!=
ESRCH
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
...
...
@@ -644,6 +601,102 @@ static void lxcMonitorEvent(int fd,
}
static
int
lxcControllerStart
(
virConnectPtr
conn
,
virDomainObjPtr
vm
,
int
nveths
,
char
**
veths
,
int
appPty
,
int
logfd
)
{
int
i
;
int
rc
;
int
ret
=
-
1
;
int
largc
=
0
,
larga
=
0
;
const
char
**
largv
=
NULL
;
pid_t
child
;
int
status
;
#define ADD_ARG_SPACE \
do { \
if (largc == larga) { \
larga += 10; \
if (VIR_REALLOC_N(largv, larga) < 0) \
goto no_memory; \
} \
} while (0)
#define ADD_ARG(thisarg) \
do { \
ADD_ARG_SPACE; \
largv[largc++] = thisarg; \
} while (0)
#define ADD_ARG_LIT(thisarg) \
do { \
ADD_ARG_SPACE; \
if ((largv[largc++] = strdup(thisarg)) == NULL) \
goto no_memory; \
} while (0)
ADD_ARG_LIT
(
vm
->
def
->
emulator
);
ADD_ARG_LIT
(
"--name"
);
ADD_ARG_LIT
(
vm
->
def
->
name
);
ADD_ARG_LIT
(
"--console"
);
ADD_ARG_LIT
(
"0"
);
/* Passing console master PTY as FD 0 */
ADD_ARG_LIT
(
"--background"
);
for
(
i
=
0
;
i
<
nveths
;
i
++
)
{
ADD_ARG_LIT
(
"--veth"
);
ADD_ARG_LIT
(
veths
[
i
]);
}
ADD_ARG
(
NULL
);
vm
->
stdin_fd
=
appPty
;
/* Passing console master PTY as FD 0 */
vm
->
stdout_fd
=
vm
->
stderr_fd
=
logfd
;
if
(
virExec
(
conn
,
largv
,
NULL
,
&
child
,
vm
->
stdin_fd
,
&
vm
->
stdout_fd
,
&
vm
->
stderr_fd
,
VIR_EXEC_NONE
)
<
0
)
goto
cleanup
;
/* We now wait for the process to exit - the controller
* will fork() itself into the background - waiting for
* it to exit thus guarentees it has written its pidfile
*/
while
((
rc
=
waitpid
(
child
,
&
status
,
0
)
==
-
1
)
&&
errno
==
EINTR
);
if
(
rc
==
-
1
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot wait for '%s': %s"
),
largv
[
0
],
strerror
(
errno
));
goto
cleanup
;
}
if
(
!
(
WIFEXITED
(
status
)
&&
WEXITSTATUS
(
status
)
==
0
))
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"container '%s' unexpectedly shutdown during startup"
),
largv
[
0
]);
goto
cleanup
;
}
#undef ADD_ARG
#undef ADD_ARG_LIT
#undef ADD_ARG_SPACE
ret
=
0
;
cleanup:
for
(
i
=
0
;
i
<
largc
;
i
++
)
VIR_FREE
(
largv
[
i
]);
return
ret
;
no_memory:
lxcError
(
conn
,
NULL
,
VIR_ERR_NO_MEMORY
,
NULL
);
goto
cleanup
;
}
/**
* lxcVmStart:
* @conn: pointer to connection
...
...
@@ -660,7 +713,6 @@ static int lxcVmStart(virConnectPtr conn,
{
int
rc
=
-
1
;
unsigned
int
i
;
int
monitor
;
int
parentTty
;
char
*
parentTtyPath
=
NULL
;
char
*
logfile
=
NULL
;
...
...
@@ -681,9 +733,6 @@ static int lxcVmStart(virConnectPtr conn,
return
-
1
;
}
if
((
monitor
=
lxcMonitorServer
(
conn
,
driver
,
vm
))
<
0
)
goto
cleanup
;
/* open parent tty */
if
(
virFileOpenTty
(
&
parentTty
,
&
parentTtyPath
,
1
)
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
...
...
@@ -702,6 +751,12 @@ static int lxcVmStart(virConnectPtr conn,
if
(
lxcSetupInterfaces
(
conn
,
vm
->
def
,
&
nveths
,
&
veths
)
!=
0
)
goto
cleanup
;
/* Persist the live configuration now we have veth & tty info */
if
(
virDomainSaveConfig
(
conn
,
driver
->
stateDir
,
vm
->
def
)
<
0
)
{
rc
=
-
1
;
goto
cleanup
;
}
if
((
logfd
=
open
(
logfile
,
O_WRONLY
|
O_TRUNC
|
O_CREAT
,
S_IRUSR
|
S_IWUSR
))
<
0
)
{
lxcError
(
conn
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
...
...
@@ -710,14 +765,11 @@ static int lxcVmStart(virConnectPtr conn,
goto
cleanup
;
}
if
(
lxcControllerStart
(
driver
->
stateDir
,
vm
->
def
,
nveths
,
veths
,
monitor
,
parentTty
,
logfd
)
<
0
)
if
(
lxcControllerStart
(
conn
,
vm
,
nveths
,
veths
,
parentTty
,
logfd
)
<
0
)
goto
cleanup
;
/* Close the server side of the monitor, now owned
* by the controller process */
close
(
monitor
);
monitor
=
-
1
;
/* Connect to the controller as a client *first* because
* this will block until the child has written their
...
...
@@ -753,8 +805,6 @@ cleanup:
vethDelete
(
veths
[
i
]);
VIR_FREE
(
veths
[
i
]);
}
if
(
monitor
!=
-
1
)
close
(
monitor
);
if
(
rc
!=
0
&&
vm
->
monitor
!=
-
1
)
{
close
(
vm
->
monitor
);
vm
->
monitor
=
-
1
;
...
...
@@ -951,6 +1001,8 @@ static int lxcStartup(void)
vm
=
lxc_driver
->
domains
;
while
(
vm
)
{
char
*
config
=
NULL
;
virDomainDefPtr
tmp
;
int
rc
;
if
((
vm
->
monitor
=
lxcMonitorClient
(
NULL
,
lxc_driver
,
vm
))
<
0
)
{
vm
=
vm
->
next
;
...
...
@@ -965,6 +1017,19 @@ static int lxcStartup(void)
continue
;
}
if
((
config
=
virDomainConfigFile
(
NULL
,
lxc_driver
->
stateDir
,
vm
->
def
->
name
))
==
NULL
)
continue
;
/* Try and load the live config */
tmp
=
virDomainDefParseFile
(
NULL
,
lxc_driver
->
caps
,
config
);
VIR_FREE
(
config
);
if
(
tmp
)
{
vm
->
newDef
=
vm
->
def
;
vm
->
def
=
tmp
;
}
if
(
vm
->
pid
!=
0
)
{
vm
->
def
->
id
=
vm
->
pid
;
vm
->
state
=
VIR_DOMAIN_RUNNING
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录