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
394769b1
Unverified
Commit
394769b1
authored
May 22, 2018
by
Serge Hallyn
Committed by
GitHub
May 22, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2337 from brauner/2018-05-18/cgroup_rework
cgroups: refactor cgroup handling
parents
f49098e0
395b1a3e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
255 additions
and
301 deletions
+255
-301
attach.c
src/lxc/attach.c
+10
-3
cgfsng.c
src/lxc/cgroups/cgfsng.c
+0
-0
cgroup.c
src/lxc/cgroups/cgroup.c
+35
-154
cgroup.h
src/lxc/cgroups/cgroup.h
+102
-36
commands.c
src/lxc/commands.c
+5
-3
conf.c
src/lxc/conf.c
+7
-5
criu.c
src/lxc/criu.c
+20
-14
freezer.c
src/lxc/freezer.c
+11
-17
lxc.h
src/lxc/lxc.h
+0
-23
lxccontainer.c
src/lxc/lxccontainer.c
+19
-2
seccomp.c
src/lxc/seccomp.c
+8
-6
start.c
src/lxc/start.c
+17
-20
start.h
src/lxc/start.h
+2
-0
state.c
src/lxc/state.c
+1
-6
cgpath.c
src/tests/cgpath.c
+18
-12
No files found.
src/lxc/attach.c
View file @
394769b1
...
...
@@ -1272,10 +1272,17 @@ int lxc_attach(const char *name, const char *lxcpath,
/* Attach to cgroup, if requested. */
if
(
options
->
attach_flags
&
LXC_ATTACH_MOVE_TO_CGROUP
)
{
if
(
!
cgroup_attach
(
name
,
lxcpath
,
pid
))
struct
cgroup_ops
*
cgroup_ops
;
cgroup_ops
=
cgroup_init
(
NULL
);
if
(
!
cgroup_ops
)
goto
on_error
;
if
(
!
cgroup_ops
->
attach
(
cgroup_ops
,
name
,
lxcpath
,
pid
))
goto
on_error
;
TRACE
(
"Moved intermediate process %d into container's "
"cgroups"
,
pid
);
cgroup_exit
(
cgroup_ops
);
TRACE
(
"Moved intermediate process %d into container's cgroups"
,
pid
);
}
/* Setup /proc limits */
...
...
src/lxc/cgroups/cgfsng.c
View file @
394769b1
This diff is collapsed.
Click to expand it.
src/lxc/cgroups/cgroup.c
View file @
394769b1
...
...
@@ -32,180 +32,61 @@
lxc_log_define
(
lxc_cgroup
,
lxc
);
static
struct
cgroup_ops
*
ops
=
NULL
;
extern
struct
cgroup_ops
*
cgfsng_ops_init
(
void
);
__attribute__
((
constructor
))
void
cgroup_ops_init
(
void
)
struct
cgroup_ops
*
cgroup_init
(
struct
lxc_handler
*
handler
)
{
if
(
ops
)
{
INFO
(
"Running with %s in version %s"
,
ops
->
driver
,
ops
->
version
);
return
;
}
DEBUG
(
"cgroup_init"
);
ops
=
cgfsng_ops_init
();
if
(
ops
)
INFO
(
"Initialized cgroup driver %s"
,
ops
->
driver
);
}
struct
cgroup_ops
*
cgroup_ops
;
bool
cgroup_init
(
struct
lxc_handler
*
handler
)
{
if
(
handler
->
cgroup_data
)
{
ERROR
(
"cgroup_init called on already initialized handler"
);
return
true
;
cgroup_ops
=
cgfsng_ops_init
();
if
(
!
cgroup_ops
)
{
ERROR
(
"Failed to initialize cgroup driver"
);
return
NULL
;
}
if
(
ops
)
{
INFO
(
"cgroup driver %s initing for %s"
,
ops
->
driver
,
handler
->
name
);
handler
->
cgroup_data
=
ops
->
init
(
handler
);
}
if
(
!
cgroup_ops
->
data_init
(
cgroup_ops
))
return
NULL
;
return
handler
->
cgroup_data
!=
NULL
;
}
TRACE
(
"Initialized cgroup driver %s"
,
cgroup_ops
->
driver
);
void
cgroup_destroy
(
struct
lxc_handler
*
handler
)
{
if
(
ops
)
{
ops
->
destroy
(
handler
->
cgroup_data
,
handler
->
conf
);
handler
->
cgroup_data
=
NULL
;
}
}
if
(
cgroup_ops
->
cgroup_layout
==
CGROUP_LAYOUT_LEGACY
)
TRACE
(
"Running with legacy cgroup layout"
);
else
if
(
cgroup_ops
->
cgroup_layout
==
CGROUP_LAYOUT_HYBRID
)
TRACE
(
"Running with hybrid cgroup layout"
);
else
if
(
cgroup_ops
->
cgroup_layout
==
CGROUP_LAYOUT_UNIFIED
)
TRACE
(
"Running with unified cgroup layout"
);
else
WARN
(
"Running with unknown cgroup layout"
);
/* Create the container cgroups for all requested controllers. */
bool
cgroup_create
(
struct
lxc_handler
*
handler
)
{
if
(
ops
)
return
ops
->
create
(
handler
->
cgroup_data
);
return
false
;
return
cgroup_ops
;
}
/* Enter the container init into its new cgroups for all requested controllers. */
bool
cgroup_enter
(
struct
lxc_handler
*
handler
)
void
cgroup_exit
(
struct
cgroup_ops
*
ops
)
{
if
(
ops
)
return
ops
->
enter
(
handler
->
cgroup_data
,
handler
->
pid
);
struct
hierarchy
**
it
;
return
false
;
}
bool
cgroup_create_legacy
(
struct
lxc_handler
*
handler
)
{
if
(
ops
&&
ops
->
create_legacy
)
return
ops
->
create_legacy
(
handler
->
cgroup_data
,
handler
->
pid
);
return
true
;
}
const
char
*
cgroup_get_cgroup
(
struct
lxc_handler
*
handler
,
const
char
*
subsystem
)
{
if
(
ops
)
return
ops
->
get_cgroup
(
handler
->
cgroup_data
,
subsystem
);
return
NULL
;
}
bool
cgroup_escape
(
struct
lxc_handler
*
handler
)
{
if
(
ops
)
return
ops
->
escape
(
handler
->
cgroup_data
);
return
false
;
}
int
cgroup_num_hierarchies
(
void
)
{
if
(
!
ops
)
return
-
1
;
return
ops
->
num_hierarchies
();
}
bool
cgroup_get_hierarchies
(
int
n
,
char
***
out
)
{
if
(
!
ops
)
return
false
;
return
ops
->
get_hierarchies
(
n
,
out
);
}
bool
cgroup_unfreeze
(
struct
lxc_handler
*
handler
)
{
if
(
ops
)
return
ops
->
unfreeze
(
handler
->
cgroup_data
);
return
false
;
}
bool
cgroup_setup_limits
(
struct
lxc_handler
*
handler
,
bool
with_devices
)
{
if
(
ops
)
return
ops
->
setup_limits
(
handler
->
cgroup_data
,
handler
->
conf
,
with_devices
);
return
false
;
}
return
;
bool
cgroup_chown
(
struct
lxc_handler
*
handler
)
{
if
(
ops
&&
ops
->
chown
)
return
ops
->
chown
(
handler
->
cgroup_data
,
handler
->
conf
);
free
(
ops
->
cgroup_use
);
free
(
ops
->
cgroup_pattern
);
free
(
ops
->
container_cgroup
);
return
true
;
}
for
(
it
=
ops
->
hierarchies
;
it
&&
*
it
;
it
++
)
{
char
**
ctrlr
;
bool
cgroup_mount
(
const
char
*
root
,
struct
lxc_handler
*
handler
,
int
type
)
{
if
(
ops
)
return
ops
->
mount_cgroup
(
handler
,
root
,
type
);
return
false
;
}
for
(
ctrlr
=
(
*
it
)
->
controllers
;
ctrlr
&&
*
ctrlr
;
ctrlr
++
)
free
(
*
ctrlr
);
free
((
*
it
)
->
controllers
);
int
cgroup_nrtasks
(
struct
lxc_handler
*
handler
)
{
if
(
ops
)
{
if
(
ops
->
nrtasks
)
return
ops
->
nrtasks
(
handler
->
cgroup_data
);
else
WARN
(
"cgroup driver
\"
%s
\"
doesn't implement nrtasks"
,
ops
->
driver
);
free
((
*
it
)
->
mountpoint
);
free
((
*
it
)
->
base_cgroup
);
free
((
*
it
)
->
fullcgpath
);
free
(
*
it
);
}
free
(
ops
->
hierarchies
);
return
-
1
;
}
bool
cgroup_attach
(
const
char
*
name
,
const
char
*
lxcpath
,
pid_t
pid
)
{
if
(
ops
)
return
ops
->
attach
(
name
,
lxcpath
,
pid
);
return
false
;
}
int
lxc_cgroup_set
(
const
char
*
filename
,
const
char
*
value
,
const
char
*
name
,
const
char
*
lxcpath
)
{
if
(
ops
)
return
ops
->
set
(
filename
,
value
,
name
,
lxcpath
);
return
-
1
;
}
int
lxc_cgroup_get
(
const
char
*
filename
,
char
*
value
,
size_t
len
,
const
char
*
name
,
const
char
*
lxcpath
)
{
if
(
ops
)
return
ops
->
get
(
filename
,
value
,
len
,
name
,
lxcpath
);
return
-
1
;
}
void
cgroup_disconnect
(
void
)
{
if
(
ops
&&
ops
->
disconnect
)
ops
->
disconnect
();
return
;
}
#define INIT_SCOPE "/init.scope"
...
...
src/lxc/cgroups/cgroup.h
View file @
394769b1
...
...
@@ -39,48 +39,114 @@ typedef enum {
CGROUP_LAYOUT_UNIFIED
=
2
,
}
cgroup_layout_t
;
/* A descriptor for a mounted hierarchy
*
* @controllers
* - legacy hierarchy
* Either NULL, or a null-terminated list of all the co-mounted controllers.
* - unified hierarchy
* Either NULL, or a null-terminated list of all enabled controllers.
*
* @mountpoint
* - The mountpoint we will use.
* - legacy hierarchy
* It will be either /sys/fs/cgroup/controller or
* /sys/fs/cgroup/controllerlist.
* - unified hierarchy
* It will either be /sys/fs/cgroup or /sys/fs/cgroup/<mountpoint-name>
* depending on whether this is a hybrid cgroup layout (mix of legacy and
* unified hierarchies) or a pure unified cgroup layout.
*
* @base_cgroup
* - The cgroup under which the container cgroup path
* is created. This will be either the caller's cgroup (if not root), or
* init's cgroup (if root).
*
* @fullcgpath
* - The full path to the containers cgroup.
*
* @version
* - legacy hierarchy
* If the hierarchy is a legacy hierarchy this will be set to
* CGROUP_SUPER_MAGIC.
* - unified hierarchy
* If the hierarchy is a legacy hierarchy this will be set to
* CGROUP2_SUPER_MAGIC.
*/
struct
hierarchy
{
char
**
controllers
;
char
*
mountpoint
;
char
*
base_cgroup
;
char
*
fullcgpath
;
int
version
;
};
struct
cgroup_ops
{
/* string constant */
const
char
*
driver
;
/* string constant */
const
char
*
version
;
void
*
(
*
init
)(
struct
lxc_handler
*
handler
);
void
(
*
destroy
)(
void
*
hdata
,
struct
lxc_conf
*
conf
);
bool
(
*
create
)(
void
*
hdata
);
bool
(
*
enter
)(
void
*
hdata
,
pid_t
pid
);
bool
(
*
create_legacy
)(
void
*
hdata
,
pid_t
pid
);
const
char
*
(
*
get_cgroup
)(
void
*
hdata
,
const
char
*
subsystem
);
bool
(
*
escape
)();
int
(
*
num_hierarchies
)();
bool
(
*
get_hierarchies
)(
int
n
,
char
***
out
);
int
(
*
set
)(
const
char
*
filename
,
const
char
*
value
,
const
char
*
name
,
const
char
*
lxcpath
);
int
(
*
get
)(
const
char
*
filename
,
char
*
value
,
size_t
len
,
const
char
*
name
,
const
char
*
lxcpath
);
bool
(
*
unfreeze
)(
void
*
hdata
);
bool
(
*
setup_limits
)(
void
*
hdata
,
struct
lxc_conf
*
conf
,
bool
with_devices
);
bool
(
*
chown
)(
void
*
hdata
,
struct
lxc_conf
*
conf
);
bool
(
*
attach
)(
const
char
*
name
,
const
char
*
lxcpath
,
pid_t
pid
);
bool
(
*
mount_cgroup
)(
void
*
hdata
,
const
char
*
root
,
int
type
);
int
(
*
nrtasks
)(
void
*
hdata
);
void
(
*
disconnect
)(
void
);
/* What controllers is the container supposed to use. */
char
*
cgroup_use
;
char
*
cgroup_pattern
;
char
*
container_cgroup
;
/* @hierarchies
* - A NULL-terminated array of struct hierarchy, one per legacy
* hierarchy. No duplicates. First sufficient, writeable mounted
* hierarchy wins.
*/
struct
hierarchy
**
hierarchies
;
struct
hierarchy
*
unified
;
/*
* @cgroup_layout
* - What cgroup layout the container is running with.
* - CGROUP_LAYOUT_UNKNOWN
* The cgroup layout could not be determined. This should be treated
* as an error condition.
* - CGROUP_LAYOUT_LEGACY
* The container is running with all controllers mounted into legacy
* cgroup hierarchies.
* - CGROUP_LAYOUT_HYBRID
* The container is running with at least one controller mounted
* into a legacy cgroup hierarchy and a mountpoint for the unified
* hierarchy. The unified hierarchy can be empty (no controllers
* enabled) or non-empty (controllers enabled).
* - CGROUP_LAYOUT_UNIFIED
* The container is running on a pure unified cgroup hierarchy. The
* unified hierarchy can be empty (no controllers enabled) or
* non-empty (controllers enabled).
*/
cgroup_layout_t
cgroup_layout
;
bool
(
*
data_init
)(
struct
cgroup_ops
*
ops
);
void
(
*
destroy
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
create
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
enter
)(
struct
cgroup_ops
*
ops
,
pid_t
pid
);
const
char
*
(
*
get_cgroup
)(
struct
cgroup_ops
*
ops
,
const
char
*
controller
);
bool
(
*
escape
)(
const
struct
cgroup_ops
*
ops
);
int
(
*
num_hierarchies
)(
struct
cgroup_ops
*
ops
);
bool
(
*
get_hierarchies
)(
struct
cgroup_ops
*
ops
,
int
n
,
char
***
out
);
int
(
*
set
)(
struct
cgroup_ops
*
ops
,
const
char
*
filename
,
const
char
*
value
,
const
char
*
name
,
const
char
*
lxcpath
);
int
(
*
get
)(
struct
cgroup_ops
*
ops
,
const
char
*
filename
,
char
*
value
,
size_t
len
,
const
char
*
name
,
const
char
*
lxcpath
);
bool
(
*
unfreeze
)(
struct
cgroup_ops
*
ops
);
bool
(
*
setup_limits
)(
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
,
bool
with_devices
);
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
);
bool
(
*
mount
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
,
const
char
*
root
,
int
type
);
int
(
*
nrtasks
)(
struct
cgroup_ops
*
ops
);
};
extern
bool
cgroup_attach
(
const
char
*
name
,
const
char
*
lxcpath
,
pid_t
pid
);
extern
bool
cgroup_mount
(
const
char
*
root
,
struct
lxc_handler
*
handler
,
int
type
);
extern
void
cgroup_destroy
(
struct
lxc_handler
*
handler
);
extern
bool
cgroup_init
(
struct
lxc_handler
*
handler
);
extern
bool
cgroup_create
(
struct
lxc_handler
*
handler
);
extern
bool
cgroup_setup_limits
(
struct
lxc_handler
*
handler
,
bool
with_devices
);
extern
bool
cgroup_chown
(
struct
lxc_handler
*
handler
);
extern
bool
cgroup_enter
(
struct
lxc_handler
*
handler
);
extern
void
cgroup_cleanup
(
struct
lxc_handler
*
handler
);
extern
bool
cgroup_create_legacy
(
struct
lxc_handler
*
handler
);
extern
int
cgroup_nrtasks
(
struct
lxc_handler
*
handler
);
extern
const
char
*
cgroup_get_cgroup
(
struct
lxc_handler
*
handler
,
const
char
*
subsystem
);
extern
bool
cgroup_escape
();
extern
int
cgroup_num_hierarchies
();
extern
bool
cgroup_get_hierarchies
(
int
i
,
char
***
out
);
extern
bool
cgroup_unfreeze
(
struct
lxc_handler
*
handler
);
extern
void
cgroup_disconnect
(
void
);
extern
struct
cgroup_ops
*
cgroup_init
(
struct
lxc_handler
*
handler
);
extern
void
cgroup_exit
(
struct
cgroup_ops
*
ops
);
extern
void
prune_init_scope
(
char
*
cg
);
extern
bool
is_crucial_cgroup_subsystem
(
const
char
*
s
);
...
...
src/lxc/commands.c
View file @
394769b1
...
...
@@ -473,11 +473,12 @@ static int lxc_cmd_get_cgroup_callback(int fd, struct lxc_cmd_req *req,
{
const
char
*
path
;
struct
lxc_cmd_rsp
rsp
;
struct
cgroup_ops
*
cgroup_ops
=
handler
->
cgroup_ops
;
if
(
req
->
datalen
>
0
)
path
=
cgroup_
get_cgroup
(
handler
,
req
->
data
);
path
=
cgroup_
ops
->
get_cgroup
(
cgroup_ops
,
req
->
data
);
else
path
=
cgroup_
get_cgroup
(
handler
,
NULL
);
path
=
cgroup_
ops
->
get_cgroup
(
cgroup_ops
,
NULL
);
if
(
!
path
)
return
-
1
;
...
...
@@ -637,6 +638,7 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
{
struct
lxc_cmd_rsp
rsp
;
int
stopsignal
=
SIGKILL
;
struct
cgroup_ops
*
cgroup_ops
=
handler
->
cgroup_ops
;
if
(
handler
->
conf
->
stopsignal
)
stopsignal
=
handler
->
conf
->
stopsignal
;
...
...
@@ -648,7 +650,7 @@ static int lxc_cmd_stop_callback(int fd, struct lxc_cmd_req *req,
* lxc_unfreeze() would do another cmd (GET_CGROUP) which would
* deadlock us.
*/
if
(
cgroup_
unfreeze
(
handler
))
if
(
cgroup_
ops
->
unfreeze
(
cgroup_ops
))
return
0
;
ERROR
(
"Failed to unfreeze container
\"
%s
\"
"
,
handler
->
name
);
...
...
src/lxc/conf.c
View file @
394769b1
...
...
@@ -757,7 +757,10 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha
if
(
flags
&
LXC_AUTO_CGROUP_FORCE
)
cg_flags
|=
LXC_AUTO_CGROUP_FORCE
;
if
(
!
cgroup_mount
(
conf
->
rootfs
.
path
?
conf
->
rootfs
.
mount
:
""
,
handler
,
cg_flags
))
{
if
(
!
handler
->
cgroup_ops
->
mount
(
handler
->
cgroup_ops
,
handler
,
conf
->
rootfs
.
path
?
conf
->
rootfs
.
mount
:
""
,
cg_flags
))
{
SYSERROR
(
"Failed to mount
\"
/sys/fs/cgroup
\"
"
);
return
-
1
;
}
...
...
@@ -2699,13 +2702,13 @@ int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
buflen
=
sizeof
(
"deny
\n
"
)
-
1
;
errno
=
0
;
ret
=
lxc_write_nointr
(
fd
,
"deny
\n
"
,
buflen
);
close
(
fd
);
if
(
ret
!=
buflen
)
{
SYSERROR
(
"Failed to write
\"
deny
\"
to "
"
\"
/proc/%d/setgroups
\"
"
,
pid
);
close
(
fd
);
return
-
1
;
}
close
(
f
d
);
TRACE
(
"Wrote
\"
deny
\"
to
\"
/proc/%d/setgroups
\"
"
,
pi
d
);
}
}
...
...
@@ -2722,13 +2725,12 @@ int write_id_mapping(enum idtype idtype, pid_t pid, const char *buf,
errno
=
0
;
ret
=
lxc_write_nointr
(
fd
,
buf
,
buf_size
);
close
(
fd
);
if
(
ret
!=
buf_size
)
{
SYSERROR
(
"Failed to write %cid mapping to
\"
%s
\"
"
,
idtype
==
ID_TYPE_UID
?
'u'
:
'g'
,
path
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
0
;
}
...
...
src/lxc/criu.c
View file @
394769b1
...
...
@@ -171,7 +171,7 @@ static int cmp_version(const char *v1, const char *v2)
return
-
1
;
}
static
void
exec_criu
(
struct
criu_opts
*
opts
)
static
void
exec_criu
(
struct
c
group_ops
*
cgroup_ops
,
struct
c
riu_opts
*
opts
)
{
char
**
argv
,
log
[
PATH_MAX
];
int
static_args
=
23
,
argc
=
0
,
i
,
ret
;
...
...
@@ -190,7 +190,7 @@ static void exec_criu(struct criu_opts *opts)
* /actual/ root cgroup so that lxcfs thinks criu has enough rights to
* see all cgroups.
*/
if
(
!
cgroup_
escape
(
))
{
if
(
!
cgroup_
ops
->
escape
(
cgroup_ops
))
{
ERROR
(
"failed to escape cgroups"
);
return
;
}
...
...
@@ -248,8 +248,8 @@ static void exec_criu(struct criu_opts *opts)
return
;
}
if
(
cgroup_
num_hierarchies
(
)
>
0
)
static_args
+=
2
*
cgroup_
num_hierarchies
(
);
if
(
cgroup_
ops
->
num_hierarchies
(
cgroup_ops
)
>
0
)
static_args
+=
2
*
cgroup_
ops
->
num_hierarchies
(
cgroup_ops
);
if
(
opts
->
user
->
verbose
)
static_args
++
;
...
...
@@ -306,11 +306,11 @@ static void exec_criu(struct criu_opts *opts)
DECLARE_ARG
(
"-o"
);
DECLARE_ARG
(
log
);
for
(
i
=
0
;
i
<
cgroup_
num_hierarchies
(
);
i
++
)
{
for
(
i
=
0
;
i
<
cgroup_
ops
->
num_hierarchies
(
cgroup_ops
);
i
++
)
{
char
**
controllers
=
NULL
,
*
fullname
;
char
*
path
,
*
tmp
;
if
(
!
cgroup_
get_hierarchies
(
i
,
&
controllers
))
{
if
(
!
cgroup_
ops
->
get_hierarchies
(
cgroup_ops
,
i
,
&
controllers
))
{
ERROR
(
"failed to get hierarchy %d"
,
i
);
goto
err
;
}
...
...
@@ -328,7 +328,7 @@ static void exec_criu(struct criu_opts *opts)
}
else
{
const
char
*
p
;
p
=
cgroup_
get_cgroup
(
opts
->
handler
,
controllers
[
0
]);
p
=
cgroup_
ops
->
get_cgroup
(
cgroup_ops
,
controllers
[
0
]);
if
(
!
p
)
{
ERROR
(
"failed to get cgroup path for %s"
,
controllers
[
0
]);
goto
err
;
...
...
@@ -937,6 +937,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
struct
lxc_handler
*
handler
;
int
status
=
0
;
int
pipes
[
2
]
=
{
-
1
,
-
1
};
struct
cgroup_ops
*
cgroup_ops
;
/* Try to detach from the current controlling tty if it exists.
* Othwerise, lxc_init (via lxc_console) will attach the container's
...
...
@@ -958,12 +959,12 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
if
(
lxc_init
(
c
->
name
,
handler
)
<
0
)
goto
out
;
if
(
!
cgroup_init
(
handler
))
{
ERROR
(
"failed initing cgroups"
);
cgroup_ops
=
cgroup_init
(
NULL
);
if
(
!
cgroup_ops
)
goto
out_fini_handler
;
}
handler
->
cgroup_ops
=
cgroup_ops
;
if
(
!
cgroup_
create
(
handler
))
{
if
(
!
cgroup_
ops
->
create
(
cgroup_ops
,
handler
))
{
ERROR
(
"failed creating groups"
);
goto
out_fini_handler
;
}
...
...
@@ -1052,7 +1053,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
os
.
console_name
=
c
->
lxc_conf
->
console
.
name
;
/* exec_criu() returning is an error */
exec_criu
(
&
os
);
exec_criu
(
cgroup_ops
,
&
os
);
umount
(
rootfs
->
mount
);
rmdir
(
rootfs
->
mount
);
goto
out_fini_handler
;
...
...
@@ -1253,16 +1254,21 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
if
(
pid
==
0
)
{
struct
criu_opts
os
;
struct
lxc_handler
h
;
struct
cgroup_ops
*
cgroup_ops
;
close
(
criuout
[
0
]);
lxc_zero_handler
(
&
h
);
h
.
name
=
c
->
name
;
if
(
!
cgroup_init
(
&
h
))
{
cgroup_ops
=
cgroup_init
(
NULL
);
if
(
!
cgroup_ops
)
{
ERROR
(
"failed to cgroup_init()"
);
_exit
(
EXIT_FAILURE
);
return
-
1
;
}
h
.
cgroup_ops
=
cgroup_ops
;
os
.
pipefd
=
criuout
[
1
];
os
.
action
=
mode
;
...
...
@@ -1278,7 +1284,7 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
}
/* exec_criu() returning is an error */
exec_criu
(
&
os
);
exec_criu
(
cgroup_ops
,
&
os
);
free
(
criu_version
);
_exit
(
EXIT_FAILURE
);
}
else
{
...
...
src/lxc/freezer.c
View file @
394769b1
...
...
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/param.h>
#include "cgroup.h"
#include "commands.h"
#include "error.h"
#include "log.h"
...
...
@@ -41,38 +42,30 @@
lxc_log_define
(
lxc_freezer
,
lxc
);
lxc_state_t
freezer_state
(
const
char
*
name
,
const
char
*
lxcpath
)
{
int
ret
;
char
v
[
100
];
ret
=
lxc_cgroup_get
(
"freezer.state"
,
v
,
sizeof
(
v
),
name
,
lxcpath
);
if
(
ret
<
0
)
return
-
1
;
v
[
99
]
=
'\0'
;
v
[
lxc_char_right_gc
(
v
,
strlen
(
v
))]
=
'\0'
;
return
lxc_str2state
(
v
);
}
static
int
do_freeze_thaw
(
bool
freeze
,
const
char
*
name
,
const
char
*
lxcpath
)
{
int
ret
;
char
v
[
100
];
struct
cgroup_ops
*
cgroup_ops
;
const
char
*
state
=
freeze
?
"FROZEN"
:
"THAWED"
;
size_t
state_len
=
6
;
lxc_state_t
new_state
=
freeze
?
FROZEN
:
THAWED
;
ret
=
lxc_cgroup_set
(
"freezer.state"
,
state
,
name
,
lxcpath
);
cgroup_ops
=
cgroup_init
(
NULL
);
if
(
!
cgroup_ops
)
return
-
1
;
ret
=
cgroup_ops
->
set
(
cgroup_ops
,
"freezer.state"
,
state
,
name
,
lxcpath
);
if
(
ret
<
0
)
{
cgroup_exit
(
cgroup_ops
);
ERROR
(
"Failed to freeze %s"
,
name
);
return
-
1
;
}
for
(;;)
{
ret
=
lxc_cgroup_get
(
"freezer.state"
,
v
,
sizeof
(
v
),
name
,
lxcpath
);
ret
=
cgroup_ops
->
get
(
cgroup_ops
,
"freezer.state"
,
v
,
sizeof
(
v
),
name
,
lxcpath
);
if
(
ret
<
0
)
{
cgroup_exit
(
cgroup_ops
);
ERROR
(
"Failed to get freezer state of %s"
,
name
);
return
-
1
;
}
...
...
@@ -82,6 +75,7 @@ static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath)
ret
=
strncmp
(
v
,
state
,
state_len
);
if
(
ret
==
0
)
{
cgroup_exit
(
cgroup_ops
);
lxc_cmd_serve_state_clients
(
name
,
lxcpath
,
new_state
);
lxc_monitor_send_state
(
name
,
new_state
,
lxcpath
);
return
0
;
...
...
src/lxc/lxc.h
View file @
394769b1
...
...
@@ -98,29 +98,6 @@ extern int lxc_unfreeze(const char *name, const char *lxcpath);
extern
lxc_state_t
lxc_state
(
const
char
*
name
,
const
char
*
lxcpath
);
/*
* Set a specified value for a specified subsystem. The specified
* subsystem must be fully specified, eg. "cpu.shares"
* @filename : the cgroup attribute filename
* @value : the value to be set
* @name : the name of the container
* @lxcpath : lxc config path for container
* Returns 0 on success, < 0 otherwise
*/
extern
int
lxc_cgroup_set
(
const
char
*
filename
,
const
char
*
value
,
const
char
*
name
,
const
char
*
lxcpath
);
/*
* Get a specified value for a specified subsystem. The specified
* subsystem must be fully specified, eg. "cpu.shares"
* @filename : the cgroup attribute filename
* @value : the value to be set
* @len : the len of the value variable
* @name : the name of the container
* @lxcpath : lxc config path for container
* Returns the number of bytes read, < 0 on error
*/
extern
int
lxc_cgroup_get
(
const
char
*
filename
,
char
*
value
,
size_t
len
,
const
char
*
name
,
const
char
*
lxcpath
);
/*
* Create and return a new lxccontainer struct.
*/
extern
struct
lxc_container
*
lxc_container_new
(
const
char
*
name
,
const
char
*
configpath
);
...
...
src/lxc/lxccontainer.c
View file @
394769b1
...
...
@@ -3141,6 +3141,7 @@ WRAP_API_1(bool, lxcapi_set_config_path, const char *)
static
bool
do_lxcapi_set_cgroup_item
(
struct
lxc_container
*
c
,
const
char
*
subsys
,
const
char
*
value
)
{
int
ret
;
struct
cgroup_ops
*
cgroup_ops
;
if
(
!
c
)
return
false
;
...
...
@@ -3148,12 +3149,19 @@ static bool do_lxcapi_set_cgroup_item(struct lxc_container *c, const char *subsy
if
(
is_stopped
(
c
))
return
false
;
cgroup_ops
=
cgroup_init
(
NULL
);
if
(
!
cgroup_ops
)
return
false
;
if
(
container_disk_lock
(
c
))
return
false
;
ret
=
lxc_cgroup_set
(
subsys
,
value
,
c
->
name
,
c
->
config_path
);
ret
=
cgroup_ops
->
set
(
cgroup_ops
,
subsys
,
value
,
c
->
name
,
c
->
config_path
);
container_disk_unlock
(
c
);
cgroup_exit
(
cgroup_ops
);
return
ret
==
0
;
}
...
...
@@ -3162,6 +3170,7 @@ WRAP_API_2(bool, lxcapi_set_cgroup_item, const char *, const char *)
static
int
do_lxcapi_get_cgroup_item
(
struct
lxc_container
*
c
,
const
char
*
subsys
,
char
*
retv
,
int
inlen
)
{
int
ret
;
struct
cgroup_ops
*
cgroup_ops
;
if
(
!
c
)
return
-
1
;
...
...
@@ -3169,12 +3178,20 @@ static int do_lxcapi_get_cgroup_item(struct lxc_container *c, const char *subsys
if
(
is_stopped
(
c
))
return
-
1
;
cgroup_ops
=
cgroup_init
(
NULL
);
if
(
!
cgroup_ops
)
return
-
1
;
if
(
container_disk_lock
(
c
))
return
-
1
;
ret
=
lxc_cgroup_get
(
subsys
,
retv
,
inlen
,
c
->
name
,
c
->
config_path
);
ret
=
cgroup_ops
->
get
(
cgroup_ops
,
subsys
,
retv
,
inlen
,
c
->
name
,
c
->
config_path
);
container_disk_unlock
(
c
);
cgroup_exit
(
cgroup_ops
);
return
ret
;
}
...
...
src/lxc/seccomp.c
View file @
394769b1
...
...
@@ -580,19 +580,21 @@ static int parse_config_v2(FILE *f, char *line, struct lxc_conf *conf)
cur_rule_arch
=
lxc_seccomp_arch_all
;
ctx
.
architectures
[
0
]
=
SCMP_ARCH_ARM
;
ctx
.
contexts
[
0
]
=
get_new_ctx
(
lxc_seccomp_arch_arm
,
default_policy_action
,
&
ctx
.
needs_merge
[
0
]);
ctx
.
contexts
[
0
]
=
get_new_ctx
(
lxc_seccomp_arch_arm
,
default_policy_action
,
&
ctx
.
needs_merge
[
0
]);
if
(
!
ctx
.
contexts
[
0
])
goto
bad
;
#ifdef SCMP_ARCH_AARCH64
ctx
.
architectures
[
2
]
=
SCMP_ARCH_AARCH64
;
ctx
.
contexts
[
2
]
=
get_new_ctx
(
lxc_seccomp_arch_arm64
,
default_policy_action
,
&
ctx
.
needs_merge
[
2
]);
ctx
.
contexts
[
2
]
=
get_new_ctx
(
lxc_seccomp_arch_arm64
,
default_policy_action
,
&
ctx
.
needs_merge
[
2
]);
if
(
!
ctx
.
contexts
[
2
])
goto
bad
;
#endif
#endif
#ifdef SCMP_ARCH_MIPS
}
else
if
(
native_arch
==
lxc_seccomp_arch_mips64
)
{
cur_rule_arch
=
lxc_seccomp_arch_all
;
...
...
src/lxc/start.c
View file @
394769b1
...
...
@@ -849,6 +849,13 @@ int lxc_init(const char *name, struct lxc_handler *handler)
}
TRACE
(
"Chowned console"
);
handler
->
cgroup_ops
=
cgroup_init
(
handler
);
if
(
!
handler
->
cgroup_ops
)
{
ERROR
(
"Failed to initialize cgroup driver"
);
goto
out_restore_sigmask
;
}
TRACE
(
"Initialized cgroup driver"
);
INFO
(
"Container
\"
%s
\"
is initialized"
,
name
);
return
0
;
...
...
@@ -871,6 +878,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
struct
lxc_list
*
cur
,
*
next
;
char
*
namespaces
[
LXC_NS_MAX
+
1
];
size_t
namespace_count
=
0
;
struct
cgroup_ops
*
cgroup_ops
=
handler
->
cgroup_ops
;
/* The STOPPING state is there for future cleanup code which can take
* awhile.
...
...
@@ -935,7 +943,8 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
while
(
namespace_count
--
)
free
(
namespaces
[
namespace_count
]);
cgroup_destroy
(
handler
);
cgroup_ops
->
destroy
(
cgroup_ops
,
handler
);
cgroup_exit
(
cgroup_ops
);
if
(
handler
->
conf
->
reboot
==
0
)
{
/* For all new state clients simply close the command socket.
...
...
@@ -1506,8 +1515,9 @@ static int lxc_spawn(struct lxc_handler *handler)
struct
lxc_list
*
id_map
;
const
char
*
name
=
handler
->
name
;
const
char
*
lxcpath
=
handler
->
lxcpath
;
bool
cgroups_connected
=
false
,
share_ns
=
false
;
bool
share_ns
=
false
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
cgroup_ops
*
cgroup_ops
=
handler
->
cgroup_ops
;
id_map
=
&
conf
->
id_map
;
wants_to_map_ids
=
!
lxc_list_empty
(
id_map
);
...
...
@@ -1567,14 +1577,7 @@ static int lxc_spawn(struct lxc_handler *handler)
}
}
if
(
!
cgroup_init
(
handler
))
{
ERROR
(
"Failed initializing cgroup support"
);
goto
out_delete_net
;
}
cgroups_connected
=
true
;
if
(
!
cgroup_create
(
handler
))
{
if
(
!
cgroup_ops
->
create
(
cgroup_ops
,
handler
))
{
ERROR
(
"Failed creating cgroups"
);
goto
out_delete_net
;
}
...
...
@@ -1663,15 +1666,15 @@ static int lxc_spawn(struct lxc_handler *handler)
if
(
ret
<
0
)
goto
out_delete_net
;
if
(
!
cgroup_
setup_limits
(
handler
,
false
))
{
if
(
!
cgroup_
ops
->
setup_limits
(
cgroup_ops
,
handler
->
conf
,
false
))
{
ERROR
(
"Failed to setup cgroup limits for container
\"
%s
\"
"
,
name
);
goto
out_delete_net
;
}
if
(
!
cgroup_
enter
(
handler
))
if
(
!
cgroup_
ops
->
enter
(
cgroup_ops
,
handler
->
pid
))
goto
out_delete_net
;
if
(
!
cgroup_
chown
(
handler
))
if
(
!
cgroup_
ops
->
chown
(
cgroup_ops
,
handler
->
conf
))
goto
out_delete_net
;
/* Now we're ready to preserve the network namespace */
...
...
@@ -1736,15 +1739,12 @@ static int lxc_spawn(struct lxc_handler *handler)
if
(
ret
<
0
)
goto
out_delete_net
;
if
(
!
cgroup_
setup_limits
(
handler
,
true
))
{
if
(
!
cgroup_
ops
->
setup_limits
(
cgroup_ops
,
handler
->
conf
,
true
))
{
ERROR
(
"Failed to setup legacy device cgroup controller limits"
);
goto
out_delete_net
;
}
TRACE
(
"Set up legacy device cgroup controller limits"
);
cgroup_disconnect
();
cgroups_connected
=
false
;
if
(
handler
->
ns_clone_flags
&
CLONE_NEWCGROUP
)
{
/* Now we're ready to preserve the cgroup namespace */
ret
=
lxc_try_preserve_ns
(
handler
->
pid
,
"cgroup"
);
...
...
@@ -1821,9 +1821,6 @@ static int lxc_spawn(struct lxc_handler *handler)
return
0
;
out_delete_net:
if
(
cgroups_connected
)
cgroup_disconnect
();
if
(
handler
->
ns_clone_flags
&
CLONE_NEWNET
)
lxc_delete_network
(
handler
);
...
...
src/lxc/start.h
View file @
394769b1
...
...
@@ -132,6 +132,8 @@ struct lxc_handler {
* true.
*/
int
exit_status
;
struct
cgroup_ops
*
cgroup_ops
;
};
struct
execute_args
{
...
...
src/lxc/state.c
View file @
394769b1
...
...
@@ -72,12 +72,7 @@ lxc_state_t lxc_str2state(const char *state)
lxc_state_t
lxc_getstate
(
const
char
*
name
,
const
char
*
lxcpath
)
{
extern
lxc_state_t
freezer_state
(
const
char
*
name
,
const
char
*
lxcpath
);
lxc_state_t
state
=
freezer_state
(
name
,
lxcpath
);
if
(
state
!=
FROZEN
&&
state
!=
FREEZING
)
state
=
lxc_cmd_get_state
(
name
,
lxcpath
);
return
state
;
return
lxc_cmd_get_state
(
name
,
lxcpath
);
}
static
int
fillwaitedstates
(
const
char
*
strstates
,
lxc_state_t
*
states
)
...
...
src/tests/cgpath.c
View file @
394769b1
...
...
@@ -53,6 +53,7 @@ static int test_running_container(const char *lxcpath,
char
*
cgrelpath
;
char
relpath
[
PATH_MAX
+
1
];
char
value
[
NAME_MAX
],
value_save
[
NAME_MAX
];
struct
cgroup_ops
*
cgroup_ops
;
sprintf
(
relpath
,
"%s/%s"
,
group
?
group
:
"lxc"
,
name
);
...
...
@@ -75,36 +76,41 @@ static int test_running_container(const char *lxcpath,
goto
err3
;
}
cgroup_ops
=
cgroup_init
(
NULL
);
if
(
!
cgroup_ops
)
goto
err3
;
/* test get/set value using memory.soft_limit_in_bytes file */
ret
=
lxc_cgroup_get
(
"memory.soft_limit_in_bytes"
,
value
,
sizeof
(
value
)
,
c
->
name
,
c
->
config_path
);
ret
=
cgroup_ops
->
get
(
cgroup_ops
,
"memory.soft_limit_in_bytes"
,
value
,
sizeof
(
value
),
c
->
name
,
c
->
config_path
);
if
(
ret
<
0
)
{
TSTERR
(
"
lxc_
cgroup_get failed"
);
TSTERR
(
"cgroup_get failed"
);
goto
err3
;
}
strcpy
(
value_save
,
value
);
ret
=
lxc_cgroup_set
(
"memory.soft_limit_in_bytes"
,
"512M"
,
c
->
name
,
c
->
config_path
);
ret
=
cgroup_ops
->
set
(
cgroup_ops
,
"memory.soft_limit_in_bytes"
,
"512M"
,
c
->
name
,
c
->
config_path
);
if
(
ret
<
0
)
{
TSTERR
(
"
lxc_
cgroup_set failed %d %d"
,
ret
,
errno
);
TSTERR
(
"cgroup_set failed %d %d"
,
ret
,
errno
);
goto
err3
;
}
ret
=
lxc_cgroup_get
(
"memory.soft_limit_in_bytes"
,
value
,
sizeof
(
value
)
,
c
->
name
,
c
->
config_path
);
ret
=
cgroup_ops
->
get
(
cgroup_ops
,
"memory.soft_limit_in_bytes"
,
value
,
sizeof
(
value
),
c
->
name
,
c
->
config_path
);
if
(
ret
<
0
)
{
TSTERR
(
"
lxc_
cgroup_get failed"
);
TSTERR
(
"cgroup_get failed"
);
goto
err3
;
}
if
(
strcmp
(
value
,
"536870912
\n
"
))
{
TSTERR
(
"
lxc_
cgroup_set_bypath failed to set value >%s<"
,
value
);
TSTERR
(
"cgroup_set_bypath failed to set value >%s<"
,
value
);
goto
err3
;
}
/* restore original value */
ret
=
lxc_cgroup_set
(
"memory.soft_limit_in_bytes"
,
value_save
,
c
->
name
,
c
->
config_path
);
ret
=
cgroup_ops
->
set
(
cgroup_ops
,
"memory.soft_limit_in_bytes"
,
value_save
,
c
->
name
,
c
->
config_path
);
if
(
ret
<
0
)
{
TSTERR
(
"
lxc_
cgroup_set failed"
);
TSTERR
(
"cgroup_set failed"
);
goto
err3
;
}
...
...
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