Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
74f04141
Commit
74f04141
authored
Jun 13, 2017
by
Serge Hallyn
Committed by
GitHub
Jun 13, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1618 from brauner/2017-06-06/kill_lxc_monitord
start: kill lxc-monitord
parents
46d9789c
d0ab6d91
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
439 additions
and
201 deletions
+439
-201
commands.c
src/lxc/commands.c
+170
-9
commands.h
src/lxc/commands.h
+4
-1
conf.c
src/lxc/conf.c
+5
-1
criu.c
src/lxc/criu.c
+4
-1
execute.c
src/lxc/execute.c
+7
-8
lxc.h
src/lxc/lxc.h
+5
-3
lxccontainer.c
src/lxc/lxccontainer.c
+48
-19
start.c
src/lxc/start.c
+133
-26
start.h
src/lxc/start.h
+17
-13
state.c
src/lxc/state.c
+10
-79
state.h
src/lxc/state.h
+9
-2
lxc_execute.c
src/lxc/tools/lxc_execute.c
+25
-37
lxc-test-apparmor-mount
src/tests/lxc-test-apparmor-mount
+1
-1
lxc-test-unpriv
src/tests/lxc-test-unpriv
+1
-1
No files found.
src/lxc/commands.c
View file @
74f04141
...
@@ -43,7 +43,9 @@
...
@@ -43,7 +43,9 @@
#include "commands.h"
#include "commands.h"
#include "console.h"
#include "console.h"
#include "confile.h"
#include "confile.h"
#include "lxclock.h"
#include "mainloop.h"
#include "mainloop.h"
#include "monitor.h"
#include "af_unix.h"
#include "af_unix.h"
#include "config.h"
#include "config.h"
...
@@ -142,6 +144,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
...
@@ -142,6 +144,7 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd)
[
LXC_CMD_GET_CONFIG_ITEM
]
=
"get_config_item"
,
[
LXC_CMD_GET_CONFIG_ITEM
]
=
"get_config_item"
,
[
LXC_CMD_GET_NAME
]
=
"get_name"
,
[
LXC_CMD_GET_NAME
]
=
"get_name"
,
[
LXC_CMD_GET_LXCPATH
]
=
"get_lxcpath"
,
[
LXC_CMD_GET_LXCPATH
]
=
"get_lxcpath"
,
[
LXC_CMD_STATE_SERVER
]
=
"state_server"
,
};
};
if
(
cmd
>=
LXC_CMD_MAX
)
if
(
cmd
>=
LXC_CMD_MAX
)
...
@@ -283,7 +286,11 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
...
@@ -283,7 +286,11 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
char
path
[
sizeof
(((
struct
sockaddr_un
*
)
0
)
->
sun_path
)]
=
{
0
};
char
path
[
sizeof
(((
struct
sockaddr_un
*
)
0
)
->
sun_path
)]
=
{
0
};
char
*
offset
=
&
path
[
1
];
char
*
offset
=
&
path
[
1
];
size_t
len
;
size_t
len
;
int
stay_connected
=
cmd
->
req
.
cmd
==
LXC_CMD_CONSOLE
;
bool
stay_connected
=
false
;
if
(
cmd
->
req
.
cmd
==
LXC_CMD_CONSOLE
||
cmd
->
req
.
cmd
==
LXC_CMD_STATE_SERVER
)
stay_connected
=
true
;
*
stopped
=
0
;
*
stopped
=
0
;
...
@@ -297,12 +304,20 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
...
@@ -297,12 +304,20 @@ static int lxc_cmd(const char *name, struct lxc_cmd_rr *cmd, int *stopped,
return
-
1
;
return
-
1
;
sock
=
lxc_abstract_unix_connect
(
path
);
sock
=
lxc_abstract_unix_connect
(
path
);
TRACE
(
"command %s tries to connect to
\"
@%s
\"
"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
offset
);
if
(
sock
<
0
)
{
if
(
sock
<
0
)
{
if
(
errno
==
ECONNREFUSED
)
if
(
errno
==
ECONNREFUSED
)
{
TRACE
(
"command %s failed to connect to
\"
@%s
\"
: %s"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
offset
,
strerror
(
errno
));
*
stopped
=
1
;
*
stopped
=
1
;
else
}
else
{
SYSERROR
(
"Command %s failed to connect to
\"
@%s
\"
."
,
SYSERROR
(
"command %s failed to connect to
\"
@%s
\"
: %s"
,
lxc_cmd_str
(
cmd
->
req
.
cmd
),
offset
);
lxc_cmd_str
(
cmd
->
req
.
cmd
),
offset
,
strerror
(
errno
));
}
return
-
1
;
return
-
1
;
}
}
...
@@ -462,20 +477,26 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
...
@@ -462,20 +477,26 @@ char *lxc_cmd_get_cgroup_path(const char *name, const char *lxcpath,
};
};
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
ret
<
0
)
if
(
ret
<
0
)
{
TRACE
(
"command %s failed for container
\"
%s
\"
: %s."
,
lxc_cmd_str
(
cmd
.
req
.
cmd
),
name
,
strerror
(
errno
));
return
NULL
;
return
NULL
;
}
if
(
!
ret
)
{
if
(
!
ret
)
{
WARN
(
"
Container
\"
%s
\"
has stopped before sending its state.
"
,
name
);
WARN
(
"
container
\"
%s
\"
has stopped before sending its state
"
,
name
);
return
NULL
;
return
NULL
;
}
}
if
(
cmd
.
rsp
.
ret
<
0
||
cmd
.
rsp
.
datalen
<
0
)
{
if
(
cmd
.
rsp
.
ret
<
0
||
cmd
.
rsp
.
datalen
<
0
)
{
ERROR
(
"
Command %s failed for container
\"
%s
\"
: %s.
"
,
ERROR
(
"
command %s failed for container
\"
%s
\"
: %s
"
,
lxc_cmd_str
(
cmd
.
req
.
cmd
),
name
,
strerror
(
-
cmd
.
rsp
.
ret
));
lxc_cmd_str
(
cmd
.
req
.
cmd
),
name
,
strerror
(
-
cmd
.
rsp
.
ret
));
return
NULL
;
return
NULL
;
}
}
TRACE
(
"command %s successful for container
\"
%s
\"
"
,
lxc_cmd_str
(
cmd
.
req
.
cmd
),
name
);
return
cmd
.
rsp
.
data
;
return
cmd
.
rsp
.
data
;
}
}
...
@@ -567,7 +588,7 @@ out:
...
@@ -567,7 +588,7 @@ out:
*
*
* Returns the state on success, < 0 on failure
* Returns the state on success, < 0 on failure
*/
*/
lxc_state_
t
lxc_cmd_get_state
(
const
char
*
name
,
const
char
*
lxcpath
)
in
t
lxc_cmd_get_state
(
const
char
*
name
,
const
char
*
lxcpath
)
{
{
int
ret
,
stopped
;
int
ret
,
stopped
;
struct
lxc_cmd_rr
cmd
=
{
struct
lxc_cmd_rr
cmd
=
{
...
@@ -847,6 +868,145 @@ static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
...
@@ -847,6 +868,145 @@ static int lxc_cmd_get_lxcpath_callback(int fd, struct lxc_cmd_req *req,
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
}
/*
* lxc_cmd_state_server: register a client fd in the handler list
*
* @name : name of container to connect to
* @lxcpath : the lxcpath in which the container is running
*
* Returns the lxcpath on success, NULL on failure.
*/
int
lxc_cmd_state_server
(
const
char
*
name
,
const
char
*
lxcpath
,
lxc_state_t
states
[
MAX_STATE
])
{
int
stopped
;
ssize_t
ret
;
int
state
=
-
1
;
struct
lxc_msg
msg
=
{
0
};
struct
lxc_cmd_rr
cmd
=
{
.
req
=
{
.
cmd
=
LXC_CMD_STATE_SERVER
,
.
data
=
states
,
.
datalen
=
(
sizeof
(
lxc_state_t
)
*
MAX_STATE
)
},
};
/* Lock the whole lxc_cmd_state_server_callback() call to ensure that
* lxc_set_state() doesn't cause us to miss a state.
*/
process_lock
();
/* Check if already in requested state. */
state
=
lxc_getstate
(
name
,
lxcpath
);
if
(
state
<
0
)
{
process_unlock
();
TRACE
(
"failed to retrieve state of container: %s"
,
strerror
(
errno
));
return
-
1
;
}
else
if
(
states
[
state
])
{
process_unlock
();
TRACE
(
"container is %s state"
,
lxc_state2str
(
state
));
return
state
;
}
if
((
state
==
STARTING
)
&&
!
states
[
RUNNING
]
&&
!
states
[
STOPPING
]
&&
!
states
[
STOPPED
])
{
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
"informed about a previous state"
,
lxc_state2str
(
state
));
return
state
;
}
else
if
((
state
==
RUNNING
)
&&
!
states
[
STOPPING
]
&&
!
states
[
STOPPED
])
{
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
"informed about a previous state"
,
lxc_state2str
(
state
));
return
state
;
}
else
if
((
state
==
STOPPING
)
&&
!
states
[
STOPPED
])
{
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
"informed about a previous state"
,
lxc_state2str
(
state
));
return
state
;
}
else
if
((
state
==
STOPPED
)
||
(
state
==
ABORTING
))
{
process_unlock
();
TRACE
(
"container is in %s state and caller requested to be "
"informed about a previous state"
,
lxc_state2str
(
state
));
return
state
;
}
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
process_unlock
();
if
(
ret
<
0
)
{
ERROR
(
"failed to execute command: %s"
,
strerror
(
errno
));
return
-
1
;
}
/* We should now be guaranteed to get an answer from the state sending
* function.
*/
if
(
cmd
.
rsp
.
ret
<
0
)
{
ERROR
(
"failed to receive socket fd"
);
return
-
1
;
}
again:
ret
=
recv
(
cmd
.
rsp
.
ret
,
&
msg
,
sizeof
(
msg
),
0
);
if
(
ret
<
0
)
{
if
(
errno
==
EINTR
)
goto
again
;
ERROR
(
"failed to receive message: %s"
,
strerror
(
errno
));
return
-
1
;
}
if
(
ret
==
0
)
{
ERROR
(
"length of message was 0"
);
return
-
1
;
}
TRACE
(
"received state %s from state client %d"
,
lxc_state2str
(
msg
.
value
),
cmd
.
rsp
.
ret
);
return
msg
.
value
;
}
static
int
lxc_cmd_state_server_callback
(
int
fd
,
struct
lxc_cmd_req
*
req
,
struct
lxc_handler
*
handler
)
{
struct
lxc_cmd_rsp
rsp
=
{
0
};
struct
state_client
*
newclient
;
struct
lxc_list
*
tmplist
;
if
(
req
->
datalen
<
0
)
{
TRACE
(
"requested datalen was < 0"
);
return
-
1
;
}
if
(
!
req
->
data
)
{
TRACE
(
"no states requested"
);
return
-
1
;
}
newclient
=
malloc
(
sizeof
(
*
newclient
));
if
(
!
newclient
)
return
-
1
;
/* copy requested states */
memcpy
(
newclient
->
states
,
req
->
data
,
sizeof
(
newclient
->
states
));
newclient
->
clientfd
=
fd
;
tmplist
=
malloc
(
sizeof
(
*
tmplist
));
if
(
!
tmplist
)
{
free
(
newclient
);
return
-
1
;
}
lxc_list_add_elem
(
tmplist
,
newclient
);
lxc_list_add_tail
(
&
handler
->
state_clients
,
tmplist
);
TRACE
(
"added state client %d to state client list"
,
fd
);
return
lxc_cmd_rsp_send
(
fd
,
&
rsp
);
}
static
int
lxc_cmd_process
(
int
fd
,
struct
lxc_cmd_req
*
req
,
static
int
lxc_cmd_process
(
int
fd
,
struct
lxc_cmd_req
*
req
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
...
@@ -863,6 +1023,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
...
@@ -863,6 +1023,7 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req,
[
LXC_CMD_GET_CONFIG_ITEM
]
=
lxc_cmd_get_config_item_callback
,
[
LXC_CMD_GET_CONFIG_ITEM
]
=
lxc_cmd_get_config_item_callback
,
[
LXC_CMD_GET_NAME
]
=
lxc_cmd_get_name_callback
,
[
LXC_CMD_GET_NAME
]
=
lxc_cmd_get_name_callback
,
[
LXC_CMD_GET_LXCPATH
]
=
lxc_cmd_get_lxcpath_callback
,
[
LXC_CMD_GET_LXCPATH
]
=
lxc_cmd_get_lxcpath_callback
,
[
LXC_CMD_STATE_SERVER
]
=
lxc_cmd_state_server_callback
,
};
};
if
(
req
->
cmd
>=
LXC_CMD_MAX
)
{
if
(
req
->
cmd
>=
LXC_CMD_MAX
)
{
...
...
src/lxc/commands.h
View file @
74f04141
...
@@ -43,6 +43,7 @@ typedef enum {
...
@@ -43,6 +43,7 @@ typedef enum {
LXC_CMD_GET_CONFIG_ITEM
,
LXC_CMD_GET_CONFIG_ITEM
,
LXC_CMD_GET_NAME
,
LXC_CMD_GET_NAME
,
LXC_CMD_GET_LXCPATH
,
LXC_CMD_GET_LXCPATH
,
LXC_CMD_STATE_SERVER
,
LXC_CMD_MAX
,
LXC_CMD_MAX
,
}
lxc_cmd_t
;
}
lxc_cmd_t
;
...
@@ -82,8 +83,10 @@ extern char *lxc_cmd_get_config_item(const char *name, const char *item, const c
...
@@ -82,8 +83,10 @@ extern char *lxc_cmd_get_config_item(const char *name, const char *item, const c
extern
char
*
lxc_cmd_get_name
(
const
char
*
hashed_sock
);
extern
char
*
lxc_cmd_get_name
(
const
char
*
hashed_sock
);
extern
char
*
lxc_cmd_get_lxcpath
(
const
char
*
hashed_sock
);
extern
char
*
lxc_cmd_get_lxcpath
(
const
char
*
hashed_sock
);
extern
pid_t
lxc_cmd_get_init_pid
(
const
char
*
name
,
const
char
*
lxcpath
);
extern
pid_t
lxc_cmd_get_init_pid
(
const
char
*
name
,
const
char
*
lxcpath
);
extern
lxc_state_
t
lxc_cmd_get_state
(
const
char
*
name
,
const
char
*
lxcpath
);
extern
in
t
lxc_cmd_get_state
(
const
char
*
name
,
const
char
*
lxcpath
);
extern
int
lxc_cmd_stop
(
const
char
*
name
,
const
char
*
lxcpath
);
extern
int
lxc_cmd_stop
(
const
char
*
name
,
const
char
*
lxcpath
);
extern
int
lxc_cmd_state_server
(
const
char
*
name
,
const
char
*
lxcpath
,
lxc_state_t
states
[
MAX_STATE
]);
struct
lxc_epoll_descr
;
struct
lxc_epoll_descr
;
struct
lxc_handler
;
struct
lxc_handler
;
...
...
src/lxc/conf.c
View file @
74f04141
...
@@ -3771,12 +3771,16 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
...
@@ -3771,12 +3771,16 @@ int chown_mapped_root(char *path, struct lxc_conf *conf)
return
0
;
return
0
;
}
}
/
/ save the current gid of "path"
/
* save the current gid of "path" */
if
(
stat
(
path
,
&
sb
)
<
0
)
{
if
(
stat
(
path
,
&
sb
)
<
0
)
{
ERROR
(
"Error stat %s"
,
path
);
ERROR
(
"Error stat %s"
,
path
);
return
-
1
;
return
-
1
;
}
}
/* Update the path argument in case this was overlayfs. */
args1
[
sizeof
(
args1
)
/
sizeof
(
args1
[
0
])
-
2
]
=
path
;
args2
[
sizeof
(
args2
)
/
sizeof
(
args2
[
0
])
-
2
]
=
path
;
/*
/*
* A file has to be group-owned by a gid mapped into the
* A file has to be group-owned by a gid mapped into the
* container, or the container won't be privileged over it.
* container, or the container won't be privileged over it.
...
...
src/lxc/criu.c
View file @
74f04141
...
@@ -797,10 +797,13 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
...
@@ -797,10 +797,13 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
close
(
fd
);
close
(
fd
);
}
}
handler
=
lxc_init
(
c
->
name
,
c
->
lxc_conf
,
c
->
config_path
);
handler
=
lxc_init
_handler
(
c
->
name
,
c
->
lxc_conf
,
c
->
config_path
);
if
(
!
handler
)
if
(
!
handler
)
goto
out
;
goto
out
;
if
(
lxc_init
(
c
->
name
,
handler
)
<
0
)
goto
out
;
if
(
!
cgroup_init
(
handler
))
{
if
(
!
cgroup_init
(
handler
))
{
ERROR
(
"failed initing cgroups"
);
ERROR
(
"failed initing cgroups"
);
goto
out_fini_handler
;
goto
out_fini_handler
;
...
...
src/lxc/execute.c
View file @
74f04141
...
@@ -111,16 +111,15 @@ static struct lxc_operations execute_start_ops = {
...
@@ -111,16 +111,15 @@ static struct lxc_operations execute_start_ops = {
};
};
int
lxc_execute
(
const
char
*
name
,
char
*
const
argv
[],
int
quiet
,
int
lxc_execute
(
const
char
*
name
,
char
*
const
argv
[],
int
quiet
,
struct
lxc_conf
*
conf
,
const
char
*
lxcpath
,
bool
backgrounded
)
struct
lxc_handler
*
handler
,
const
char
*
lxcpath
,
bool
backgrounded
)
{
{
struct
execute_args
args
=
{
struct
execute_args
args
=
{.
argv
=
argv
,
.
quiet
=
quiet
};
.
argv
=
argv
,
.
quiet
=
quiet
};
if
(
lxc_check_inherited
(
conf
,
false
,
-
1
))
if
(
lxc_check_inherited
(
handler
->
conf
,
false
,
handler
->
conf
->
maincmd_fd
))
return
-
1
;
return
-
1
;
conf
->
is_execute
=
1
;
handler
->
conf
->
is_execute
=
1
;
return
__lxc_start
(
name
,
conf
,
&
execute_start_ops
,
&
args
,
lxcpath
,
backgrounded
);
return
__lxc_start
(
name
,
handler
,
&
execute_start_ops
,
&
args
,
lxcpath
,
backgrounded
);
}
}
src/lxc/lxc.h
View file @
74f04141
...
@@ -36,6 +36,7 @@ extern "C" {
...
@@ -36,6 +36,7 @@ extern "C" {
struct
lxc_msg
;
struct
lxc_msg
;
struct
lxc_conf
;
struct
lxc_conf
;
struct
lxc_arguments
;
struct
lxc_arguments
;
struct
lxc_handler
;
/**
/**
Following code is for liblxc.
Following code is for liblxc.
...
@@ -51,8 +52,9 @@ struct lxc_arguments;
...
@@ -51,8 +52,9 @@ struct lxc_arguments;
* @backgrounded : whether or not the container is daemonized
* @backgrounded : whether or not the container is daemonized
* Returns 0 on success, < 0 otherwise
* Returns 0 on success, < 0 otherwise
*/
*/
extern
int
lxc_start
(
const
char
*
name
,
char
*
const
argv
[],
struct
lxc_conf
*
conf
,
extern
int
lxc_start
(
const
char
*
name
,
char
*
const
argv
[],
const
char
*
lxcpath
,
bool
backgrounded
);
struct
lxc_handler
*
handler
,
const
char
*
lxcpath
,
bool
backgrounded
);
/*
/*
* Start the specified command inside an application container
* Start the specified command inside an application container
...
@@ -64,7 +66,7 @@ extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf
...
@@ -64,7 +66,7 @@ extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf
* Returns 0 on success, < 0 otherwise
* Returns 0 on success, < 0 otherwise
*/
*/
extern
int
lxc_execute
(
const
char
*
name
,
char
*
const
argv
[],
int
quiet
,
extern
int
lxc_execute
(
const
char
*
name
,
char
*
const
argv
[],
int
quiet
,
struct
lxc_
conf
*
conf
,
const
char
*
lxcpath
,
struct
lxc_
handler
*
handler
,
const
char
*
lxcpath
,
bool
backgrounded
);
bool
backgrounded
);
/*
/*
...
...
src/lxc/lxccontainer.c
View file @
74f04141
...
@@ -57,6 +57,7 @@
...
@@ -57,6 +57,7 @@
#include "namespace.h"
#include "namespace.h"
#include "network.h"
#include "network.h"
#include "sync.h"
#include "sync.h"
#include "start.h"
#include "state.h"
#include "state.h"
#include "utils.h"
#include "utils.h"
#include "version.h"
#include "version.h"
...
@@ -715,6 +716,7 @@ static void free_init_cmd(char **argv)
...
@@ -715,6 +716,7 @@ static void free_init_cmd(char **argv)
static
bool
do_lxcapi_start
(
struct
lxc_container
*
c
,
int
useinit
,
char
*
const
argv
[])
static
bool
do_lxcapi_start
(
struct
lxc_container
*
c
,
int
useinit
,
char
*
const
argv
[])
{
{
int
ret
;
int
ret
;
struct
lxc_handler
*
handler
;
struct
lxc_conf
*
conf
;
struct
lxc_conf
*
conf
;
bool
daemonize
=
false
;
bool
daemonize
=
false
;
FILE
*
pid_fp
=
NULL
;
FILE
*
pid_fp
=
NULL
;
...
@@ -731,21 +733,21 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -731,21 +733,21 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
/* If anything fails before we set error_num, we want an error in there */
/* If anything fails before we set error_num, we want an error in there */
c
->
error_num
=
1
;
c
->
error_num
=
1
;
/* container has been setup */
/* container has
not
been setup */
if
(
!
c
->
lxc_conf
)
if
(
!
c
->
lxc_conf
)
return
false
;
return
false
;
if
((
ret
=
ongoing_create
(
c
))
<
0
)
{
ret
=
ongoing_create
(
c
);
if
(
ret
<
0
)
{
ERROR
(
"Error checking for incomplete creation"
);
ERROR
(
"Error checking for incomplete creation"
);
return
false
;
return
false
;
}
if
(
ret
==
2
)
{
ERROR
(
"Error: %s creation was not completed"
,
c
->
name
);
do_lxcapi_destroy
(
c
);
return
false
;
}
else
if
(
ret
==
1
)
{
}
else
if
(
ret
==
1
)
{
ERROR
(
"Error: creation of %s is ongoing"
,
c
->
name
);
ERROR
(
"Error: creation of %s is ongoing"
,
c
->
name
);
return
false
;
return
false
;
}
else
if
(
ret
==
2
)
{
ERROR
(
"Error: %s creation was not completed"
,
c
->
name
);
do_lxcapi_destroy
(
c
);
return
false
;
}
}
/* is this app meant to be run through lxcinit, as in lxc-execute? */
/* is this app meant to be run through lxcinit, as in lxc-execute? */
...
@@ -756,10 +758,18 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -756,10 +758,18 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
return
false
;
return
false
;
conf
=
c
->
lxc_conf
;
conf
=
c
->
lxc_conf
;
daemonize
=
c
->
daemonize
;
daemonize
=
c
->
daemonize
;
/* initialize handler */
handler
=
lxc_init_handler
(
c
->
name
,
conf
,
c
->
config_path
);
container_mem_unlock
(
c
);
container_mem_unlock
(
c
);
if
(
!
handler
)
return
false
;
if
(
useinit
)
{
if
(
useinit
)
{
ret
=
lxc_execute
(
c
->
name
,
argv
,
1
,
conf
,
c
->
config_path
,
daemonize
);
TRACE
(
"calling
\"
lxc_execute
\"
"
);
ret
=
lxc_execute
(
c
->
name
,
argv
,
1
,
handler
,
c
->
config_path
,
daemonize
);
c
->
error_num
=
ret
;
return
ret
==
0
?
true
:
false
;
return
ret
==
0
?
true
:
false
;
}
}
...
@@ -780,17 +790,21 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -780,17 +790,21 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
*/
*/
if
(
daemonize
)
{
if
(
daemonize
)
{
char
title
[
2048
];
char
title
[
2048
];
lxc_monitord_spawn
(
c
->
config_path
)
;
pid_t
pid
;
pid_t
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
)
if
(
pid
<
0
)
{
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
return
false
;
return
false
;
}
if
(
pid
!=
0
)
{
if
(
pid
!=
0
)
{
/* Set to NULL because we don't want father unlink
/* Set to NULL because we don't want father unlink
* the PID file, child will do the free and unlink.
* the PID file, child will do the free and unlink.
*/
*/
c
->
pidfile
=
NULL
;
c
->
pidfile
=
NULL
;
close
(
handler
->
conf
->
maincmd_fd
);
return
wait_on_daemonized_start
(
c
,
pid
);
return
wait_on_daemonized_start
(
c
,
pid
);
}
}
...
@@ -815,7 +829,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -815,7 +829,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
SYSERROR
(
"Error chdir()ing to /."
);
SYSERROR
(
"Error chdir()ing to /."
);
exit
(
1
);
exit
(
1
);
}
}
lxc_check_inherited
(
conf
,
true
,
-
1
);
lxc_check_inherited
(
conf
,
true
,
handler
->
conf
->
maincmd_fd
);
if
(
null_stdfds
()
<
0
)
{
if
(
null_stdfds
()
<
0
)
{
ERROR
(
"failed to close fds"
);
ERROR
(
"failed to close fds"
);
exit
(
1
);
exit
(
1
);
...
@@ -824,11 +838,12 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -824,11 +838,12 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
}
else
{
}
else
{
if
(
!
am_single_threaded
())
{
if
(
!
am_single_threaded
())
{
ERROR
(
"Cannot start non-daemonized container when threaded"
);
ERROR
(
"Cannot start non-daemonized container when threaded"
);
lxc_free_handler
(
handler
);
return
false
;
return
false
;
}
}
}
}
/* We need to write PID file after daem
i
nize, so we always
/* We need to write PID file after daem
o
nize, so we always
* write the right PID.
* write the right PID.
*/
*/
if
(
c
->
pidfile
)
{
if
(
c
->
pidfile
)
{
...
@@ -836,6 +851,8 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -836,6 +851,8 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
if
(
pid_fp
==
NULL
)
{
if
(
pid_fp
==
NULL
)
{
SYSERROR
(
"Failed to create pidfile '%s' for '%s'"
,
SYSERROR
(
"Failed to create pidfile '%s' for '%s'"
,
c
->
pidfile
,
c
->
name
);
c
->
pidfile
,
c
->
name
);
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
if
(
daemonize
)
if
(
daemonize
)
exit
(
1
);
exit
(
1
);
return
false
;
return
false
;
...
@@ -845,6 +862,8 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -845,6 +862,8 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
SYSERROR
(
"Failed to write '%s'"
,
c
->
pidfile
);
SYSERROR
(
"Failed to write '%s'"
,
c
->
pidfile
);
fclose
(
pid_fp
);
fclose
(
pid_fp
);
pid_fp
=
NULL
;
pid_fp
=
NULL
;
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
if
(
daemonize
)
if
(
daemonize
)
exit
(
1
);
exit
(
1
);
return
false
;
return
false
;
...
@@ -860,22 +879,34 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
...
@@ -860,22 +879,34 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
if
(
conf
->
monitor_unshare
)
{
if
(
conf
->
monitor_unshare
)
{
if
(
unshare
(
CLONE_NEWNS
))
{
if
(
unshare
(
CLONE_NEWNS
))
{
SYSERROR
(
"failed to unshare mount namespace"
);
SYSERROR
(
"failed to unshare mount namespace"
);
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
return
false
;
return
false
;
}
}
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
if
(
mount
(
NULL
,
"/"
,
NULL
,
MS_SLAVE
|
MS_REC
,
NULL
))
{
SYSERROR
(
"Failed to make / rslave at startup"
);
SYSERROR
(
"Failed to make / rslave at startup"
);
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
return
false
;
return
false
;
}
}
}
}
reboot
:
reboot
:
if
(
lxc_check_inherited
(
conf
,
daemonize
,
-
1
))
{
if
(
conf
->
reboot
==
2
)
{
/* initialize handler */
handler
=
lxc_init_handler
(
c
->
name
,
conf
,
c
->
config_path
);
if
(
!
handler
)
goto
out
;
}
if
(
lxc_check_inherited
(
conf
,
daemonize
,
handler
->
conf
->
maincmd_fd
))
{
ERROR
(
"Inherited fds found"
);
ERROR
(
"Inherited fds found"
);
lxc_free_handler
(
handler
);
ret
=
1
;
ret
=
1
;
goto
out
;
goto
out
;
}
}
ret
=
lxc_start
(
c
->
name
,
argv
,
conf
,
c
->
config_path
,
daemonize
);
ret
=
lxc_start
(
c
->
name
,
argv
,
handler
,
c
->
config_path
,
daemonize
);
c
->
error_num
=
ret
;
c
->
error_num
=
ret
;
if
(
conf
->
reboot
==
1
)
{
if
(
conf
->
reboot
==
1
)
{
...
@@ -890,13 +921,11 @@ out:
...
@@ -890,13 +921,11 @@ out:
free
(
c
->
pidfile
);
free
(
c
->
pidfile
);
c
->
pidfile
=
NULL
;
c
->
pidfile
=
NULL
;
}
}
free_init_cmd
(
init_cmd
);
free_init_cmd
(
init_cmd
);
if
(
daemonize
)
if
(
daemonize
)
exit
(
ret
==
0
?
true
:
false
);
exit
(
ret
==
0
?
true
:
false
);
else
return
(
ret
==
0
?
true
:
false
);
return
(
ret
==
0
?
true
:
false
);
}
}
static
bool
lxcapi_start
(
struct
lxc_container
*
c
,
int
useinit
,
char
*
const
argv
[])
static
bool
lxcapi_start
(
struct
lxc_container
*
c
,
int
useinit
,
char
*
const
argv
[])
...
...
src/lxc/start.c
View file @
74f04141
...
@@ -341,10 +341,64 @@ static int signal_handler(int fd, uint32_t events, void *data,
...
@@ -341,10 +341,64 @@ static int signal_handler(int fd, uint32_t events, void *data,
return
1
;
return
1
;
}
}
int
lxc_set_state
(
const
char
*
name
,
struct
lxc_handler
*
handler
,
lxc_state_t
state
)
int
lxc_set_state
(
const
char
*
name
,
struct
lxc_handler
*
handler
,
lxc_state_t
state
)
{
{
ssize_t
ret
;
struct
lxc_list
*
cur
,
*
next
;
struct
state_client
*
client
;
struct
lxc_msg
msg
=
{.
type
=
lxc_msg_state
,
.
value
=
state
};
process_lock
();
/* Only set state under process lock held so that we don't cause
* lxc_cmd_state_server() to miss a state.
*/
handler
->
state
=
state
;
handler
->
state
=
state
;
TRACE
(
"set container state to %s"
,
lxc_state2str
(
state
));
if
(
lxc_list_empty
(
&
handler
->
state_clients
))
{
TRACE
(
"no state clients registered"
);
process_unlock
();
return
0
;
}
strncpy
(
msg
.
name
,
name
,
sizeof
(
msg
.
name
));
msg
.
name
[
sizeof
(
msg
.
name
)
-
1
]
=
0
;
lxc_list_for_each_safe
(
cur
,
&
handler
->
state_clients
,
next
)
{
client
=
cur
->
elem
;
if
(
!
client
->
states
[
state
])
{
TRACE
(
"state %s not registered for state client %d"
,
lxc_state2str
(
state
),
client
->
clientfd
);
continue
;
}
TRACE
(
"sending state %s to state client %d"
,
lxc_state2str
(
state
),
client
->
clientfd
);
again:
ret
=
send
(
client
->
clientfd
,
&
msg
,
sizeof
(
msg
),
0
);
if
(
ret
<
0
)
{
if
(
errno
==
EINTR
)
goto
again
;
ERROR
(
"failed to send message to client"
);
}
/* kick client from list */
close
(
client
->
clientfd
);
lxc_list_del
(
cur
);
free
(
cur
->
elem
);
free
(
cur
);
}
process_unlock
();
/* This function will try to connect to the legacy lxc-monitord state
* server and only exists for backwards compatibility.
*/
lxc_monitor_send_state
(
name
,
state
,
handler
->
lxcpath
);
lxc_monitor_send_state
(
name
,
state
,
handler
->
lxcpath
);
return
0
;
return
0
;
}
}
...
@@ -384,6 +438,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
...
@@ -384,6 +438,7 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
DEBUG
(
"Not starting utmp handler as CAP_SYS_BOOT cannot be dropped without capabilities support."
);
DEBUG
(
"Not starting utmp handler as CAP_SYS_BOOT cannot be dropped without capabilities support."
);
#endif
#endif
}
}
TRACE
(
"lxc mainloop is ready"
);
return
lxc_mainloop
(
&
descr
,
-
1
);
return
lxc_mainloop
(
&
descr
,
-
1
);
...
@@ -396,14 +451,29 @@ out_sigfd:
...
@@ -396,14 +451,29 @@ out_sigfd:
return
-
1
;
return
-
1
;
}
}
struct
lxc_handler
*
lxc_init
(
const
char
*
name
,
struct
lxc_conf
*
conf
,
const
char
*
lxcpath
)
void
lxc_free_handler
(
struct
lxc_handler
*
handler
)
{
if
(
handler
->
conf
&&
handler
->
conf
->
maincmd_fd
)
close
(
handler
->
conf
->
maincmd_fd
);
if
(
handler
->
name
)
free
(
handler
->
name
);
handler
->
conf
=
NULL
;
free
(
handler
);
}
struct
lxc_handler
*
lxc_init_handler
(
const
char
*
name
,
struct
lxc_conf
*
conf
,
const
char
*
lxcpath
)
{
{
int
i
;
int
i
;
struct
lxc_handler
*
handler
;
struct
lxc_handler
*
handler
;
handler
=
malloc
(
sizeof
(
*
handler
));
handler
=
malloc
(
sizeof
(
*
handler
));
if
(
!
handler
)
if
(
!
handler
)
{
ERROR
(
"failed to allocate memory"
);
return
NULL
;
return
NULL
;
}
memset
(
handler
,
0
,
sizeof
(
*
handler
));
memset
(
handler
,
0
,
sizeof
(
*
handler
));
...
@@ -411,31 +481,52 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
...
@@ -411,31 +481,52 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
handler
->
conf
=
conf
;
handler
->
conf
=
conf
;
handler
->
lxcpath
=
lxcpath
;
handler
->
lxcpath
=
lxcpath
;
handler
->
pinfd
=
-
1
;
handler
->
pinfd
=
-
1
;
lxc_list_init
(
&
handler
->
state_clients
);
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
for
(
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
handler
->
nsfd
[
i
]
=
-
1
;
handler
->
nsfd
[
i
]
=
-
1
;
lsm_init
();
handler
->
name
=
strdup
(
name
);
handler
->
name
=
strdup
(
name
);
if
(
!
handler
->
name
)
{
if
(
!
handler
->
name
)
{
ERROR
(
"
Failed to allocate memory.
"
);
ERROR
(
"
failed to allocate memory
"
);
goto
o
ut_free
;
goto
o
n_error
;
}
}
if
(
lxc_cmd_init
(
name
,
handler
,
lxcpath
))
if
(
lxc_cmd_init
(
name
,
handler
,
lxcpath
))
{
goto
out_free_name
;
ERROR
(
"failed to set up command socket"
);
goto
on_error
;
}
TRACE
(
"unix domain socket %d for command server is ready"
,
handler
->
conf
->
maincmd_fd
);
return
handler
;
on_error:
lxc_free_handler
(
handler
);
return
NULL
;
}
int
lxc_init
(
const
char
*
name
,
struct
lxc_handler
*
handler
)
{
struct
lxc_conf
*
conf
=
handler
->
conf
;
lsm_init
();
TRACE
(
"initialized LSM"
);
if
(
lxc_read_seccomp_config
(
conf
)
!=
0
)
{
if
(
lxc_read_seccomp_config
(
conf
)
!=
0
)
{
ERROR
(
"Failed loading seccomp policy."
);
ERROR
(
"Failed loading seccomp policy."
);
goto
out_close_maincmd_fd
;
goto
out_close_maincmd_fd
;
}
}
TRACE
(
"read seccomp policy"
);
/* Begin by setting the state to STARTING. */
/* Begin by setting the state to STARTING. */
if
(
lxc_set_state
(
name
,
handler
,
STARTING
))
{
if
(
lxc_set_state
(
name
,
handler
,
STARTING
))
{
ERROR
(
"Failed to set state for container
\"
%s
\"
to
\"
%s
\"
."
,
name
,
lxc_state2str
(
STARTING
));
ERROR
(
"Failed to set state for container
\"
%s
\"
to
\"
%s
\"
."
,
name
,
lxc_state2str
(
STARTING
));
goto
out_close_maincmd_fd
;
goto
out_close_maincmd_fd
;
}
}
TRACE
(
"set container state to
\"
STARTING
\"
"
);
/* Start of environment variable setup for hooks. */
/* Start of environment variable setup for hooks. */
if
(
name
&&
setenv
(
"LXC_NAME"
,
name
,
1
))
if
(
name
&&
setenv
(
"LXC_NAME"
,
name
,
1
))
...
@@ -460,10 +551,13 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
...
@@ -460,10 +551,13 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
SYSERROR
(
"Failed to set environment variable LXC_CGNS_AWARE=1."
);
SYSERROR
(
"Failed to set environment variable LXC_CGNS_AWARE=1."
);
/* End of environment variable setup for hooks. */
/* End of environment variable setup for hooks. */
TRACE
(
"set environment variables"
);
if
(
run_lxc_hooks
(
name
,
"pre-start"
,
conf
,
handler
->
lxcpath
,
NULL
))
{
if
(
run_lxc_hooks
(
name
,
"pre-start"
,
conf
,
handler
->
lxcpath
,
NULL
))
{
ERROR
(
"Failed to run lxc.hook.pre-start for container
\"
%s
\"
."
,
name
);
ERROR
(
"Failed to run lxc.hook.pre-start for container
\"
%s
\"
."
,
name
);
goto
out_aborting
;
goto
out_aborting
;
}
}
TRACE
(
"ran pre-start hooks"
);
/* The signal fd has to be created before forking otherwise if the child
/* The signal fd has to be created before forking otherwise if the child
* process exits before we setup the signal fd, the event will be lost
* process exits before we setup the signal fd, the event will be lost
...
@@ -474,20 +568,23 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
...
@@ -474,20 +568,23 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
ERROR
(
"Failed to setup SIGCHLD fd handler."
);
ERROR
(
"Failed to setup SIGCHLD fd handler."
);
goto
out_delete_tty
;
goto
out_delete_tty
;
}
}
TRACE
(
"set up signal fd"
);
/* Do this after setting up signals since it might unblock SIGWINCH. */
/* Do this after setting up signals since it might unblock SIGWINCH. */
if
(
lxc_console_create
(
conf
))
{
if
(
lxc_console_create
(
conf
))
{
ERROR
(
"Failed to create console for container
\"
%s
\"
."
,
name
);
ERROR
(
"Failed to create console for container
\"
%s
\"
."
,
name
);
goto
out_restore_sigmask
;
goto
out_restore_sigmask
;
}
}
TRACE
(
"created console"
);
if
(
lxc_ttys_shift_ids
(
conf
)
<
0
)
{
if
(
lxc_ttys_shift_ids
(
conf
)
<
0
)
{
ERROR
(
"Failed to shift tty into container."
);
ERROR
(
"Failed to shift tty into container."
);
goto
out_restore_sigmask
;
goto
out_restore_sigmask
;
}
}
TRACE
(
"shifted tty ids"
);
INFO
(
"
Container
\"
%s
\"
is initialized.
"
,
name
);
INFO
(
"
container
\"
%s
\"
is initialized
"
,
name
);
return
handler
;
return
0
;
out_restore_sigmask:
out_restore_sigmask:
sigprocmask
(
SIG_SETMASK
,
&
handler
->
oldmask
,
NULL
);
sigprocmask
(
SIG_SETMASK
,
&
handler
->
oldmask
,
NULL
);
...
@@ -498,19 +595,15 @@ out_aborting:
...
@@ -498,19 +595,15 @@ out_aborting:
out_close_maincmd_fd:
out_close_maincmd_fd:
close
(
conf
->
maincmd_fd
);
close
(
conf
->
maincmd_fd
);
conf
->
maincmd_fd
=
-
1
;
conf
->
maincmd_fd
=
-
1
;
out_free_name:
return
-
1
;
free
(
handler
->
name
);
handler
->
name
=
NULL
;
out_free:
free
(
handler
);
return
NULL
;
}
}
void
lxc_fini
(
const
char
*
name
,
struct
lxc_handler
*
handler
)
void
lxc_fini
(
const
char
*
name
,
struct
lxc_handler
*
handler
)
{
{
int
i
,
rc
;
int
i
,
rc
;
struct
lxc_list
*
cur
,
*
next
;
pid_t
self
=
getpid
();
pid_t
self
=
getpid
();
char
*
namespaces
[
LXC_NS_MAX
+
1
];
char
*
namespaces
[
LXC_NS_MAX
+
1
];
size_t
namespace_count
=
0
;
size_t
namespace_count
=
0
;
/* The STOPPING state is there for future cleanup code which can take
/* The STOPPING state is there for future cleanup code which can take
...
@@ -572,8 +665,23 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
...
@@ -572,8 +665,23 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
lxc_console_delete
(
&
handler
->
conf
->
console
);
lxc_console_delete
(
&
handler
->
conf
->
console
);
lxc_delete_tty
(
&
handler
->
conf
->
tty_info
);
lxc_delete_tty
(
&
handler
->
conf
->
tty_info
);
/* close the command socket */
close
(
handler
->
conf
->
maincmd_fd
);
close
(
handler
->
conf
->
maincmd_fd
);
handler
->
conf
->
maincmd_fd
=
-
1
;
handler
->
conf
->
maincmd_fd
=
-
1
;
/* The command socket is now closed, no more state clients can register
* themselves from now on. So free the list of state clients.
*/
lxc_list_for_each_safe
(
cur
,
&
handler
->
state_clients
,
next
)
{
struct
state_client
*
client
=
cur
->
elem
;
/* close state client socket */
close
(
client
->
clientfd
);
lxc_list_del
(
cur
);
free
(
cur
->
elem
);
free
(
cur
);
}
free
(
handler
->
name
);
free
(
handler
->
name
);
if
(
handler
->
ttysock
[
0
]
!=
-
1
)
{
if
(
handler
->
ttysock
[
0
]
!=
-
1
)
{
close
(
handler
->
ttysock
[
0
]);
close
(
handler
->
ttysock
[
0
]);
...
@@ -1337,17 +1445,16 @@ out_abort:
...
@@ -1337,17 +1445,16 @@ out_abort:
return
-
1
;
return
-
1
;
}
}
int
__lxc_start
(
const
char
*
name
,
struct
lxc_
conf
*
conf
,
int
__lxc_start
(
const
char
*
name
,
struct
lxc_
handler
*
handler
,
struct
lxc_operations
*
ops
,
void
*
data
,
const
char
*
lxcpath
,
struct
lxc_operations
*
ops
,
void
*
data
,
const
char
*
lxcpath
,
bool
backgrounded
)
bool
backgrounded
)
{
{
struct
lxc_handler
*
handler
;
int
err
=
-
1
;
int
status
;
int
status
;
int
err
=
-
1
;
bool
removed_all_netdevs
=
true
;
bool
removed_all_netdevs
=
true
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
handler
=
lxc_init
(
name
,
conf
,
lxcpath
);
if
(
lxc_init
(
name
,
handler
)
<
0
)
{
if
(
!
handler
)
{
ERROR
(
"Failed to initialize container
\"
%s
\"
."
,
name
);
ERROR
(
"Failed to initialize container
\"
%s
\"
."
,
name
);
return
-
1
;
return
-
1
;
}
}
...
@@ -1494,15 +1601,15 @@ static struct lxc_operations start_ops = {
...
@@ -1494,15 +1601,15 @@ static struct lxc_operations start_ops = {
.
post_start
=
post_start
.
post_start
=
post_start
};
};
int
lxc_start
(
const
char
*
name
,
char
*
const
argv
[],
struct
lxc_
conf
*
conf
,
int
lxc_start
(
const
char
*
name
,
char
*
const
argv
[],
struct
lxc_
handler
*
handler
,
const
char
*
lxcpath
,
bool
backgrounded
)
const
char
*
lxcpath
,
bool
backgrounded
)
{
{
struct
start_args
start_arg
=
{
struct
start_args
start_arg
=
{
.
argv
=
argv
,
.
argv
=
argv
,
};
};
conf
->
need_utmp_watch
=
1
;
handler
->
conf
->
need_utmp_watch
=
1
;
return
__lxc_start
(
name
,
conf
,
&
start_ops
,
&
start_arg
,
lxcpath
,
backgrounded
);
return
__lxc_start
(
name
,
handler
,
&
start_ops
,
&
start_arg
,
lxcpath
,
backgrounded
);
}
}
static
void
lxc_destroy_container_on_signal
(
struct
lxc_handler
*
handler
,
static
void
lxc_destroy_container_on_signal
(
struct
lxc_handler
*
handler
,
...
...
src/lxc/start.h
View file @
74f04141
...
@@ -27,21 +27,11 @@
...
@@ -27,21 +27,11 @@
#include <sys/param.h>
#include <sys/param.h>
#include <stdbool.h>
#include <stdbool.h>
#include "conf.h"
#include "config.h"
#include "config.h"
#include "state.h"
#include "state.h"
#include "namespace.h"
#include "namespace.h"
struct
lxc_conf
;
struct
lxc_handler
;
struct
lxc_operations
{
int
(
*
start
)(
struct
lxc_handler
*
,
void
*
);
int
(
*
post_start
)(
struct
lxc_handler
*
,
void
*
);
};
struct
cgroup_desc
;
struct
lxc_handler
{
struct
lxc_handler
{
pid_t
pid
;
pid_t
pid
;
char
*
name
;
char
*
name
;
...
@@ -60,17 +50,31 @@ struct lxc_handler {
...
@@ -60,17 +50,31 @@ struct lxc_handler {
bool
backgrounded
;
// indicates whether should we close std{in,out,err} on start
bool
backgrounded
;
// indicates whether should we close std{in,out,err} on start
int
nsfd
[
LXC_NS_MAX
];
int
nsfd
[
LXC_NS_MAX
];
int
netnsfd
;
int
netnsfd
;
struct
lxc_list
state_clients
;
};
};
struct
lxc_operations
{
int
(
*
start
)(
struct
lxc_handler
*
,
void
*
);
int
(
*
post_start
)(
struct
lxc_handler
*
,
void
*
);
};
struct
state_client
{
int
clientfd
;
lxc_state_t
states
[
MAX_STATE
];
};
extern
int
lxc_poll
(
const
char
*
name
,
struct
lxc_handler
*
handler
);
extern
int
lxc_poll
(
const
char
*
name
,
struct
lxc_handler
*
handler
);
extern
int
lxc_set_state
(
const
char
*
name
,
struct
lxc_handler
*
handler
,
lxc_state_t
state
);
extern
int
lxc_set_state
(
const
char
*
name
,
struct
lxc_handler
*
handler
,
lxc_state_t
state
);
extern
void
lxc_abort
(
const
char
*
name
,
struct
lxc_handler
*
handler
);
extern
void
lxc_abort
(
const
char
*
name
,
struct
lxc_handler
*
handler
);
extern
struct
lxc_handler
*
lxc_init
(
const
char
*
name
,
struct
lxc_conf
*
,
const
char
*
);
extern
struct
lxc_handler
*
lxc_init_handler
(
const
char
*
name
,
struct
lxc_conf
*
conf
,
const
char
*
lxcpath
);
extern
void
lxc_free_handler
(
struct
lxc_handler
*
handler
);
extern
int
lxc_init
(
const
char
*
name
,
struct
lxc_handler
*
handler
);
extern
void
lxc_fini
(
const
char
*
name
,
struct
lxc_handler
*
handler
);
extern
void
lxc_fini
(
const
char
*
name
,
struct
lxc_handler
*
handler
);
extern
int
lxc_check_inherited
(
struct
lxc_conf
*
conf
,
bool
closeall
,
int
fd_to_ignore
);
extern
int
lxc_check_inherited
(
struct
lxc_conf
*
conf
,
bool
closeall
,
int
fd_to_ignore
);
int
__lxc_start
(
const
char
*
,
struct
lxc_
conf
*
,
struct
lxc_operations
*
,
int
__lxc_start
(
const
char
*
,
struct
lxc_
handler
*
,
struct
lxc_operations
*
,
void
*
,
const
char
*
,
bool
);
void
*
,
const
char
*
,
bool
);
extern
void
resolve_clone_flags
(
struct
lxc_handler
*
handler
);
extern
void
resolve_clone_flags
(
struct
lxc_handler
*
handler
);
...
...
src/lxc/state.c
View file @
74f04141
...
@@ -79,7 +79,7 @@ lxc_state_t lxc_getstate(const char *name, const char *lxcpath)
...
@@ -79,7 +79,7 @@ lxc_state_t lxc_getstate(const char *name, const char *lxcpath)
return
state
;
return
state
;
}
}
static
int
fillwaitedstates
(
const
char
*
strstates
,
in
t
*
states
)
static
int
fillwaitedstates
(
const
char
*
strstates
,
lxc_state_
t
*
states
)
{
{
char
*
token
,
*
saveptr
=
NULL
;
char
*
token
,
*
saveptr
=
NULL
;
char
*
strstates_dup
=
strdup
(
strstates
);
char
*
strstates_dup
=
strdup
(
strstates
);
...
@@ -108,90 +108,21 @@ static int fillwaitedstates(const char *strstates, int *states)
...
@@ -108,90 +108,21 @@ static int fillwaitedstates(const char *strstates, int *states)
extern
int
lxc_wait
(
const
char
*
lxcname
,
const
char
*
states
,
int
timeout
,
extern
int
lxc_wait
(
const
char
*
lxcname
,
const
char
*
states
,
int
timeout
,
const
char
*
lxcpath
)
const
char
*
lxcpath
)
{
{
struct
lxc_msg
msg
;
int
state
;
int
state
,
ret
;
lxc_state_t
s
[
MAX_STATE
]
=
{
0
};
int
s
[
MAX_STATE
]
=
{
0
},
fd
;
if
(
fillwaitedstates
(
states
,
s
))
if
(
fillwaitedstates
(
states
,
s
))
return
-
1
;
return
-
1
;
if
(
lxc_monitord_spawn
(
lxcpath
))
state
=
lxc_cmd_state_server
(
lxcname
,
lxcpath
,
s
);
return
-
1
;
fd
=
lxc_monitor_open
(
lxcpath
);
if
(
fd
<
0
)
return
-
1
;
/*
* if container present,
* then check if already in requested state
*/
ret
=
-
1
;
state
=
lxc_getstate
(
lxcname
,
lxcpath
);
if
(
state
<
0
)
{
if
(
state
<
0
)
{
goto
out_close
;
SYSERROR
(
"failed to receive state from monitor"
);
}
else
if
((
state
>=
0
)
&&
(
s
[
state
]))
{
return
-
1
;
ret
=
0
;
goto
out_close
;
}
}
for
(;;)
{
TRACE
(
"retrieved state of container %s"
,
lxc_state2str
(
state
));
int64_t
elapsed_time
,
curtime
=
0
;
if
(
!
s
[
state
])
struct
timespec
tspec
;
return
-
1
;
int
stop
=
0
;
int
retval
;
if
(
timeout
!=
-
1
)
{
retval
=
clock_gettime
(
CLOCK_REALTIME
,
&
tspec
);
if
(
retval
)
goto
out_close
;
curtime
=
tspec
.
tv_sec
;
}
if
(
lxc_monitor_read_timeout
(
fd
,
&
msg
,
timeout
)
<
0
)
{
/* try again if select interrupted by signal */
if
(
errno
!=
EINTR
)
goto
out_close
;
}
if
(
timeout
!=
-
1
)
{
retval
=
clock_gettime
(
CLOCK_REALTIME
,
&
tspec
);
if
(
retval
)
goto
out_close
;
elapsed_time
=
tspec
.
tv_sec
-
curtime
;
if
(
timeout
-
elapsed_time
<=
0
)
stop
=
1
;
timeout
-=
elapsed_time
;
}
if
(
strcmp
(
lxcname
,
msg
.
name
))
{
if
(
stop
)
{
ret
=
-
2
;
goto
out_close
;
}
continue
;
}
switch
(
msg
.
type
)
{
case
lxc_msg_state
:
if
(
msg
.
value
<
0
||
msg
.
value
>=
MAX_STATE
)
goto
out_close
;
if
(
s
[
msg
.
value
])
{
ret
=
0
;
goto
out_close
;
}
break
;
default:
if
(
stop
)
{
ret
=
-
2
;
goto
out_close
;
}
/* just ignore garbage */
break
;
}
}
out_close:
return
0
;
lxc_monitor_close
(
fd
);
return
ret
;
}
}
src/lxc/state.h
View file @
74f04141
...
@@ -24,8 +24,15 @@
...
@@ -24,8 +24,15 @@
#define __LXC_STATE_H
#define __LXC_STATE_H
typedef
enum
{
typedef
enum
{
STOPPED
,
STARTING
,
RUNNING
,
STOPPING
,
STOPPED
,
ABORTING
,
FREEZING
,
FROZEN
,
THAWED
,
MAX_STATE
,
STARTING
,
RUNNING
,
STOPPING
,
ABORTING
,
FREEZING
,
FROZEN
,
THAWED
,
MAX_STATE
,
}
lxc_state_t
;
}
lxc_state_t
;
extern
int
lxc_rmstate
(
const
char
*
name
);
extern
int
lxc_rmstate
(
const
char
*
name
);
...
...
src/lxc/tools/lxc_execute.c
View file @
74f04141
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include <libgen.h>
#include <libgen.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
#include <lxc/lxccontainer.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/param.h>
...
@@ -40,7 +41,6 @@
...
@@ -40,7 +41,6 @@
#include "config.h"
#include "config.h"
#include "start.h"
#include "start.h"
#include "utils.h"
#include "utils.h"
#include "lxccontainer.h"
lxc_log_define
(
lxc_execute_ui
,
lxc
);
lxc_log_define
(
lxc_execute_ui
,
lxc
);
...
@@ -105,10 +105,10 @@ Options :\n\
...
@@ -105,10 +105,10 @@ Options :\n\
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
char
*
rcfile
;
struct
lxc_container
*
c
;
struct
lxc_conf
*
conf
;
struct
lxc_log
log
;
struct
lxc_log
log
;
int
ret
;
int
ret
;
bool
bret
;
lxc_list_init
(
&
defines
);
lxc_list_init
(
&
defines
);
...
@@ -129,50 +129,38 @@ int main(int argc, char *argv[])
...
@@ -129,50 +129,38 @@ int main(int argc, char *argv[])
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
lxc_log_options_no_override
();
lxc_log_options_no_override
();
/* rcfile is specified in the cli option */
c
=
lxc_container_new
(
my_args
.
name
,
my_args
.
lxcpath
[
0
]);
if
(
my_args
.
rcfile
)
if
(
!
c
)
{
rcfile
=
(
char
*
)
my_args
.
rcfile
;
ERROR
(
"Failed to create lxc_container"
)
;
else
{
exit
(
EXIT_FAILURE
);
int
rc
;
}
rc
=
asprintf
(
&
rcfile
,
"%s/%s/config"
,
my_args
.
lxcpath
[
0
],
my_args
.
name
);
if
(
my_args
.
rcfile
)
{
if
(
rc
==
-
1
)
{
c
->
clear_config
(
c
);
SYSERROR
(
"failed to allocate memory"
);
if
(
!
c
->
load_config
(
c
,
my_args
.
rcfile
))
{
ERROR
(
"Failed to load rcfile"
);
lxc_container_put
(
c
);
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
}
}
c
->
configfile
=
strdup
(
my_args
.
rcfile
);
/* container configuration does not exist */
if
(
!
c
->
configfile
)
{
if
(
access
(
rcfile
,
F_OK
))
{
ERROR
(
"Out of memory setting new config filename"
);
free
(
rcfile
);
lxc_container_put
(
c
);
rcfile
=
NULL
;
exit
(
EXIT_FAILURE
)
;
}
}
}
}
conf
=
lxc_conf_init
();
if
(
!
conf
)
{
ERROR
(
"failed to initialize configuration"
);
exit
(
EXIT_FAILURE
);
}
if
(
rcfile
&&
lxc_config_read
(
rcfile
,
conf
,
NULL
))
{
ERROR
(
"failed to read configuration file"
);
exit
(
EXIT_FAILURE
);
}
if
(
lxc_config_define_load
(
&
defines
,
conf
))
exit
(
EXIT_FAILURE
);
if
(
my_args
.
uid
)
if
(
my_args
.
uid
)
conf
->
init_uid
=
my_args
.
uid
;
c
->
lxc_c
onf
->
init_uid
=
my_args
.
uid
;
if
(
my_args
.
gid
)
if
(
my_args
.
gid
)
conf
->
init_gid
=
my_args
.
gid
;
c
->
lxc_conf
->
init_gid
=
my_args
.
gid
;
ret
=
lxc_execute
(
my_args
.
name
,
my_args
.
argv
,
my_args
.
quiet
,
conf
,
my_args
.
lxcpath
[
0
],
false
);
lxc_conf_free
(
conf
);
if
(
ret
<
0
)
c
->
daemonize
=
false
;
bret
=
c
->
start
(
c
,
1
,
my_args
.
argv
);
ret
=
c
->
error_num
;
lxc_container_put
(
c
);
if
(
!
bret
)
exit
(
EXIT_FAILURE
);
exit
(
EXIT_FAILURE
);
exit
(
ret
);
exit
(
ret
);
}
}
src/tests/lxc-test-apparmor-mount
View file @
74f04141
...
@@ -50,7 +50,7 @@ cleanup() {
...
@@ -50,7 +50,7 @@ cleanup() {
run_cmd lxc-destroy
-f
-n
$cname
||
true
run_cmd lxc-destroy
-f
-n
$cname
||
true
umount
-l
$MOUNTSR
||
true
umount
-l
$MOUNTSR
||
true
rmdir
$dnam
||
true
rmdir
$dnam
||
true
pkill
-u
$(
id
-u
$TUSER
)
-9
pkill
-u
$(
id
-u
$TUSER
)
-9
||
true
sed
-i
'/lxcunpriv/d'
/run/lxc/nics /etc/lxc/lxc-usernet
sed
-i
'/lxcunpriv/d'
/run/lxc/nics /etc/lxc/lxc-usernet
sed
-i
'/^lxcunpriv:/d'
/etc/subuid /etc/subgid
sed
-i
'/^lxcunpriv:/d'
/etc/subuid /etc/subgid
rm
-Rf
$HDIR
/run/user/
$(
id
-u
$TUSER
)
rm
-Rf
$HDIR
/run/user/
$(
id
-u
$TUSER
)
...
...
src/tests/lxc-test-unpriv
View file @
74f04141
...
@@ -71,7 +71,7 @@ cleanup() {
...
@@ -71,7 +71,7 @@ cleanup() {
run_cmd lxc-stop
-n
c2
-k
||
true
run_cmd lxc-stop
-n
c2
-k
||
true
run_cmd lxc-stop
-n
c1
-k
||
true
run_cmd lxc-stop
-n
c1
-k
||
true
pkill
-u
$(
id
-u
$TUSER
)
-9
pkill
-u
$(
id
-u
$TUSER
)
-9
||
true
sed
-i
'/lxcunpriv/d'
/run/lxc/nics /etc/lxc/lxc-usernet
sed
-i
'/lxcunpriv/d'
/run/lxc/nics /etc/lxc/lxc-usernet
sed
-i
'/^lxcunpriv:/d'
/etc/subuid /etc/subgid
sed
-i
'/^lxcunpriv:/d'
/etc/subuid /etc/subgid
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment