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
1f7db633
Unverified
Commit
1f7db633
authored
Feb 16, 2021
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cgroups: rework how hierarchies are added
Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
63a7a2ac
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
90 additions
and
105 deletions
+90
-105
cgfsng.c
src/lxc/cgroups/cgfsng.c
+90
-105
No files found.
src/lxc/cgroups/cgfsng.c
View file @
1f7db633
...
@@ -469,50 +469,101 @@ static char **cg_unified_get_controllers(int dfd, const char *file)
...
@@ -469,50 +469,101 @@ static char **cg_unified_get_controllers(int dfd, const char *file)
return
move_ptr
(
aret
);
return
move_ptr
(
aret
);
}
}
static
struct
hierarchy
*
add_hierarchy
(
struct
cgroup_ops
*
ops
,
static
bool
cgroup_use_wants_controllers
(
const
struct
cgroup_ops
*
ops
,
char
**
clist
,
char
*
mountpoint
,
char
**
controllers
)
char
*
container_base_path
,
int
type
)
{
if
(
!
ops
->
cgroup_use
)
return
true
;
for
(
char
**
cur_ctrl
=
controllers
;
cur_ctrl
&&
*
cur_ctrl
;
cur_ctrl
++
)
{
bool
found
=
false
;
for
(
char
**
cur_use
=
ops
->
cgroup_use
;
cur_use
&&
*
cur_use
;
cur_use
++
)
{
if
(
!
strequal
(
*
cur_use
,
*
cur_ctrl
))
continue
;
found
=
true
;
break
;
}
if
(
found
)
continue
;
return
false
;
}
return
true
;
}
static
int
add_hierarchy
(
struct
cgroup_ops
*
ops
,
char
**
clist
,
char
*
mountpoint
,
char
*
container_base_path
,
int
type
)
{
{
__do_close
int
dfd_base
=
-
EBADF
,
dfd_mnt
=
-
EBADF
;
__do_close
int
dfd_base
=
-
EBADF
,
dfd_mnt
=
-
EBADF
;
__do_free
struct
hierarchy
*
new
=
NULL
;
__do_free
struct
hierarchy
*
new
=
NULL
;
__do_free_string_list
char
**
controllers
=
clist
;
int
newentry
;
int
newentry
;
if
(
abspath
(
container_base_path
))
if
(
abspath
(
container_base_path
))
return
syserrno
(
NULL
,
"Container base path must be relative to controller mount"
);
return
syserrno
(
-
errno
,
"Container base path must be relative to controller mount"
);
if
(
!
controllers
&&
type
!=
CGROUP2_SUPER_MAGIC
)
return
syserrno_set
(
-
EINVAL
,
"Empty controller list for non-unified cgroup hierarchy passed"
);
dfd_mnt
=
open_at
(
-
EBADF
,
mountpoint
,
PROTECT_OPATH_DIRECTORY
,
PROTECT_LOOKUP_ABSOLUTE_XDEV
,
0
);
if
(
dfd_mnt
<
0
)
return
syserrno
(
-
errno
,
"Failed to open %s"
,
mountpoint
);
if
(
is_empty_string
(
container_base_path
))
dfd_base
=
dfd_mnt
;
else
dfd_base
=
open_at
(
dfd_mnt
,
container_base_path
,
PROTECT_OPATH_DIRECTORY
,
PROTECT_LOOKUP_BENEATH_XDEV
,
0
);
if
(
dfd_base
<
0
)
return
syserrno
(
-
errno
,
"Failed to open %d(%s)"
,
dfd_base
,
container_base_path
);
if
(
!
controllers
)
{
/*
* We assume that the cgroup we're currently in has been delegated to
* us and we are free to further delege all of the controllers listed
* in cgroup.controllers further down the hierarchy.
*/
controllers
=
cg_unified_get_controllers
(
dfd_base
,
"cgroup.controllers"
);
if
(
!
controllers
)
controllers
=
cg_unified_make_empty_controller
();
if
(
!
controllers
[
0
])
TRACE
(
"No controllers are enabled for delegation"
);
}
/* Exclude all controllers that cgroup use does not want. */
if
(
!
cgroup_use_wants_controllers
(
ops
,
controllers
))
return
log_trace
(
0
,
"Skipping cgroup hiearchy with non-requested controllers"
);
new
=
zalloc
(
sizeof
(
*
new
));
new
=
zalloc
(
sizeof
(
*
new
));
if
(
!
new
)
if
(
!
new
)
return
ret_
set_errno
(
NULL
,
ENOMEM
);
return
ret_
errno
(
ENOMEM
);
new
->
version
=
type
;
new
->
version
=
type
;
new
->
controllers
=
clist
;
new
->
controllers
=
move_ptr
(
controllers
)
;
new
->
mountpoint
=
mountpoint
;
new
->
mountpoint
=
mountpoint
;
new
->
container_base_path
=
container_base_path
;
new
->
container_base_path
=
container_base_path
;
new
->
cgfd_con
=
-
EBADF
;
new
->
cgfd_con
=
-
EBADF
;
new
->
cgfd_limit
=
-
EBADF
;
new
->
cgfd_limit
=
-
EBADF
;
new
->
cgfd_mon
=
-
EBADF
;
new
->
cgfd_mon
=
-
EBADF
;
dfd_mnt
=
open_at
(
-
EBADF
,
mountpoint
,
PROTECT_OPATH_DIRECTORY
,
TRACE
(
"Adding cgroup hierarchy with mountpoint %s and base cgroup %s"
,
PROTECT_LOOKUP_ABSOLUTE_XDEV
,
0
);
mountpoint
,
container_base_path
);
if
(
dfd_mnt
<
0
)
for
(
char
*
const
*
it
=
new
->
controllers
;
it
&&
*
it
;
it
++
)
return
syserrno
(
NULL
,
"Failed to open %s"
,
mountpoint
);
TRACE
(
"The detected hierarchy contains the %s controller"
,
*
it
);
dfd_base
=
open_at
(
dfd_mnt
,
container_base_path
,
PROTECT_OPATH_DIRECTORY
,
PROTECT_LOOKUP_BENEATH_XDEV
,
0
);
if
(
dfd_base
<
0
)
return
syserrno
(
NULL
,
"Failed to open %d(%s)"
,
dfd_base
,
container_base_path
);
TRACE
(
"Adding cgroup hierarchy with mountpoint %s and base cgroup %s %s"
,
mountpoint
,
container_base_path
,
(
clist
&&
*
clist
)
?
"with controllers "
:
"without any controllers"
);
for
(
char
*
const
*
it
=
clist
;
it
&&
*
it
;
it
++
)
TRACE
(
"%s"
,
*
it
);
newentry
=
append_null_to_list
((
void
***
)
&
ops
->
hierarchies
);
newentry
=
append_null_to_list
((
void
***
)
&
ops
->
hierarchies
);
new
->
dfd_mnt
=
move_fd
(
dfd_mnt
);
new
->
dfd_mnt
=
move_fd
(
dfd_mnt
);
new
->
dfd_base
=
move_fd
(
dfd_base
);
new
->
dfd_base
=
move_fd
(
dfd_base
);
(
ops
->
hierarchies
)[
newentry
]
=
new
;
if
(
type
==
CGROUP2_SUPER_MAGIC
)
return
move_ptr
(
new
);
ops
->
unified
=
new
;
(
ops
->
hierarchies
)[
newentry
]
=
move_ptr
(
new
);
return
0
;
}
}
/* Get a copy of the mountpoint from @line, which is a line from
/* Get a copy of the mountpoint from @line, which is a line from
...
@@ -3222,32 +3273,6 @@ __cgfsng_ops static bool cgfsng_payload_delegate_controllers(struct cgroup_ops *
...
@@ -3222,32 +3273,6 @@ __cgfsng_ops static bool cgfsng_payload_delegate_controllers(struct cgroup_ops *
return
__cgfsng_delegate_controllers
(
ops
,
ops
->
container_cgroup
);
return
__cgfsng_delegate_controllers
(
ops
,
ops
->
container_cgroup
);
}
}
static
bool
cgroup_use_wants_controllers
(
const
struct
cgroup_ops
*
ops
,
char
**
controllers
)
{
if
(
!
ops
->
cgroup_use
)
return
true
;
for
(
char
**
cur_ctrl
=
controllers
;
cur_ctrl
&&
*
cur_ctrl
;
cur_ctrl
++
)
{
bool
found
=
false
;
for
(
char
**
cur_use
=
ops
->
cgroup_use
;
cur_use
&&
*
cur_use
;
cur_use
++
)
{
if
(
!
strequal
(
*
cur_use
,
*
cur_ctrl
))
continue
;
found
=
true
;
break
;
}
if
(
found
)
continue
;
return
false
;
}
return
true
;
}
static
void
cg_unified_delegate
(
char
***
delegate
)
static
void
cg_unified_delegate
(
char
***
delegate
)
{
{
__do_free
char
*
buf
=
NULL
;
__do_free
char
*
buf
=
NULL
;
...
@@ -3314,7 +3339,6 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg
...
@@ -3314,7 +3339,6 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg
__do_free_string_list
char
**
controller_list
=
NULL
;
__do_free_string_list
char
**
controller_list
=
NULL
;
int
type
;
int
type
;
bool
writeable
;
bool
writeable
;
struct
hierarchy
*
new
;
type
=
get_cgroup_version
(
line
);
type
=
get_cgroup_version
(
line
);
if
(
type
==
0
)
if
(
type
==
0
)
...
@@ -3370,36 +3394,14 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg
...
@@ -3370,36 +3394,14 @@ static int cg_hybrid_init(struct cgroup_ops *ops, bool relative, bool unprivileg
continue
;
continue
;
}
}
if
(
type
==
CGROUP2_SUPER_MAGIC
)
{
if
(
type
==
CGROUP2_SUPER_MAGIC
)
char
*
cgv2_ctrl_path
;
ret
=
add_hierarchy
(
ops
,
NULL
,
move_ptr
(
mountpoint
),
move_ptr
(
base_cgroup
),
type
);
else
cgv2_ctrl_path
=
must_make_path
(
mountpoint
,
base_cgroup
,
ret
=
add_hierarchy
(
ops
,
move_ptr
(
controller_list
),
move_ptr
(
mountpoint
),
move_ptr
(
base_cgroup
),
type
);
"cgroup.controllers"
,
if
(
ret
)
NULL
);
return
syserrno
(
ret
,
"Failed to add cgroup hierarchy"
);
if
(
ops
->
unified
&&
unprivileged
)
controller_list
=
cg_unified_get_controllers
(
-
EBADF
,
cgv2_ctrl_path
);
cg_unified_delegate
(
&
(
ops
->
unified
)
->
cgroup2_chown
);
free
(
cgv2_ctrl_path
);
if
(
!
controller_list
)
{
controller_list
=
cg_unified_make_empty_controller
();
TRACE
(
"No controllers are enabled for "
"delegation in the unified hierarchy"
);
}
}
/* Exclude all controllers that cgroup use does not want. */
if
(
!
cgroup_use_wants_controllers
(
ops
,
controller_list
))
{
TRACE
(
"Skipping controller"
);
continue
;
}
new
=
add_hierarchy
(
ops
,
move_ptr
(
controller_list
),
move_ptr
(
mountpoint
),
move_ptr
(
base_cgroup
),
type
);
if
(
!
new
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to add cgroup hierarchy"
);
if
(
type
==
CGROUP2_SUPER_MAGIC
&&
!
ops
->
unified
)
{
if
(
unprivileged
)
cg_unified_delegate
(
&
new
->
cgroup2_chown
);
ops
->
unified
=
new
;
}
}
}
/* verify that all controllers in cgroup.use and all crucial
/* verify that all controllers in cgroup.use and all crucial
...
@@ -3452,26 +3454,13 @@ static char *cg_unified_get_current_cgroup(bool relative)
...
@@ -3452,26 +3454,13 @@ static char *cg_unified_get_current_cgroup(bool relative)
static
int
cg_unified_init
(
struct
cgroup_ops
*
ops
,
bool
relative
,
static
int
cg_unified_init
(
struct
cgroup_ops
*
ops
,
bool
relative
,
bool
unprivileged
)
bool
unprivileged
)
{
{
__do_free
char
*
base_cgroup
=
NULL
,
*
controllers_path
=
NULL
;
__do_free
char
*
base_cgroup
=
NULL
;
__do_free_string_list
char
**
delegatable
=
NULL
;
int
ret
;
__do_free
struct
hierarchy
*
new
=
NULL
;
base_cgroup
=
cg_unified_get_current_cgroup
(
relative
);
base_cgroup
=
cg_unified_get_current_cgroup
(
relative
);
if
(
!
base_cgroup
)
if
(
!
base_cgroup
)
return
ret_errno
(
EINVAL
);
return
ret_errno
(
EINVAL
);
/*
* We assume that the cgroup we're currently in has been delegated to
* us and we are free to further delege all of the controllers listed
* in cgroup.controllers further down the hierarchy.
*/
controllers_path
=
must_make_path_relative
(
base_cgroup
,
"cgroup.controllers"
,
NULL
);
delegatable
=
cg_unified_get_controllers
(
ops
->
dfd_mnt_cgroupfs_host
,
controllers_path
);
if
(
!
delegatable
)
delegatable
=
cg_unified_make_empty_controller
();
if
(
!
delegatable
[
0
])
TRACE
(
"No controllers are enabled for delegation"
);
/* TODO: If the user requested specific controllers via lxc.cgroup.use
/* TODO: If the user requested specific controllers via lxc.cgroup.use
* we should verify here. The reason I'm not doing it right is that I'm
* we should verify here. The reason I'm not doing it right is that I'm
* not convinced that lxc.cgroup.use will be the future since it is a
* not convinced that lxc.cgroup.use will be the future since it is a
...
@@ -3479,23 +3468,19 @@ static int cg_unified_init(struct cgroup_ops *ops, bool relative,
...
@@ -3479,23 +3468,19 @@ static int cg_unified_init(struct cgroup_ops *ops, bool relative,
* controllers per container.
* controllers per container.
*/
*/
new
=
add_hierarchy
(
ops
,
ret
=
add_hierarchy
(
ops
,
NULL
,
move_ptr
(
delegatable
),
must_copy_string
(
DEFAULT_CGROUP_MOUNTPOINT
),
must_copy_string
(
DEFAULT_CGROUP_MOUNTPOINT
),
move_ptr
(
base_cgroup
),
move_ptr
(
base_cgroup
),
CGROUP2_SUPER_MAGIC
);
CGROUP2_SUPER_MAGIC
);
if
(
ret
)
if
(
!
new
)
return
syserrno
(
ret
,
"Failed to add unified cgroup hierarchy"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add unified cgroup hierarchy"
);
if
(
unprivileged
)
if
(
unprivileged
)
cg_unified_delegate
(
&
new
->
cgroup2_chown
);
cg_unified_delegate
(
&
(
ops
->
unified
)
->
cgroup2_chown
);
if
(
bpf_devices_cgroup_supported
())
if
(
bpf_devices_cgroup_supported
())
new
->
bpf_device_controller
=
1
;
ops
->
unified
->
bpf_device_controller
=
1
;
ops
->
cgroup_layout
=
CGROUP_LAYOUT_UNIFIED
;
ops
->
cgroup_layout
=
CGROUP_LAYOUT_UNIFIED
;
ops
->
unified
=
move_ptr
(
new
);
return
CGROUP2_SUPER_MAGIC
;
return
CGROUP2_SUPER_MAGIC
;
}
}
...
...
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