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
0374aacd
Unverified
Commit
0374aacd
authored
Dec 06, 2019
by
Stéphane Graber
Committed by
GitHub
Dec 06, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3215 from brauner/cgroup2_controller_delegation
cgroup2: rework controller delegation
parents
92ef1f8a
c581d2a6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
194 additions
and
141 deletions
+194
-141
cgfsng.c
src/lxc/cgroups/cgfsng.c
+130
-109
cgroup.c
src/lxc/cgroups/cgroup.c
+1
-0
cgroup.h
src/lxc/cgroups/cgroup.h
+8
-4
lxccontainer.c
src/lxc/lxccontainer.c
+17
-17
macro.h
src/lxc/macro.h
+6
-0
start.c
src/lxc/start.c
+29
-11
start.h
src/lxc/start.h
+3
-0
No files found.
src/lxc/cgroups/cgfsng.c
View file @
0374aacd
This diff is collapsed.
Click to expand it.
src/lxc/cgroups/cgroup.c
View file @
0374aacd
...
...
@@ -65,6 +65,7 @@ void cgroup_exit(struct cgroup_ops *ops)
free
(
ops
->
cgroup_pattern
);
free
(
ops
->
container_cgroup
);
free
(
ops
->
monitor_cgroup
);
if
(
ops
->
cgroup2_devices
)
bpf_program_free
(
ops
->
cgroup2_devices
);
...
...
src/lxc/cgroups/cgroup.h
View file @
0374aacd
...
...
@@ -88,6 +88,7 @@ struct cgroup_ops {
char
**
cgroup_use
;
char
*
cgroup_pattern
;
char
*
container_cgroup
;
char
*
monitor_cgroup
;
/* Static memory, do not free.*/
const
char
*
monitor_pattern
;
...
...
@@ -135,9 +136,9 @@ struct cgroup_ops {
void
(
*
payload_destroy
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
void
(
*
monitor_destroy
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
monitor_create
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
monitor_enter
)(
struct
cgroup_ops
*
ops
,
pid_t
pid
);
bool
(
*
monitor_enter
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
payload_create
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
payload_enter
)(
struct
cgroup_ops
*
ops
,
pid_t
pid
);
bool
(
*
payload_enter
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
const
char
*
(
*
get_cgroup
)(
struct
cgroup_ops
*
ops
,
const
char
*
controller
);
bool
(
*
escape
)(
const
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
);
int
(
*
num_hierarchies
)(
struct
cgroup_ops
*
ops
);
...
...
@@ -148,8 +149,9 @@ struct cgroup_ops {
size_t
len
,
const
char
*
name
,
const
char
*
lxcpath
);
int
(
*
freeze
)(
struct
cgroup_ops
*
ops
,
int
timeout
);
int
(
*
unfreeze
)(
struct
cgroup_ops
*
ops
,
int
timeout
);
bool
(
*
setup_limits
)(
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
,
bool
with_devices
);
bool
(
*
setup_limits_legacy
)(
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
,
bool
with_devices
);
bool
(
*
setup_limits
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
chown
)(
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
);
bool
(
*
attach
)(
struct
cgroup_ops
*
ops
,
const
char
*
name
,
const
char
*
lxcpath
,
pid_t
pid
);
...
...
@@ -158,6 +160,8 @@ struct cgroup_ops {
int
(
*
nrtasks
)(
struct
cgroup_ops
*
ops
);
bool
(
*
devices_activate
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
monitor_delegate_controllers
)(
struct
cgroup_ops
*
ops
);
bool
(
*
payload_delegate_controllers
)(
struct
cgroup_ops
*
ops
);
};
extern
struct
cgroup_ops
*
cgroup_init
(
struct
lxc_conf
*
conf
);
...
...
src/lxc/lxccontainer.c
View file @
0374aacd
...
...
@@ -824,6 +824,15 @@ static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid)
{
int
ret
,
state
;
/* The first child is going to fork() again and then exits. So we reap
* the first child here.
*/
ret
=
wait_for_pid
(
pid
);
if
(
ret
<
0
)
DEBUG
(
"Failed waiting on first child %d"
,
pid
);
else
DEBUG
(
"First child %d exited"
,
pid
);
/* Close write end of the socket pair. */
close
(
handler
->
state_socket_pair
[
1
]);
handler
->
state_socket_pair
[
1
]
=
-
1
;
...
...
@@ -834,15 +843,6 @@ static bool wait_on_daemonized_start(struct lxc_handler *handler, int pid)
close
(
handler
->
state_socket_pair
[
0
]);
handler
->
state_socket_pair
[
0
]
=
-
1
;
/* The first child is going to fork() again and then exits. So we reap
* the first child here.
*/
ret
=
wait_for_pid
(
pid
);
if
(
ret
<
0
)
DEBUG
(
"Failed waiting on first child %d"
,
pid
);
else
DEBUG
(
"First child %d exited"
,
pid
);
if
(
state
<
0
)
{
SYSERROR
(
"Failed to receive the container state"
);
return
false
;
...
...
@@ -935,17 +935,17 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
if
(
c
->
daemonize
)
{
bool
started
;
char
title
[
2048
];
pid_t
pid
;
pid_t
pid
_first
,
pid_second
;
pid
=
fork
();
if
(
pid
<
0
)
{
pid
_first
=
fork
();
if
(
pid
_first
<
0
)
{
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
return
false
;
}
/* first parent */
if
(
pid
!=
0
)
{
if
(
pid
_first
!=
0
)
{
/* Set to NULL because we don't want father unlink
* the PID file, child will do the free and unlink.
*/
...
...
@@ -954,7 +954,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
/* Wait for container to tell us whether it started
* successfully.
*/
started
=
wait_on_daemonized_start
(
handler
,
pid
);
started
=
wait_on_daemonized_start
(
handler
,
pid
_first
);
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
...
...
@@ -980,14 +980,14 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
* POSIX's daemon() function we change to "/" and redirect
* std{in,out,err} to /dev/null.
*/
pid
=
fork
();
if
(
pid
<
0
)
{
pid
_second
=
fork
();
if
(
pid
_second
<
0
)
{
SYSERROR
(
"Failed to fork first child process"
);
_exit
(
EXIT_FAILURE
);
}
/* second parent */
if
(
pid
!=
0
)
{
if
(
pid
_second
!=
0
)
{
free_init_cmd
(
init_cmd
);
lxc_free_handler
(
handler
);
_exit
(
EXIT_SUCCESS
);
...
...
src/lxc/macro.h
View file @
0374aacd
...
...
@@ -448,6 +448,12 @@ enum {
-1; \
})
#define ret_set_errno(__ret__, __errno__) \
({ \
errno = __errno__; \
__ret__; \
})
#define free_replace_move_ptr(a, b) \
({ \
free(a); \
...
...
src/lxc/start.c
View file @
0374aacd
...
...
@@ -737,6 +737,10 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf,
handler
->
nsfd
[
i
]
=
-
1
;
handler
->
name
=
name
;
if
(
daemonize
)
handler
->
transient_pid
=
lxc_raw_getpid
();
else
handler
->
transient_pid
=
-
1
;
if
(
daemonize
&&
handler
->
conf
->
reboot
==
REBOOT_NONE
)
{
/* Create socketpair() to synchronize on daemonized startup.
...
...
@@ -912,7 +916,7 @@ int lxc_init(const char *name, struct lxc_handler *handler)
ret
=
lsm_process_prepare
(
conf
,
handler
->
lxcpath
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to initialize LSM"
);
goto
out_de
stroy_cgroups
;
goto
out_de
lete_terminal
;
}
TRACE
(
"Initialized LSM"
);
...
...
@@ -920,10 +924,6 @@ int lxc_init(const char *name, struct lxc_handler *handler)
handler
->
monitor_status_fd
=
move_fd
(
status_fd
);
return
0
;
out_destroy_cgroups:
handler
->
cgroup_ops
->
payload_destroy
(
handler
->
cgroup_ops
,
handler
);
handler
->
cgroup_ops
->
monitor_destroy
(
handler
->
cgroup_ops
,
handler
);
out_delete_terminal:
lxc_terminal_delete
(
&
handler
->
conf
->
console
);
...
...
@@ -1016,8 +1016,10 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
lsm_process_cleanup
(
handler
->
conf
,
handler
->
lxcpath
);
cgroup_ops
->
payload_destroy
(
cgroup_ops
,
handler
);
cgroup_ops
->
monitor_destroy
(
cgroup_ops
,
handler
);
if
(
cgroup_ops
)
{
cgroup_ops
->
payload_destroy
(
cgroup_ops
,
handler
);
cgroup_ops
->
monitor_destroy
(
cgroup_ops
,
handler
);
}
if
(
handler
->
conf
->
reboot
==
REBOOT_NONE
)
{
/* For all new state clients simply close the command socket.
...
...
@@ -1813,14 +1815,24 @@ static int lxc_spawn(struct lxc_handler *handler)
if
(
ret
<
0
)
goto
out_delete_net
;
if
(
!
cgroup_ops
->
setup_limits
(
cgroup_ops
,
handler
->
conf
,
false
))
{
if
(
!
cgroup_ops
->
setup_limits
_legacy
(
cgroup_ops
,
handler
->
conf
,
false
))
{
ERROR
(
"Failed to setup cgroup limits for container
\"
%s
\"
"
,
name
);
goto
out_delete_net
;
}
if
(
!
cgroup_ops
->
payload_enter
(
cgroup_ops
,
handler
->
pid
))
if
(
!
cgroup_ops
->
payload_enter
(
cgroup_ops
,
handler
))
goto
out_delete_net
;
if
(
!
cgroup_ops
->
payload_delegate_controllers
(
cgroup_ops
))
{
ERROR
(
"Failed to delegate controllers to payload cgroup"
);
goto
out_delete_net
;
}
if
(
!
cgroup_ops
->
setup_limits
(
cgroup_ops
,
handler
))
{
ERROR
(
"Failed to setup cgroup limits for container
\"
%s
\"
"
,
name
);
goto
out_delete_net
;
}
if
(
!
cgroup_ops
->
chown
(
cgroup_ops
,
handler
->
conf
))
goto
out_delete_net
;
...
...
@@ -1883,7 +1895,7 @@ static int lxc_spawn(struct lxc_handler *handler)
if
(
ret
<
0
)
goto
out_delete_net
;
if
(
!
cgroup_ops
->
setup_limits
(
cgroup_ops
,
handler
->
conf
,
true
))
{
if
(
!
cgroup_ops
->
setup_limits
_legacy
(
cgroup_ops
,
handler
->
conf
,
true
))
{
ERROR
(
"Failed to setup legacy device cgroup controller limits"
);
goto
out_delete_net
;
}
...
...
@@ -2015,12 +2027,18 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
goto
out_fini_nonet
;
}
if
(
!
cgroup_ops
->
monitor_enter
(
cgroup_ops
,
handler
->
monitor_pid
))
{
if
(
!
cgroup_ops
->
monitor_enter
(
cgroup_ops
,
handler
))
{
ERROR
(
"Failed to enter monitor cgroup"
);
ret
=
-
1
;
goto
out_fini_nonet
;
}
if
(
!
cgroup_ops
->
monitor_delegate_controllers
(
cgroup_ops
))
{
ERROR
(
"Failed to delegate controllers to monitor cgroup"
);
ret
=
-
1
;
goto
out_fini_nonet
;
}
if
(
geteuid
()
==
0
&&
!
lxc_list_empty
(
&
conf
->
id_map
))
{
/* If the backing store is a device, mount it here and now. */
if
(
rootfs_is_blockdev
(
conf
))
{
...
...
src/lxc/start.h
View file @
0374aacd
...
...
@@ -89,6 +89,9 @@ struct lxc_handler {
*/
int
proc_pidfd
;
/* The grandfather's pid when double-forking. */
pid_t
transient_pid
;
/* The monitor's pid. */
pid_t
monitor_pid
;
...
...
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