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
ea0f0c84
Unverified
Commit
ea0f0c84
authored
Sep 21, 2018
by
Serge Hallyn
Committed by
GitHub
Sep 21, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2606 from brauner/2018-09-09/cgroup_escape
cgroups: scoping for cgroup v2
parents
e52f28af
d28779d9
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
167 additions
and
64 deletions
+167
-64
configure.ac
configure.ac
+1
-1
cgfsng.c
src/lxc/cgroups/cgfsng.c
+131
-50
cgroup.c
src/lxc/cgroups/cgroup.c
+5
-2
cgroup.h
src/lxc/cgroups/cgroup.h
+13
-6
criu.c
src/lxc/criu.c
+1
-1
initutils.c
src/lxc/initutils.c
+1
-1
start.c
src/lxc/start.c
+14
-2
cgpath.c
src/tests/cgpath.c
+1
-1
No files found.
configure.ac
View file @
ea0f0c84
...
@@ -483,7 +483,7 @@ AC_ARG_WITH([cgroup-pattern],
...
@@ -483,7 +483,7 @@ AC_ARG_WITH([cgroup-pattern],
[AC_HELP_STRING(
[AC_HELP_STRING(
[--with-cgroup-pattern=pattern],
[--with-cgroup-pattern=pattern],
[pattern for container cgroups]
[pattern for container cgroups]
)], [], [with_cgroup_pattern=['lxc/%n']])
)], [], [with_cgroup_pattern=['lxc
.payload
/%n']])
# The path for the apparmor_parser's cache for generated apparmor profiles
# The path for the apparmor_parser's cache for generated apparmor profiles
AC_ARG_WITH([apparmor-cache-dir],
AC_ARG_WITH([apparmor-cache-dir],
...
...
src/lxc/cgroups/cgfsng.c
View file @
ea0f0c84
...
@@ -573,7 +573,7 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
...
@@ -573,7 +573,7 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
if
(
slash
)
if
(
slash
)
*
slash
=
'\0'
;
*
slash
=
'\0'
;
cgpath
=
must_make_path
(
h
->
mountpoint
,
h
->
base_cgroup
,
cgname
,
NULL
);
cgpath
=
must_make_path
(
h
->
mountpoint
,
h
->
container_base_path
,
cgname
,
NULL
);
if
(
slash
)
if
(
slash
)
*
slash
=
'/'
;
*
slash
=
'/'
;
...
@@ -810,7 +810,7 @@ static char **cg_unified_get_controllers(const char *file)
...
@@ -810,7 +810,7 @@ static char **cg_unified_get_controllers(const char *file)
}
}
static
struct
hierarchy
*
add_hierarchy
(
struct
hierarchy
***
h
,
char
**
clist
,
char
*
mountpoint
,
static
struct
hierarchy
*
add_hierarchy
(
struct
hierarchy
***
h
,
char
**
clist
,
char
*
mountpoint
,
char
*
base_cgroup
,
int
type
)
char
*
container_base_path
,
int
type
)
{
{
struct
hierarchy
*
new
;
struct
hierarchy
*
new
;
int
newentry
;
int
newentry
;
...
@@ -818,8 +818,9 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char
...
@@ -818,8 +818,9 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char
new
=
must_alloc
(
sizeof
(
*
new
));
new
=
must_alloc
(
sizeof
(
*
new
));
new
->
controllers
=
clist
;
new
->
controllers
=
clist
;
new
->
mountpoint
=
mountpoint
;
new
->
mountpoint
=
mountpoint
;
new
->
base_cgroup
=
base_cgroup
;
new
->
container_base_path
=
container_base_path
;
new
->
fullcgpath
=
NULL
;
new
->
container_full_path
=
NULL
;
new
->
monitor_full_path
=
NULL
;
new
->
version
=
type
;
new
->
version
=
type
;
newentry
=
append_null_to_list
((
void
***
)
h
);
newentry
=
append_null_to_list
((
void
***
)
h
);
...
@@ -1015,7 +1016,7 @@ static void lxc_cgfsng_print_hierarchies(struct cgroup_ops *ops)
...
@@ -1015,7 +1016,7 @@ static void lxc_cgfsng_print_hierarchies(struct cgroup_ops *ops)
int
j
;
int
j
;
char
**
cit
;
char
**
cit
;
TRACE
(
" %d: base_cgroup: %s"
,
i
,
(
*
it
)
->
base_cgroup
?
(
*
it
)
->
base_cgroup
:
"(null)"
);
TRACE
(
" %d: base_cgroup: %s"
,
i
,
(
*
it
)
->
container_base_path
?
(
*
it
)
->
container_base_path
:
"(null)"
);
TRACE
(
" mountpoint: %s"
,
(
*
it
)
->
mountpoint
?
(
*
it
)
->
mountpoint
:
"(null)"
);
TRACE
(
" mountpoint: %s"
,
(
*
it
)
->
mountpoint
?
(
*
it
)
->
mountpoint
:
"(null)"
);
TRACE
(
" controllers:"
);
TRACE
(
" controllers:"
);
for
(
j
=
0
,
cit
=
(
*
it
)
->
controllers
;
cit
&&
*
cit
;
cit
++
,
j
++
)
for
(
j
=
0
,
cit
=
(
*
it
)
->
controllers
;
cit
&&
*
cit
;
cit
++
,
j
++
)
...
@@ -1051,15 +1052,15 @@ static int cgroup_rmdir(struct hierarchy **hierarchies,
...
@@ -1051,15 +1052,15 @@ static int cgroup_rmdir(struct hierarchy **hierarchies,
int
ret
;
int
ret
;
struct
hierarchy
*
h
=
hierarchies
[
i
];
struct
hierarchy
*
h
=
hierarchies
[
i
];
if
(
!
h
->
fullcg
path
)
if
(
!
h
->
container_full_
path
)
continue
;
continue
;
ret
=
recursive_destroy
(
h
->
fullcg
path
);
ret
=
recursive_destroy
(
h
->
container_full_
path
);
if
(
ret
<
0
)
if
(
ret
<
0
)
WARN
(
"Failed to destroy
\"
%s
\"
"
,
h
->
fullcg
path
);
WARN
(
"Failed to destroy
\"
%s
\"
"
,
h
->
container_full_
path
);
free
(
h
->
fullcg
path
);
free
(
h
->
container_full_
path
);
h
->
fullcg
path
=
NULL
;
h
->
container_full_
path
=
NULL
;
}
}
return
0
;
return
0
;
...
@@ -1167,7 +1168,7 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname)
...
@@ -1167,7 +1168,7 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname)
if
(
parts_len
>
0
)
if
(
parts_len
>
0
)
parts_len
--
;
parts_len
--
;
cgroup
=
must_make_path
(
h
->
mountpoint
,
h
->
base_cgroup
,
NULL
);
cgroup
=
must_make_path
(
h
->
mountpoint
,
h
->
container_base_path
,
NULL
);
for
(
i
=
0
;
i
<
parts_len
;
i
++
)
{
for
(
i
=
0
;
i
<
parts_len
;
i
++
)
{
int
ret
;
int
ret
;
char
*
target
;
char
*
target
;
...
@@ -1192,13 +1193,30 @@ on_error:
...
@@ -1192,13 +1193,30 @@ on_error:
return
bret
;
return
bret
;
}
}
static
bool
create_path_for_hierarchy
(
struct
hierarchy
*
h
,
char
*
cgname
)
static
bool
monitor_
create_path_for_hierarchy
(
struct
hierarchy
*
h
,
char
*
cgname
)
{
{
int
ret
;
int
ret
;
h
->
fullcgpath
=
must_make_path
(
h
->
mountpoint
,
h
->
base_cgroup
,
cgname
,
NULL
);
h
->
monitor_full_path
=
must_make_path
(
h
->
mountpoint
,
h
->
container_base_path
,
cgname
,
NULL
);
if
(
dir_exists
(
h
->
fullcgpath
))
{
if
(
dir_exists
(
h
->
monitor_full_path
))
ERROR
(
"The cgroup
\"
%s
\"
already existed"
,
h
->
fullcgpath
);
return
true
;
ret
=
mkdir_p
(
h
->
monitor_full_path
,
0755
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to create cgroup
\"
%s
\"
"
,
h
->
monitor_full_path
);
return
false
;
}
return
cg_unified_create_cgroup
(
h
,
cgname
);
}
static
bool
container_create_path_for_hierarchy
(
struct
hierarchy
*
h
,
char
*
cgname
)
{
int
ret
;
h
->
container_full_path
=
must_make_path
(
h
->
mountpoint
,
h
->
container_base_path
,
cgname
,
NULL
);
if
(
dir_exists
(
h
->
container_full_path
))
{
ERROR
(
"The cgroup
\"
%s
\"
already existed"
,
h
->
container_full_path
);
return
false
;
return
false
;
}
}
...
@@ -1207,31 +1225,77 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
...
@@ -1207,31 +1225,77 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
return
false
;
return
false
;
}
}
ret
=
mkdir_p
(
h
->
fullcg
path
,
0755
);
ret
=
mkdir_p
(
h
->
container_full_
path
,
0755
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
ERROR
(
"Failed to create cgroup
\"
%s
\"
"
,
h
->
fullcg
path
);
ERROR
(
"Failed to create cgroup
\"
%s
\"
"
,
h
->
container_full_
path
);
return
false
;
return
false
;
}
}
return
cg_unified_create_cgroup
(
h
,
cgname
);
return
cg_unified_create_cgroup
(
h
,
cgname
);
}
}
static
void
remove_path_for_hierarchy
(
struct
hierarchy
*
h
,
char
*
cgname
)
static
void
remove_path_for_hierarchy
(
struct
hierarchy
*
h
,
char
*
cgname
,
bool
monitor
)
{
{
int
ret
;
int
ret
;
char
*
full_path
;
ret
=
rmdir
(
h
->
fullcgpath
);
if
(
monitor
)
full_path
=
h
->
monitor_full_path
;
else
full_path
=
h
->
container_full_path
;
ret
=
rmdir
(
full_path
);
if
(
ret
<
0
)
if
(
ret
<
0
)
SYSERROR
(
"Failed to rmdir(
\"
%s
\"
) from failed creation attempt"
,
h
->
fullcg
path
);
SYSERROR
(
"Failed to rmdir(
\"
%s
\"
) from failed creation attempt"
,
full_
path
);
free
(
h
->
fullcgpath
);
free
(
full_path
);
h
->
fullcgpath
=
NULL
;
if
(
monitor
)
h
->
monitor_full_path
=
NULL
;
else
h
->
container_full_path
=
NULL
;
}
__cgfsng_ops__
static
inline
bool
cgfsng_monitor_create
(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
)
{
char
*
monitor_cgroup
;
bool
bret
=
false
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
if
(
!
conf
)
return
bret
;
if
(
conf
->
cgroup_meta
.
dir
)
monitor_cgroup
=
lxc_string_join
(
"/"
,
(
const
char
*
[]){
conf
->
cgroup_meta
.
dir
,
ops
->
monitor_pattern
,
handler
->
name
,
NULL
},
false
);
else
monitor_cgroup
=
must_make_path
(
ops
->
monitor_pattern
,
handler
->
name
,
NULL
);
if
(
!
monitor_cgroup
)
return
bret
;
for
(
int
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
if
(
!
monitor_create_path_for_hierarchy
(
ops
->
hierarchies
[
i
],
monitor_cgroup
))
{
ERROR
(
"Failed to create cgroup
\"
%s
\"
"
,
ops
->
hierarchies
[
i
]
->
monitor_full_path
);
free
(
ops
->
hierarchies
[
i
]
->
container_full_path
);
ops
->
hierarchies
[
i
]
->
container_full_path
=
NULL
;
for
(
int
j
=
0
;
j
<
i
;
j
++
)
remove_path_for_hierarchy
(
ops
->
hierarchies
[
j
],
monitor_cgroup
,
true
);
goto
on_error
;
}
}
bret
=
true
;
on_error:
free
(
monitor_cgroup
);
return
bret
;
}
}
/* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
/* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
* next cgroup_pattern-1, -2, ..., -999.
* next cgroup_pattern-1, -2, ..., -999.
*/
*/
__cgfsng_ops__
static
inline
bool
cgfsng_create
(
struct
cgroup_ops
*
ops
,
__cgfsng_ops__
static
inline
bool
cgfsng_
payload_
create
(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
{
int
i
;
int
i
;
...
@@ -1285,13 +1349,12 @@ again:
...
@@ -1285,13 +1349,12 @@ again:
}
}
for
(
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
for
(
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
if
(
!
create_path_for_hierarchy
(
ops
->
hierarchies
[
i
],
container_cgroup
))
{
if
(
!
container_create_path_for_hierarchy
(
ops
->
hierarchies
[
i
],
container_cgroup
))
{
int
j
;
ERROR
(
"Failed to create cgroup
\"
%s
\"
"
,
ops
->
hierarchies
[
i
]
->
container_full_path
);
ERROR
(
"Failed to create cgroup
\"
%s
\"
"
,
ops
->
hierarchies
[
i
]
->
fullcgpath
);
free
(
ops
->
hierarchies
[
i
]
->
container_full_path
);
free
(
ops
->
hierarchies
[
i
]
->
fullcgpath
);
ops
->
hierarchies
[
i
]
->
container_full_path
=
NULL
;
ops
->
hierarchies
[
i
]
->
fullcgpath
=
NULL
;
for
(
int
j
=
0
;
j
<
i
;
j
++
)
for
(
j
=
0
;
j
<
i
;
j
++
)
remove_path_for_hierarchy
(
ops
->
hierarchies
[
j
],
container_cgroup
,
false
);
remove_path_for_hierarchy
(
ops
->
hierarchies
[
j
],
container_cgroup
);
idx
++
;
idx
++
;
goto
again
;
goto
again
;
}
}
...
@@ -1307,33 +1370,48 @@ out_free:
...
@@ -1307,33 +1370,48 @@ out_free:
return
false
;
return
false
;
}
}
__cgfsng_ops__
static
bool
cgfsng_enter
(
struct
cgroup_ops
*
ops
,
pid_t
pid
)
__cgfsng_ops__
static
bool
__do_cgroup_enter
(
struct
cgroup_ops
*
ops
,
pid_t
pid
,
bool
monitor
)
{
{
int
i
,
len
;
int
len
;
char
pidstr
[
25
];
char
pidstr
[
25
];
len
=
snprintf
(
pidstr
,
25
,
"%d"
,
pid
);
len
=
snprintf
(
pidstr
,
25
,
"%d"
,
pid
);
if
(
len
<
0
||
len
>=
25
)
if
(
len
<
0
||
len
>=
25
)
return
false
;
return
false
;
for
(
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
for
(
i
nt
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
int
ret
;
int
ret
;
char
*
full
path
;
char
*
path
;
fullpath
=
must_make_path
(
ops
->
hierarchies
[
i
]
->
fullcgpath
,
if
(
monitor
)
path
=
must_make_path
(
ops
->
hierarchies
[
i
]
->
monitor_full_path
,
"cgroup.procs"
,
NULL
);
"cgroup.procs"
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
pidstr
,
len
,
false
,
0666
);
else
path
=
must_make_path
(
ops
->
hierarchies
[
i
]
->
container_full_path
,
"cgroup.procs"
,
NULL
);
ret
=
lxc_write_to_file
(
path
,
pidstr
,
len
,
false
,
0666
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
SYSERROR
(
"Failed to enter cgroup
\"
%s
\"
"
,
full
path
);
SYSERROR
(
"Failed to enter cgroup
\"
%s
\"
"
,
path
);
free
(
full
path
);
free
(
path
);
return
false
;
return
false
;
}
}
free
(
full
path
);
free
(
path
);
}
}
return
true
;
return
true
;
}
}
__cgfsng_ops__
static
bool
cgfsng_monitor_enter
(
struct
cgroup_ops
*
ops
,
pid_t
pid
)
{
return
__do_cgroup_enter
(
ops
,
pid
,
true
);
}
static
bool
cgfsng_payload_enter
(
struct
cgroup_ops
*
ops
,
pid_t
pid
)
{
return
__do_cgroup_enter
(
ops
,
pid
,
false
);
}
static
int
chowmod
(
char
*
path
,
uid_t
chown_uid
,
gid_t
chown_gid
,
static
int
chowmod
(
char
*
path
,
uid_t
chown_uid
,
gid_t
chown_gid
,
mode_t
chmod_mode
)
mode_t
chmod_mode
)
{
{
...
@@ -1395,7 +1473,7 @@ static int chown_cgroup_wrapper(void *data)
...
@@ -1395,7 +1473,7 @@ static int chown_cgroup_wrapper(void *data)
for
(
i
=
0
;
arg
->
hierarchies
[
i
];
i
++
)
{
for
(
i
=
0
;
arg
->
hierarchies
[
i
];
i
++
)
{
char
*
fullpath
;
char
*
fullpath
;
char
*
path
=
arg
->
hierarchies
[
i
]
->
fullcg
path
;
char
*
path
=
arg
->
hierarchies
[
i
]
->
container_full_
path
;
ret
=
chowmod
(
path
,
destuid
,
nsgid
,
0775
);
ret
=
chowmod
(
path
,
destuid
,
nsgid
,
0775
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -1498,7 +1576,7 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
...
@@ -1498,7 +1576,7 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
INFO
(
"Remounted %s read-only"
,
controllerpath
);
INFO
(
"Remounted %s read-only"
,
controllerpath
);
}
}
sourcepath
=
must_make_path
(
h
->
mountpoint
,
h
->
base_cgroup
,
sourcepath
=
must_make_path
(
h
->
mountpoint
,
h
->
container_base_path
,
container_cgroup
,
NULL
);
container_cgroup
,
NULL
);
if
(
type
==
LXC_AUTO_CGROUP_RO
)
if
(
type
==
LXC_AUTO_CGROUP_RO
)
flags
|=
MS_RDONLY
;
flags
|=
MS_RDONLY
;
...
@@ -1669,7 +1747,7 @@ __cgfsng_ops__ static bool cgfsng_mount(struct cgroup_ops *ops,
...
@@ -1669,7 +1747,7 @@ __cgfsng_ops__ static bool cgfsng_mount(struct cgroup_ops *ops,
continue
;
continue
;
}
}
path2
=
must_make_path
(
controllerpath
,
h
->
base_cgroup
,
path2
=
must_make_path
(
controllerpath
,
h
->
container_base_path
,
ops
->
container_cgroup
,
NULL
);
ops
->
container_cgroup
,
NULL
);
ret
=
mkdir_p
(
path2
,
0755
);
ret
=
mkdir_p
(
path2
,
0755
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -1742,7 +1820,7 @@ __cgfsng_ops__ static int cgfsng_nrtasks(struct cgroup_ops *ops)
...
@@ -1742,7 +1820,7 @@ __cgfsng_ops__ static int cgfsng_nrtasks(struct cgroup_ops *ops)
if
(
!
ops
->
container_cgroup
||
!
ops
->
hierarchies
)
if
(
!
ops
->
container_cgroup
||
!
ops
->
hierarchies
)
return
-
1
;
return
-
1
;
path
=
must_make_path
(
ops
->
hierarchies
[
0
]
->
fullcg
path
,
NULL
);
path
=
must_make_path
(
ops
->
hierarchies
[
0
]
->
container_full_
path
,
NULL
);
count
=
recursive_count_nrtasks
(
path
);
count
=
recursive_count_nrtasks
(
path
);
free
(
path
);
free
(
path
);
return
count
;
return
count
;
...
@@ -1762,7 +1840,7 @@ __cgfsng_ops__ static bool cgfsng_escape(const struct cgroup_ops *ops,
...
@@ -1762,7 +1840,7 @@ __cgfsng_ops__ static bool cgfsng_escape(const struct cgroup_ops *ops,
char
*
fullpath
;
char
*
fullpath
;
fullpath
=
must_make_path
(
ops
->
hierarchies
[
i
]
->
mountpoint
,
fullpath
=
must_make_path
(
ops
->
hierarchies
[
i
]
->
mountpoint
,
ops
->
hierarchies
[
i
]
->
base_cgroup
,
ops
->
hierarchies
[
i
]
->
container_base_path
,
"cgroup.procs"
,
NULL
);
"cgroup.procs"
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
"0"
,
2
,
false
,
0666
);
ret
=
lxc_write_to_file
(
fullpath
,
"0"
,
2
,
false
,
0666
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
...
@@ -1816,7 +1894,7 @@ __cgfsng_ops__ static bool cgfsng_unfreeze(struct cgroup_ops *ops)
...
@@ -1816,7 +1894,7 @@ __cgfsng_ops__ static bool cgfsng_unfreeze(struct cgroup_ops *ops)
if
(
!
h
)
if
(
!
h
)
return
false
;
return
false
;
fullpath
=
must_make_path
(
h
->
fullcg
path
,
"freezer.state"
,
NULL
);
fullpath
=
must_make_path
(
h
->
container_full_
path
,
"freezer.state"
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
THAWED
,
THAWED_LEN
,
false
,
0666
);
ret
=
lxc_write_to_file
(
fullpath
,
THAWED
,
THAWED_LEN
,
false
,
0666
);
free
(
fullpath
);
free
(
fullpath
);
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -1837,7 +1915,7 @@ __cgfsng_ops__ static const char *cgfsng_get_cgroup(struct cgroup_ops *ops,
...
@@ -1837,7 +1915,7 @@ __cgfsng_ops__ static const char *cgfsng_get_cgroup(struct cgroup_ops *ops,
return
NULL
;
return
NULL
;
}
}
return
h
->
fullcgpath
?
h
->
fullcg
path
+
strlen
(
h
->
mountpoint
)
:
NULL
;
return
h
->
container_full_path
?
h
->
container_full_
path
+
strlen
(
h
->
mountpoint
)
:
NULL
;
}
}
/* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path,
/* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path,
...
@@ -2162,7 +2240,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
...
@@ -2162,7 +2240,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
return
-
ENOENT
;
return
-
ENOENT
;
}
}
fullpath
=
must_make_path
(
h
->
fullcg
path
,
filename
,
NULL
);
fullpath
=
must_make_path
(
h
->
container_full_
path
,
filename
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
value
,
strlen
(
value
),
false
,
0666
);
ret
=
lxc_write_to_file
(
fullpath
,
value
,
strlen
(
value
),
false
,
0666
);
free
(
fullpath
);
free
(
fullpath
);
return
ret
;
return
ret
;
...
@@ -2230,7 +2308,7 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops,
...
@@ -2230,7 +2308,7 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops,
char
*
fullpath
;
char
*
fullpath
;
struct
lxc_cgroup
*
cg
=
iterator
->
elem
;
struct
lxc_cgroup
*
cg
=
iterator
->
elem
;
fullpath
=
must_make_path
(
h
->
fullcg
path
,
cg
->
subsystem
,
NULL
);
fullpath
=
must_make_path
(
h
->
container_full_
path
,
cg
->
subsystem
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
cg
->
value
,
strlen
(
cg
->
value
),
false
,
0666
);
ret
=
lxc_write_to_file
(
fullpath
,
cg
->
value
,
strlen
(
cg
->
value
),
false
,
0666
);
free
(
fullpath
);
free
(
fullpath
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -2569,6 +2647,7 @@ __cgfsng_ops__ static bool cgfsng_data_init(struct cgroup_ops *ops)
...
@@ -2569,6 +2647,7 @@ __cgfsng_ops__ static bool cgfsng_data_init(struct cgroup_ops *ops)
return
false
;
return
false
;
}
}
ops
->
cgroup_pattern
=
must_copy_string
(
cgroup_pattern
);
ops
->
cgroup_pattern
=
must_copy_string
(
cgroup_pattern
);
ops
->
monitor_pattern
=
must_copy_string
(
"lxc.monitor"
);
return
true
;
return
true
;
}
}
...
@@ -2591,8 +2670,10 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
...
@@ -2591,8 +2670,10 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
cgfsng_ops
->
data_init
=
cgfsng_data_init
;
cgfsng_ops
->
data_init
=
cgfsng_data_init
;
cgfsng_ops
->
destroy
=
cgfsng_destroy
;
cgfsng_ops
->
destroy
=
cgfsng_destroy
;
cgfsng_ops
->
create
=
cgfsng_create
;
cgfsng_ops
->
monitor_create
=
cgfsng_monitor_create
;
cgfsng_ops
->
enter
=
cgfsng_enter
;
cgfsng_ops
->
monitor_enter
=
cgfsng_monitor_enter
;
cgfsng_ops
->
payload_create
=
cgfsng_payload_create
;
cgfsng_ops
->
payload_enter
=
cgfsng_payload_enter
;
cgfsng_ops
->
escape
=
cgfsng_escape
;
cgfsng_ops
->
escape
=
cgfsng_escape
;
cgfsng_ops
->
num_hierarchies
=
cgfsng_num_hierarchies
;
cgfsng_ops
->
num_hierarchies
=
cgfsng_num_hierarchies
;
cgfsng_ops
->
get_hierarchies
=
cgfsng_get_hierarchies
;
cgfsng_ops
->
get_hierarchies
=
cgfsng_get_hierarchies
;
...
...
src/lxc/cgroups/cgroup.c
View file @
ea0f0c84
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
*/
*/
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
...
@@ -75,6 +76,7 @@ void cgroup_exit(struct cgroup_ops *ops)
...
@@ -75,6 +76,7 @@ void cgroup_exit(struct cgroup_ops *ops)
free
(
ops
->
cgroup_pattern
);
free
(
ops
->
cgroup_pattern
);
free
(
ops
->
container_cgroup
);
free
(
ops
->
container_cgroup
);
free
(
ops
->
monitor_pattern
);
for
(
it
=
ops
->
hierarchies
;
it
&&
*
it
;
it
++
)
{
for
(
it
=
ops
->
hierarchies
;
it
&&
*
it
;
it
++
)
{
char
**
ctrlr
;
char
**
ctrlr
;
...
@@ -84,8 +86,9 @@ void cgroup_exit(struct cgroup_ops *ops)
...
@@ -84,8 +86,9 @@ void cgroup_exit(struct cgroup_ops *ops)
free
((
*
it
)
->
controllers
);
free
((
*
it
)
->
controllers
);
free
((
*
it
)
->
mountpoint
);
free
((
*
it
)
->
mountpoint
);
free
((
*
it
)
->
base_cgroup
);
free
((
*
it
)
->
container_base_path
);
free
((
*
it
)
->
fullcgpath
);
free
((
*
it
)
->
container_full_path
);
free
((
*
it
)
->
monitor_full_path
);
free
(
*
it
);
free
(
*
it
);
}
}
free
(
ops
->
hierarchies
);
free
(
ops
->
hierarchies
);
...
...
src/lxc/cgroups/cgroup.h
View file @
ea0f0c84
...
@@ -57,14 +57,17 @@ typedef enum {
...
@@ -57,14 +57,17 @@ typedef enum {
* depending on whether this is a hybrid cgroup layout (mix of legacy and
* depending on whether this is a hybrid cgroup layout (mix of legacy and
* unified hierarchies) or a pure unified cgroup layout.
* unified hierarchies) or a pure unified cgroup layout.
*
*
* @
base_cgroup
* @
container_base_path
* - The cgroup under which the container cgroup path
* - The cgroup under which the container cgroup path
* is created. This will be either the caller's cgroup (if not root), or
* is created. This will be either the caller's cgroup (if not root), or
* init's cgroup (if root).
* init's cgroup (if root).
*
*
* @
fullcg
path
* @
container_full_
path
* - The full path to the containers cgroup.
* - The full path to the containers cgroup.
*
*
* @monitor_full_path
* - The full path to the monitor's cgroup.
*
* @version
* @version
* - legacy hierarchy
* - legacy hierarchy
* If the hierarchy is a legacy hierarchy this will be set to
* If the hierarchy is a legacy hierarchy this will be set to
...
@@ -76,8 +79,9 @@ typedef enum {
...
@@ -76,8 +79,9 @@ typedef enum {
struct
hierarchy
{
struct
hierarchy
{
char
**
controllers
;
char
**
controllers
;
char
*
mountpoint
;
char
*
mountpoint
;
char
*
base_cgroup
;
char
*
container_base_path
;
char
*
fullcgpath
;
char
*
container_full_path
;
char
*
monitor_full_path
;
int
version
;
int
version
;
};
};
...
@@ -92,6 +96,7 @@ struct cgroup_ops {
...
@@ -92,6 +96,7 @@ struct cgroup_ops {
char
**
cgroup_use
;
char
**
cgroup_use
;
char
*
cgroup_pattern
;
char
*
cgroup_pattern
;
char
*
container_cgroup
;
char
*
container_cgroup
;
char
*
monitor_pattern
;
/* @hierarchies
/* @hierarchies
* - A NULL-terminated array of struct hierarchy, one per legacy
* - A NULL-terminated array of struct hierarchy, one per legacy
...
@@ -124,8 +129,10 @@ struct cgroup_ops {
...
@@ -124,8 +129,10 @@ struct cgroup_ops {
bool
(
*
data_init
)(
struct
cgroup_ops
*
ops
);
bool
(
*
data_init
)(
struct
cgroup_ops
*
ops
);
void
(
*
destroy
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
void
(
*
destroy
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
create
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
monitor_create
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
enter
)(
struct
cgroup_ops
*
ops
,
pid_t
pid
);
bool
(
*
monitor_enter
)(
struct
cgroup_ops
*
ops
,
pid_t
pid
);
bool
(
*
payload_create
)(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
);
bool
(
*
payload_enter
)(
struct
cgroup_ops
*
ops
,
pid_t
pid
);
const
char
*
(
*
get_cgroup
)(
struct
cgroup_ops
*
ops
,
const
char
*
controller
);
const
char
*
(
*
get_cgroup
)(
struct
cgroup_ops
*
ops
,
const
char
*
controller
);
bool
(
*
escape
)(
const
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
);
bool
(
*
escape
)(
const
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
);
int
(
*
num_hierarchies
)(
struct
cgroup_ops
*
ops
);
int
(
*
num_hierarchies
)(
struct
cgroup_ops
*
ops
);
...
...
src/lxc/criu.c
View file @
ea0f0c84
...
@@ -972,7 +972,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
...
@@ -972,7 +972,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
goto
out_fini_handler
;
goto
out_fini_handler
;
handler
->
cgroup_ops
=
cgroup_ops
;
handler
->
cgroup_ops
=
cgroup_ops
;
if
(
!
cgroup_ops
->
create
(
cgroup_ops
,
handler
))
{
if
(
!
cgroup_ops
->
payload_
create
(
cgroup_ops
,
handler
))
{
ERROR
(
"failed creating groups"
);
ERROR
(
"failed creating groups"
);
goto
out_fini_handler
;
goto
out_fini_handler
;
}
}
...
...
src/lxc/initutils.c
View file @
ea0f0c84
...
@@ -101,7 +101,7 @@ const char *lxc_global_config_value(const char *option_name)
...
@@ -101,7 +101,7 @@ const char *lxc_global_config_value(const char *option_name)
sprintf
(
user_config_path
,
"%s/.config/lxc/lxc.conf"
,
user_home
);
sprintf
(
user_config_path
,
"%s/.config/lxc/lxc.conf"
,
user_home
);
sprintf
(
user_default_config_path
,
"%s/.config/lxc/default.conf"
,
user_home
);
sprintf
(
user_default_config_path
,
"%s/.config/lxc/default.conf"
,
user_home
);
sprintf
(
user_lxc_path
,
"%s/.local/share/lxc/"
,
user_home
);
sprintf
(
user_lxc_path
,
"%s/.local/share/lxc/"
,
user_home
);
user_cgroup_pattern
=
strdup
(
"lxc/%n"
);
user_cgroup_pattern
=
strdup
(
"lxc
.payload
/%n"
);
}
}
else
{
else
{
user_config_path
=
strdup
(
LXC_GLOBAL_CONF
);
user_config_path
=
strdup
(
LXC_GLOBAL_CONF
);
...
...
src/lxc/start.c
View file @
ea0f0c84
...
@@ -1678,7 +1678,7 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1678,7 +1678,7 @@ static int lxc_spawn(struct lxc_handler *handler)
}
}
}
}
if
(
!
cgroup_ops
->
create
(
cgroup_ops
,
handler
))
{
if
(
!
cgroup_ops
->
payload_
create
(
cgroup_ops
,
handler
))
{
ERROR
(
"Failed creating cgroups"
);
ERROR
(
"Failed creating cgroups"
);
goto
out_delete_net
;
goto
out_delete_net
;
}
}
...
@@ -1772,7 +1772,7 @@ static int lxc_spawn(struct lxc_handler *handler)
...
@@ -1772,7 +1772,7 @@ static int lxc_spawn(struct lxc_handler *handler)
goto
out_delete_net
;
goto
out_delete_net
;
}
}
if
(
!
cgroup_ops
->
enter
(
cgroup_ops
,
handler
->
pid
))
if
(
!
cgroup_ops
->
payload_
enter
(
cgroup_ops
,
handler
->
pid
))
goto
out_delete_net
;
goto
out_delete_net
;
if
(
!
cgroup_ops
->
chown
(
cgroup_ops
,
handler
->
conf
))
if
(
!
cgroup_ops
->
chown
(
cgroup_ops
,
handler
->
conf
))
...
@@ -1949,6 +1949,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
...
@@ -1949,6 +1949,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
{
{
int
ret
,
status
;
int
ret
,
status
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
cgroup_ops
*
cgroup_ops
;
ret
=
lxc_init
(
name
,
handler
);
ret
=
lxc_init
(
name
,
handler
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -1958,12 +1959,23 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
...
@@ -1958,12 +1959,23 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
handler
->
ops
=
ops
;
handler
->
ops
=
ops
;
handler
->
data
=
data
;
handler
->
data
=
data
;
handler
->
daemonize
=
daemonize
;
handler
->
daemonize
=
daemonize
;
cgroup_ops
=
handler
->
cgroup_ops
;
if
(
!
attach_block_device
(
handler
->
conf
))
{
if
(
!
attach_block_device
(
handler
->
conf
))
{
ERROR
(
"Failed to attach block device"
);
ERROR
(
"Failed to attach block device"
);
goto
out_fini_nonet
;
goto
out_fini_nonet
;
}
}
if
(
!
cgroup_ops
->
monitor_create
(
cgroup_ops
,
handler
))
{
ERROR
(
"Failed to create monitor cgroup"
);
goto
out_fini_nonet
;
}
if
(
!
cgroup_ops
->
monitor_enter
(
cgroup_ops
,
lxc_raw_getpid
()))
{
ERROR
(
"Failed to enter monitor cgroup"
);
goto
out_fini_nonet
;
}
if
(
geteuid
()
==
0
&&
!
lxc_list_empty
(
&
conf
->
id_map
))
{
if
(
geteuid
()
==
0
&&
!
lxc_list_empty
(
&
conf
->
id_map
))
{
/* If the backing store is a device, mount it here and now. */
/* If the backing store is a device, mount it here and now. */
if
(
rootfs_is_blockdev
(
conf
))
{
if
(
rootfs_is_blockdev
(
conf
))
{
...
...
src/tests/cgpath.c
View file @
ea0f0c84
...
@@ -59,7 +59,7 @@ static int test_running_container(const char *lxcpath,
...
@@ -59,7 +59,7 @@ static int test_running_container(const char *lxcpath,
char
value
[
NAME_MAX
],
value_save
[
NAME_MAX
];
char
value
[
NAME_MAX
],
value_save
[
NAME_MAX
];
struct
cgroup_ops
*
cgroup_ops
;
struct
cgroup_ops
*
cgroup_ops
;
sprintf
(
relpath
,
"%s/%s"
,
group
?
group
:
"lxc"
,
name
);
sprintf
(
relpath
,
"%s/%s"
,
group
?
group
:
"lxc
.payload
"
,
name
);
if
((
c
=
lxc_container_new
(
name
,
lxcpath
))
==
NULL
)
{
if
((
c
=
lxc_container_new
(
name
,
lxcpath
))
==
NULL
)
{
TSTERR
(
"container %s couldn't instantiate"
,
name
);
TSTERR
(
"container %s couldn't instantiate"
,
name
);
...
...
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