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
7453799a
Unverified
Commit
7453799a
authored
Dec 07, 2019
by
Stéphane Graber
Committed by
GitHub
Dec 07, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3217 from brauner/rework_cgroups
cgroups, logging: fixes and improvements
parents
0374aacd
c04a6d4e
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
597 additions
and
430 deletions
+597
-430
af_unix.c
src/lxc/af_unix.c
+4
-4
attach.c
src/lxc/attach.c
+6
-8
cgfsng.c
src/lxc/cgroups/cgfsng.c
+380
-259
cgroup.c
src/lxc/cgroups/cgroup.c
+7
-10
cgroup.h
src/lxc/cgroups/cgroup.h
+1
-1
cgroup2_devices.c
src/lxc/cgroups/cgroup2_devices.c
+24
-24
commands.c
src/lxc/commands.c
+7
-7
compiler.h
src/lxc/compiler.h
+7
-0
confile.c
src/lxc/confile.c
+36
-36
confile_utils.c
src/lxc/confile_utils.c
+1
-1
file_utils.c
src/lxc/file_utils.c
+33
-0
file_utils.h
src/lxc/file_utils.h
+4
-0
log.h
src/lxc/log.h
+33
-26
lxccontainer.c
src/lxc/lxccontainer.c
+1
-1
macro.h
src/lxc/macro.h
+6
-6
network.c
src/lxc/network.c
+44
-44
start.c
src/lxc/start.c
+3
-3
No files found.
src/lxc/af_unix.c
View file @
7453799a
...
...
@@ -335,14 +335,14 @@ int lxc_unix_sockaddr(struct sockaddr_un *ret, const char *path)
len
=
strlen
(
path
);
if
(
len
==
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
path
[
0
]
!=
'/'
&&
path
[
0
]
!=
'@'
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
path
[
1
]
==
'\0'
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
len
+
1
>
sizeof
(
ret
->
sun_path
))
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
*
ret
=
(
struct
sockaddr_un
){
.
sun_family
=
AF_UNIX
,
...
...
src/lxc/attach.c
View file @
7453799a
...
...
@@ -104,9 +104,8 @@ static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
static
inline
void
lxc_proc_close_ns_fd
(
struct
lxc_proc_context_info
*
ctx
)
{
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
{
__do_close_prot_errno
int
fd
ATTR_UNUSED
=
move_fd
(
ctx
->
ns_fd
[
i
]);
}
for
(
int
i
=
0
;
i
<
LXC_NS_MAX
;
i
++
)
close_prot_errno_disarm
(
ctx
->
ns_fd
[
i
]);
}
static
void
lxc_proc_put_context_info
(
struct
lxc_proc_context_info
*
ctx
)
...
...
@@ -668,9 +667,8 @@ struct attach_clone_payload {
static
void
lxc_put_attach_clone_payload
(
struct
attach_clone_payload
*
p
)
{
__do_close_prot_errno
int
ipc_socket
ATTR_UNUSED
=
p
->
ipc_socket
;
__do_close_prot_errno
int
terminal_slave_fd
ATTR_UNUSED
=
p
->
terminal_slave_fd
;
close_prot_errno_disarm
(
p
->
ipc_socket
);
close_prot_errno_disarm
(
p
->
terminal_slave_fd
);
if
(
p
->
init_ctx
)
{
lxc_proc_put_context_info
(
p
->
init_ctx
);
p
->
init_ctx
=
NULL
;
...
...
@@ -1009,10 +1007,10 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
}
if
(
!
container
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
!
lxc_container_get
(
container
))
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
name
=
container
->
name
;
lxcpath
=
container
->
config_path
;
...
...
src/lxc/cgroups/cgfsng.c
View file @
7453799a
...
...
@@ -500,13 +500,11 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized)
copy_parent:
if
(
!
am_initialized
)
{
fpath
=
must_make_path
(
path
,
"cpuset.cpus"
,
NULL
);
ret
=
lxc_write_to_file
(
fpath
,
cpulist
,
strlen
(
cpulist
),
false
,
0666
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to write cpu list to
\"
%s
\"
"
,
fpath
);
return
false
;
}
ret
=
lxc_write_openat
(
path
,
"cpuset.cpus"
,
cpulist
,
strlen
(
cpulist
));
if
(
ret
<
0
)
return
log_error_errno
(
false
,
errno
,
"Failed to write cpu list to
\"
%s/cpuset.cpus
\"
"
,
path
);
TRACE
(
"Copied cpu settings of parent cgroup"
);
}
...
...
@@ -517,7 +515,7 @@ copy_parent:
/* Copy contents of parent(@path)/@file to @path/@file */
static
bool
copy_parent_file
(
char
*
path
,
char
*
file
)
{
__do_free
char
*
child_path
=
NULL
,
*
parent_path
=
NULL
,
*
value
=
NULL
;
__do_free
char
*
parent_path
=
NULL
,
*
value
=
NULL
;
int
ret
;
char
oldv
;
int
len
=
0
;
...
...
@@ -545,13 +543,17 @@ static bool copy_parent_file(char *path, char *file)
}
*
lastslash
=
oldv
;
child_path
=
must_make_path
(
path
,
file
,
NULL
);
ret
=
lxc_write_to_file
(
child_path
,
value
,
len
,
false
,
0666
);
ret
=
lxc_write_openat
(
path
,
file
,
value
,
len
);
if
(
ret
<
0
)
SYSERROR
(
"Failed to write
\"
%s
\"
to file
\"
%s
\"
"
,
value
,
child_path
);
SYSERROR
(
"Failed to write
\"
%s
\"
to file
\"
%s
/%s
\"
"
,
value
,
path
,
file
);
return
ret
>=
0
;
}
static
bool
is_unified_hierarchy
(
const
struct
hierarchy
*
h
)
{
return
h
->
version
==
CGROUP2_SUPER_MAGIC
;
}
/* Initialize the cpuset hierarchy in first directory of @gname and set
* cgroup.clone_children so that children inherit settings. Since the
* h->base_path is populated by init or ourselves, we know it is already
...
...
@@ -559,11 +561,15 @@ static bool copy_parent_file(char *path, char *file)
*/
static
bool
cg_legacy_handle_cpuset_hierarchy
(
struct
hierarchy
*
h
,
char
*
cgname
)
{
__do_free
char
*
cgpath
=
NULL
,
*
clonechildrenpath
=
NULL
;
__do_free
char
*
cgpath
=
NULL
;
__do_close_prot_errno
int
cgroup_fd
=
-
EBADF
;
int
ret
;
char
v
;
char
*
slash
;
if
(
is_unified_hierarchy
(
h
))
return
true
;
if
(
!
string_in_list
(
h
->
controllers
,
"cpuset"
))
return
true
;
...
...
@@ -585,14 +591,13 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
}
}
clonechildrenpath
=
must_make_path
(
cgpath
,
"cgroup.clone_children"
,
NULL
);
/* unified hierarchy doesn't have clone_children */
if
(
!
file_exists
(
clonechildrenpath
))
return
true
;
cgroup_fd
=
lxc_open_dirfd
(
cgpath
);
if
(
cgroup_fd
<
0
)
return
false
;
ret
=
lxc_read
_from_file
(
clonechildrenpath
,
&
v
,
1
);
ret
=
lxc_read
at
(
cgroup_fd
,
"cgroup.clone_children"
,
&
v
,
1
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to read file
\"
%s
\"
"
,
clonechildren
path
);
SYSERROR
(
"Failed to read file
\"
%s
/cgroup.clone_children
\"
"
,
cg
path
);
return
false
;
}
...
...
@@ -612,10 +617,10 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
return
false
;
}
ret
=
lxc_write
_to_file
(
clonechildrenpath
,
"1"
,
1
,
false
,
0666
);
ret
=
lxc_write
at
(
cgroup_fd
,
"cgroup.clone_children"
,
"1"
,
1
);
if
(
ret
<
0
)
{
/* Set clone_children so children inherit our settings */
SYSERROR
(
"Failed to write 1 to
\"
%s
\"
"
,
clonechildren
path
);
SYSERROR
(
"Failed to write 1 to
\"
%s
/cgroup.clone_children
\"
"
,
cg
path
);
return
false
;
}
...
...
@@ -1086,9 +1091,18 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops,
int
ret
;
struct
generic_userns_exec_data
wrap
;
if
(
!
ops
)
log_error_errno
(
return
,
ENOENT
,
"Called with uninitialized cgroup operations"
);
if
(
!
ops
->
hierarchies
)
return
;
if
(
!
handler
)
log_error_errno
(
return
,
EINVAL
,
"Called with uninitialized handler"
);
if
(
!
handler
->
conf
)
log_error_errno
(
return
,
EINVAL
,
"Called with uninitialized conf"
);
wrap
.
origuid
=
0
;
wrap
.
container_cgroup
=
ops
->
container_cgroup
;
wrap
.
hierarchies
=
ops
->
hierarchies
;
...
...
@@ -1115,12 +1129,23 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
struct
lxc_handler
*
handler
)
{
int
len
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
char
pidstr
[
INTTYPE_TO_STRLEN
(
pid_t
)];
struct
lxc_conf
*
conf
;
if
(
!
ops
)
log_error_errno
(
return
,
ENOENT
,
"Called with uninitialized cgroup operations"
);
if
(
!
ops
->
hierarchies
)
return
;
if
(
!
handler
)
log_error_errno
(
return
,
EINVAL
,
"Called with uninitialized handler"
);
if
(
!
handler
->
conf
)
log_error_errno
(
return
,
EINVAL
,
"Called with uninitialized conf"
);
conf
=
handler
->
conf
;
len
=
snprintf
(
pidstr
,
sizeof
(
pidstr
),
"%d"
,
handler
->
monitor_pid
);
if
(
len
<
0
||
(
size_t
)
len
>=
sizeof
(
pidstr
))
return
;
...
...
@@ -1155,16 +1180,15 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
* Make sure not to pass in the ro string literal PIVOT_CGROUP
* here.
*/
if
(
!
cg_legacy_handle_cpuset_hierarchy
(
h
,
pivot_cgroup
))
{
WARN
(
"Failed to handle legacy cpuset controller"
);
continue
;
}
if
(
!
cg_legacy_handle_cpuset_hierarchy
(
h
,
pivot_cgroup
))
log_warn_errno
(
continue
,
errno
,
"Failed to handle legacy cpuset controller"
);
ret
=
mkdir_p
(
pivot_path
,
0755
);
if
(
ret
<
0
&&
errno
!=
EEXIST
)
{
SYSWARN
(
"Failed to create cgroup
\"
%s
\"\n
"
,
pivot_path
);
continue
;
}
if
(
ret
<
0
&&
errno
!=
EEXIST
)
log_warn_errno
(
continue
,
errno
,
"Failed to create cgroup
\"
%s
\"\n
"
,
pivot_path
);
if
(
chop
)
*
chop
=
'/'
;
...
...
@@ -1173,10 +1197,10 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
* cgroup.
*/
ret
=
lxc_write_to_file
(
pivot_path
,
pidstr
,
len
,
false
,
0666
);
if
(
ret
!=
0
)
{
SYSWARN
(
"Failed to move monitor %s to
\"
%s
\"\n
"
,
pidstr
,
pivot_path
);
continue
;
}
if
(
ret
!=
0
)
log_warn_errno
(
continue
,
errno
,
"Failed to move monitor %s to
\"
%s
\"\n
"
,
pidstr
,
pivot_path
);
ret
=
recursive_destroy
(
h
->
monitor_full_path
);
if
(
ret
<
0
)
...
...
@@ -1284,14 +1308,22 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
char
*
offset
,
*
tmp
;
int
i
,
idx
=
0
;
size_t
len
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
lxc_conf
*
conf
;
if
(
!
conf
)
return
false
;
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
)
;
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
ops
->
monitor_cgroup
)
return
ret_set_errno
(
false
,
EEXIST
);
if
(
!
handler
||
!
handler
->
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
conf
=
handler
->
conf
;
if
(
conf
->
cgroup_meta
.
dir
)
tmp
=
lxc_string_join
(
"/"
,
(
const
char
*
[]){
conf
->
cgroup_meta
.
dir
,
...
...
@@ -1301,7 +1333,7 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
else
tmp
=
must_make_path
(
ops
->
monitor_pattern
,
handler
->
name
,
NULL
);
if
(
!
tmp
)
return
false
;
return
ret_set_errno
(
false
,
ENOMEM
)
;
len
=
strlen
(
tmp
)
+
5
;
/* leave room for -NNN\0 */
monitor_cgroup
=
must_realloc
(
tmp
,
len
);
...
...
@@ -1309,11 +1341,8 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
*
offset
=
0
;
do
{
if
(
idx
)
{
int
ret
=
snprintf
(
offset
,
5
,
"-%d"
,
idx
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
5
)
return
false
;
}
if
(
idx
)
sprintf
(
offset
,
"-%d"
,
idx
);
for
(
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
if
(
!
monitor_create_path_for_hierarchy
(
ops
->
hierarchies
[
i
],
...
...
@@ -1332,43 +1361,46 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
}
while
(
ops
->
hierarchies
[
i
]
&&
idx
>
0
&&
idx
<
1000
);
if
(
idx
==
1000
)
return
false
;
return
ret_set_errno
(
false
,
ERANGE
)
;
INFO
(
"The monitor process uses
\"
%s
\"
as cgroup"
,
monitor_cgroup
);
ops
->
monitor_cgroup
=
move_ptr
(
monitor_cgroup
);
return
true
;
return
log_info
(
true
,
"The monitor process uses
\"
%s
\"
as cgroup"
,
ops
->
monitor_cgroup
)
;
}
/* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
* next cgroup_pattern-1, -2, ..., -999.
*/
__cgfsng_ops
static
inline
bool
cgfsng_payload_create
(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
)
struct
lxc_handler
*
handler
)
{
__do_free
char
*
container_cgroup
=
NULL
,
*
tmp
=
NULL
;
int
idx
=
0
;
int
i
,
ret
;
size_t
len
;
char
*
offset
;
int
idx
=
0
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
if
(
ops
->
container_cgroup
)
return
false
;
struct
lxc_conf
*
conf
;
if
(
!
conf
)
return
false
;
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
)
;
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
ops
->
container_cgroup
)
return
ret_set_errno
(
false
,
EEXIST
);
if
(
!
handler
||
!
handler
->
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
conf
=
handler
->
conf
;
if
(
conf
->
cgroup_meta
.
dir
)
tmp
=
lxc_string_join
(
"/"
,
(
const
char
*
[]){
conf
->
cgroup_meta
.
dir
,
handler
->
name
,
NULL
},
false
);
else
tmp
=
lxc_string_replace
(
"%n"
,
handler
->
name
,
ops
->
cgroup_pattern
);
if
(
!
tmp
)
{
ERROR
(
"Failed expanding cgroup name pattern"
);
return
false
;
}
if
(
!
tmp
)
return
log_error_errno
(
false
,
ENOMEM
,
"Failed expanding cgroup name pattern"
);
len
=
strlen
(
tmp
)
+
5
;
/* leave room for -NNN\0 */
container_cgroup
=
must_realloc
(
NULL
,
len
);
...
...
@@ -1376,11 +1408,8 @@ __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
offset
=
container_cgroup
+
len
-
5
;
do
{
if
(
idx
)
{
ret
=
snprintf
(
offset
,
5
,
"-%d"
,
idx
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
5
)
return
false
;
}
if
(
idx
)
sprintf
(
offset
,
"-%d"
,
idx
);
for
(
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
if
(
!
container_create_path_for_hierarchy
(
ops
->
hierarchies
[
i
],
...
...
@@ -1398,7 +1427,7 @@ __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
}
while
(
ops
->
hierarchies
[
i
]
&&
idx
>
0
&&
idx
<
1000
);
if
(
idx
==
1000
)
return
false
;
return
ret_set_errno
(
false
,
ERANGE
)
;
INFO
(
"The container process uses
\"
%s
\"
as cgroup"
,
container_cgroup
);
ops
->
container_cgroup
=
move_ptr
(
container_cgroup
);
...
...
@@ -1422,9 +1451,18 @@ __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops,
char
monitor
[
INTTYPE_TO_STRLEN
(
pid_t
)],
transient
[
INTTYPE_TO_STRLEN
(
pid_t
)];
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
!
ops
->
monitor_cgroup
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
handler
||
!
handler
->
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
monitor_len
=
snprintf
(
monitor
,
sizeof
(
monitor
),
"%d"
,
handler
->
monitor_pid
);
if
(
handler
->
transient_pid
>
0
)
transient_len
=
snprintf
(
transient
,
sizeof
(
transient
),
"%d"
,
...
...
@@ -1458,9 +1496,18 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops,
int
len
;
char
pidstr
[
INTTYPE_TO_STRLEN
(
pid_t
)];
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
!
ops
->
container_cgroup
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
handler
||
!
handler
->
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
len
=
snprintf
(
pidstr
,
sizeof
(
pidstr
),
"%d"
,
handler
->
pid
);
for
(
int
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
...
...
@@ -1513,24 +1560,20 @@ static int chown_cgroup_wrapper(void *data)
gid_t
nsgid
=
(
arg
->
conf
->
root_nsgid_map
!=
NULL
)
?
0
:
arg
->
conf
->
init_gid
;
ret
=
setresgid
(
nsgid
,
nsgid
,
nsgid
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to setresgid(%d, %d, %d)"
,
(
int
)
nsgid
,
(
int
)
nsgid
,
(
int
)
nsgid
);
return
-
1
;
}
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to setresgid(%d, %d, %d)"
,
(
int
)
nsgid
,
(
int
)
nsgid
,
(
int
)
nsgid
);
ret
=
setresuid
(
nsuid
,
nsuid
,
nsuid
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to setresuid(%d, %d, %d)"
,
(
int
)
nsuid
,
(
int
)
nsuid
,
(
int
)
nsuid
);
return
-
1
;
}
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to setresuid(%d, %d, %d)"
,
(
int
)
nsuid
,
(
int
)
nsuid
,
(
int
)
nsuid
);
ret
=
setgroups
(
0
,
NULL
);
if
(
ret
<
0
&&
errno
!=
EPERM
)
{
SYSERROR
(
"Failed to setgroups(0, NULL)"
);
return
-
1
;
}
if
(
ret
<
0
&&
errno
!=
EPERM
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to setgroups(0, NULL)"
);
destuid
=
get_ns_uid
(
arg
->
origuid
);
if
(
destuid
==
LXC_INVALID_UID
)
...
...
@@ -1542,7 +1585,9 @@ static int chown_cgroup_wrapper(void *data)
ret
=
chowmod
(
path
,
destuid
,
nsgid
,
0775
);
if
(
ret
<
0
)
return
-
1
;
log_info_errno
(
continue
,
errno
,
"Failed to change %s to uid %d and gid %d and mode 0755"
,
path
,
destuid
,
nsgid
);
/* Failures to chown() these are inconvenient but not
* detrimental We leave these owned by the container launcher,
...
...
@@ -1553,18 +1598,27 @@ static int chown_cgroup_wrapper(void *data)
if
(
arg
->
hierarchies
[
i
]
->
version
==
CGROUP_SUPER_MAGIC
)
{
fullpath
=
must_make_path
(
path
,
"tasks"
,
NULL
);
(
void
)
chowmod
(
fullpath
,
destuid
,
nsgid
,
0664
);
ret
=
chowmod
(
fullpath
,
destuid
,
nsgid
,
0664
);
if
(
ret
<
0
)
SYSINFO
(
"Failed to change %s to uid %d and gid %d and mode 0664"
,
fullpath
,
destuid
,
nsgid
);
}
fullpath
=
must_make_path
(
path
,
"cgroup.procs"
,
NULL
);
(
void
)
chowmod
(
fullpath
,
destuid
,
nsgid
,
0664
);
ret
=
chowmod
(
fullpath
,
destuid
,
nsgid
,
0664
);
if
(
ret
<
0
)
SYSINFO
(
"Failed to change %s to uid %d and gid %d and mode 0664"
,
fullpath
,
destuid
,
nsgid
);
if
(
arg
->
hierarchies
[
i
]
->
version
!=
CGROUP2_SUPER_MAGIC
)
continue
;
for
(
char
**
p
=
arg
->
hierarchies
[
i
]
->
cgroup2_chown
;
p
&&
*
p
;
p
++
)
{
fullpath
=
must_make_path
(
path
,
*
p
,
NULL
);
(
void
)
chowmod
(
fullpath
,
destuid
,
nsgid
,
0664
);
ret
=
chowmod
(
fullpath
,
destuid
,
nsgid
,
0664
);
if
(
ret
<
0
)
SYSINFO
(
"Failed to change %s to uid %d and gid %d and mode 0664"
,
fullpath
,
destuid
,
nsgid
);
}
}
...
...
@@ -1572,26 +1626,32 @@ static int chown_cgroup_wrapper(void *data)
}
__cgfsng_ops
static
bool
cgfsng_chown
(
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
)
struct
lxc_conf
*
conf
)
{
struct
generic_userns_exec_data
wrap
;
if
(
lxc_list_empty
(
&
conf
->
id_map
)
)
return
true
;
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
)
;
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
!
ops
->
container_cgroup
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
if
(
lxc_list_empty
(
&
conf
->
id_map
))
return
true
;
wrap
.
origuid
=
geteuid
();
wrap
.
path
=
NULL
;
wrap
.
hierarchies
=
ops
->
hierarchies
;
wrap
.
conf
=
conf
;
if
(
userns_exec_1
(
conf
,
chown_cgroup_wrapper
,
&
wrap
,
"chown_cgroup_wrapper"
)
<
0
)
{
ERROR
(
"Error requesting cgroup chown in new user namespace"
);
return
false
;
}
if
(
userns_exec_1
(
conf
,
chown_cgroup_wrapper
,
&
wrap
,
"chown_cgroup_wrapper"
)
<
0
)
return
log_error_errno
(
false
,
errno
,
"Error requesting cgroup chown in new user namespace"
);
return
true
;
}
...
...
@@ -1728,9 +1788,15 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops,
int
ret
;
bool
has_cgns
=
false
,
retval
=
false
,
wants_force_mount
=
false
;
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
!
handler
||
!
handler
->
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
if
((
type
&
LXC_AUTO_CGROUP_MASK
)
==
0
)
return
true
;
...
...
@@ -1790,10 +1856,10 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops,
continue
;
ret
=
mkdir
(
controllerpath
,
0755
);
if
(
ret
<
0
)
{
SYSERROR
(
"Error creating cgroup path: %s"
,
controllerpath
);
goto
on_error
;
}
if
(
ret
<
0
)
log_error_errno
(
goto
on_error
,
errno
,
"Error creating cgroup path: %s"
,
controllerpath
);
if
(
has_cgns
&&
wants_force_mount
)
{
/* If cgroup namespaces are supported but the container
...
...
@@ -1872,8 +1938,11 @@ __cgfsng_ops static int cgfsng_nrtasks(struct cgroup_ops *ops)
{
__do_free
char
*
path
=
NULL
;
if
(
!
ops
)
return
ret_set_errno
(
-
1
,
ENOENT
);
if
(
!
ops
->
container_cgroup
||
!
ops
->
hierarchies
)
return
-
1
;
return
ret_set_errno
(
-
1
,
EINVAL
)
;
path
=
must_make_path
(
ops
->
hierarchies
[
0
]
->
container_full_path
,
NULL
);
return
recursive_count_nrtasks
(
path
);
...
...
@@ -1881,23 +1950,33 @@ __cgfsng_ops static int cgfsng_nrtasks(struct cgroup_ops *ops)
/* Only root needs to escape to the cgroup of its init. */
__cgfsng_ops
static
bool
cgfsng_escape
(
const
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
)
struct
lxc_conf
*
conf
)
{
if
(
conf
->
cgroup_meta
.
relative
||
geteuid
()
||
!
ops
->
hierarchies
)
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
!
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
if
(
conf
->
cgroup_meta
.
relative
||
geteuid
())
return
true
;
for
(
int
i
=
0
;
ops
->
hierarchies
[
i
];
i
++
)
{
int
ret
;
__do_free
char
*
fullpath
=
NULL
;
int
ret
;
fullpath
=
must_make_path
(
ops
->
hierarchies
[
i
]
->
mountpoint
,
ops
->
hierarchies
[
i
]
->
container_base_path
,
"cgroup.procs"
,
NULL
);
fullpath
=
must_make_path
(
ops
->
hierarchies
[
i
]
->
mountpoint
,
ops
->
hierarchies
[
i
]
->
container_base_path
,
"cgroup.procs"
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
"0"
,
2
,
false
,
0666
);
if
(
ret
!=
0
)
{
SYSERROR
(
"Failed to escape to cgroup
\"
%s
\"
"
,
fullpath
);
return
false
;
}
if
(
ret
!=
0
)
return
log_error_errno
(
false
,
errno
,
"Failed to escape to cgroup
\"
%s
\"
"
,
fullpath
);
}
return
true
;
...
...
@@ -1907,6 +1986,9 @@ __cgfsng_ops static int cgfsng_num_hierarchies(struct cgroup_ops *ops)
{
int
i
=
0
;
if
(
!
ops
)
return
ret_set_errno
(
-
1
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
0
;
...
...
@@ -1916,35 +1998,37 @@ __cgfsng_ops static int cgfsng_num_hierarchies(struct cgroup_ops *ops)
return
i
;
}
__cgfsng_ops
static
bool
cgfsng_get_hierarchies
(
struct
cgroup_ops
*
ops
,
int
n
,
char
***
out
)
__cgfsng_ops
static
bool
cgfsng_get_hierarchies
(
struct
cgroup_ops
*
ops
,
int
n
,
char
***
out
)
{
int
i
;
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
false
;
/* sanity check n */
for
(
i
=
0
;
i
<
n
;
i
++
)
if
(
!
ops
->
hierarchies
[
i
])
return
false
;
return
ret_set_errno
(
false
,
ENOENT
)
;
*
out
=
ops
->
hierarchies
[
i
]
->
controllers
;
return
true
;
}
static
bool
cg_legacy_freeze
(
struct
cgroup_ops
*
ops
)
{
__do_free
char
*
path
=
NULL
;
struct
hierarchy
*
h
;
h
=
get_hierarchy
(
ops
,
"freezer"
);
if
(
!
h
)
return
minus_one_set_errno
(
ENOENT
);
return
ret_set_errno
(
-
1
,
ENOENT
);
path
=
must_make_path
(
h
->
container_full_path
,
"freezer.state"
,
NULL
);
return
lxc_write_to_file
(
path
,
"FROZEN"
,
STRLITERALLEN
(
"FROZEN"
),
false
,
0666
);
return
lxc_write_openat
(
h
->
container_full_path
,
"freezer.state"
,
"FROZEN"
,
STRLITERALLEN
(
"FROZEN"
)
);
}
static
int
freezer_cgroup_events_cb
(
int
fd
,
uint32_t
events
,
void
*
cbdata
,
...
...
@@ -1984,7 +2068,6 @@ static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata,
static
int
cg_unified_freeze
(
struct
cgroup_ops
*
ops
,
int
timeout
)
{
__do_close_prot_errno
int
fd
=
-
EBADF
;
__do_free
char
*
path
=
NULL
;
__do_lxc_mainloop_close
struct
lxc_epoll_descr
*
descr_ptr
=
NULL
;
int
ret
;
struct
lxc_epoll_descr
descr
;
...
...
@@ -1992,10 +2075,10 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
h
=
ops
->
unified
;
if
(
!
h
)
return
minus_one_set_errno
(
ENOENT
);
return
ret_set_errno
(
-
1
,
ENOENT
);
if
(
!
h
->
container_full_path
)
return
minus_one_set_errno
(
EEXIST
);
return
ret_set_errno
(
-
1
,
EEXIST
);
if
(
timeout
!=
0
)
{
__do_free
char
*
events_file
=
NULL
;
...
...
@@ -2003,27 +2086,26 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
events_file
=
must_make_path
(
h
->
container_full_path
,
"cgroup.events"
,
NULL
);
fd
=
open
(
events_file
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
return
error_log_errno
(
errno
,
"Failed to open cgroup.events file"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to open cgroup.events file"
);
ret
=
lxc_mainloop_open
(
&
descr
);
if
(
ret
)
return
error_log_errno
(
errno
,
"Failed to create epoll instance to wait for container freeze"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to create epoll instance to wait for container freeze"
);
/* automatically cleaned up now */
descr_ptr
=
&
descr
;
ret
=
lxc_mainloop_add_handler
(
&
descr
,
fd
,
freezer_cgroup_events_cb
,
INT_TO_PTR
((
int
){
1
}));
if
(
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to add cgroup.events fd handler to mainloop"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add cgroup.events fd handler to mainloop"
);
}
path
=
must_make_path
(
h
->
container_full_path
,
"cgroup.freeze"
,
NULL
);
ret
=
lxc_write_to_file
(
path
,
"1"
,
1
,
false
,
0666
);
ret
=
lxc_write_openat
(
h
->
container_full_path
,
"cgroup.freeze"
,
"1"
,
1
);
if
(
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to open cgroup.freeze file"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to open cgroup.freeze file"
);
if
(
timeout
!=
0
&&
lxc_mainloop
(
&
descr
,
timeout
))
return
error_log_errno
(
errno
,
"Failed to wait for container to be frozen"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to wait for container to be frozen"
);
return
0
;
}
...
...
@@ -2031,7 +2113,7 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout)
__cgfsng_ops
static
int
cgfsng_freeze
(
struct
cgroup_ops
*
ops
,
int
timeout
)
{
if
(
!
ops
->
hierarchies
)
return
minus_one_set_errno
(
ENOENT
);
return
ret_set_errno
(
-
1
,
ENOENT
);
if
(
ops
->
cgroup_layout
!=
CGROUP_LAYOUT_UNIFIED
)
return
cg_legacy_freeze
(
ops
);
...
...
@@ -2041,21 +2123,19 @@ __cgfsng_ops static int cgfsng_freeze(struct cgroup_ops *ops, int timeout)
static
int
cg_legacy_unfreeze
(
struct
cgroup_ops
*
ops
)
{
__do_free
char
*
path
=
NULL
;
struct
hierarchy
*
h
;
h
=
get_hierarchy
(
ops
,
"freezer"
);
if
(
!
h
)
return
minus_one_set_errno
(
ENOENT
);
return
ret_set_errno
(
-
1
,
ENOENT
);
path
=
must_make_path
(
h
->
container_full_path
,
"freezer.state"
,
NULL
);
return
lxc_write_to_file
(
path
,
"THAWED"
,
STRLITERALLEN
(
"THAWED"
),
false
,
0666
);
return
lxc_write_openat
(
h
->
container_full_path
,
"freezer.state"
,
"THAWED"
,
STRLITERALLEN
(
"THAWED"
)
);
}
static
int
cg_unified_unfreeze
(
struct
cgroup_ops
*
ops
,
int
timeout
)
{
__do_close_prot_errno
int
fd
=
-
EBADF
;
__do_free
char
*
path
=
NULL
;
__do_lxc_mainloop_close
struct
lxc_epoll_descr
*
descr_ptr
=
NULL
;
int
ret
;
struct
lxc_epoll_descr
descr
;
...
...
@@ -2063,10 +2143,10 @@ static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout)
h
=
ops
->
unified
;
if
(
!
h
)
return
minus_one_set_errno
(
ENOENT
);
return
ret_set_errno
(
-
1
,
ENOENT
);
if
(
!
h
->
container_full_path
)
return
minus_one_set_errno
(
EEXIST
);
return
ret_set_errno
(
-
1
,
EEXIST
);
if
(
timeout
!=
0
)
{
__do_free
char
*
events_file
=
NULL
;
...
...
@@ -2074,27 +2154,26 @@ static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout)
events_file
=
must_make_path
(
h
->
container_full_path
,
"cgroup.events"
,
NULL
);
fd
=
open
(
events_file
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
return
error_log_errno
(
errno
,
"Failed to open cgroup.events file"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to open cgroup.events file"
);
ret
=
lxc_mainloop_open
(
&
descr
);
if
(
ret
)
return
error_log_errno
(
errno
,
"Failed to create epoll instance to wait for container unfreeze"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to create epoll instance to wait for container unfreeze"
);
/* automatically cleaned up now */
descr_ptr
=
&
descr
;
ret
=
lxc_mainloop_add_handler
(
&
descr
,
fd
,
freezer_cgroup_events_cb
,
INT_TO_PTR
((
int
){
0
}));
if
(
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to add cgroup.events fd handler to mainloop"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add cgroup.events fd handler to mainloop"
);
}
path
=
must_make_path
(
h
->
container_full_path
,
"cgroup.freeze"
,
NULL
);
ret
=
lxc_write_to_file
(
path
,
"0"
,
1
,
false
,
0666
);
ret
=
lxc_write_openat
(
h
->
container_full_path
,
"cgroup.freeze"
,
"0"
,
1
);
if
(
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to open cgroup.freeze file"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to open cgroup.freeze file"
);
if
(
timeout
!=
0
&&
lxc_mainloop
(
&
descr
,
timeout
))
return
error_log_errno
(
errno
,
"Failed to wait for container to be unfrozen"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to wait for container to be unfrozen"
);
return
0
;
}
...
...
@@ -2102,7 +2181,7 @@ static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout)
__cgfsng_ops
static
int
cgfsng_unfreeze
(
struct
cgroup_ops
*
ops
,
int
timeout
)
{
if
(
!
ops
->
hierarchies
)
return
minus_one_set_errno
(
ENOENT
);
return
ret_set_errno
(
-
1
,
ENOENT
);
if
(
ops
->
cgroup_layout
!=
CGROUP_LAYOUT_UNIFIED
)
return
cg_legacy_unfreeze
(
ops
);
...
...
@@ -2111,18 +2190,19 @@ __cgfsng_ops static int cgfsng_unfreeze(struct cgroup_ops *ops, int timeout)
}
__cgfsng_ops
static
const
char
*
cgfsng_get_cgroup
(
struct
cgroup_ops
*
ops
,
const
char
*
controller
)
const
char
*
controller
)
{
struct
hierarchy
*
h
;
h
=
get_hierarchy
(
ops
,
controller
);
if
(
!
h
)
{
WARN
(
"Failed to find hierarchy for controller
\"
%s
\"
"
,
controller
?
controller
:
"(null)"
);
return
NULL
;
}
if
(
!
h
)
return
log_warn_errno
(
NULL
,
ENOENT
,
"Failed to find hierarchy for controller
\"
%s
\"
"
,
controller
?
controller
:
"(null)"
);
return
h
->
container_full_path
?
h
->
container_full_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,
...
...
@@ -2137,51 +2217,53 @@ static inline char *build_full_cgpath_from_monitorpath(struct hierarchy *h,
static
int
cgroup_attach_leaf
(
int
unified_fd
,
int64_t
pid
)
{
int
idx
=
0
;
int
idx
=
1
;
int
ret
;
char
pidstr
[
INTTYPE_TO_STRLEN
(
int64_t
)
+
1
];
char
attach_cgroup
[
STRLITERALLEN
(
"lxc-1000/cgroup.procs"
)
+
1
];
size_t
pidstr_len
;
/* Create leaf cgroup. */
ret
=
mkdirat
(
unified_fd
,
"lxc"
,
0755
);
if
(
ret
<
0
&&
errno
!=
EEXIST
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to create leaf cgroup
\"
lxc
\"
"
);
pidstr_len
=
sprintf
(
pidstr
,
INT64_FMT
,
pid
);
ret
=
lxc_writeat
(
unified_fd
,
"cgroup.procs"
,
pidstr
,
pidstr_len
);
ret
=
lxc_writeat
(
unified_fd
,
"lxc/cgroup.procs"
,
pidstr
,
pidstr_len
);
if
(
ret
<
0
)
ret
=
lxc_writeat
(
unified_fd
,
"cgroup.procs"
,
pidstr
,
pidstr_len
);
if
(
ret
==
0
)
return
0
;
/* this is a non-leaf node */
if
(
errno
!=
EBUSY
)
return
error_log_errno
(
errno
,
"Failed to attach to unified cgroup"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to attach to unified cgroup"
);
do
{
char
*
slash
;
char
attach_cgroup
[
STRLITERALLEN
(
"lxc-1000/cgroup.procs"
)
+
1
];
if
(
idx
)
ret
=
snprintf
(
attach_cgroup
,
sizeof
(
attach_cgroup
),
"lxc-%d/cgroup.procs"
,
idx
);
else
ret
=
snprintf
(
attach_cgroup
,
sizeof
(
attach_cgroup
),
"lxc/cgroup.procs"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
attach_cgroup
))
return
-
1
;
sprintf
(
attach_cgroup
,
"lxc-%d/cgroup.procs"
,
idx
);
slash
=
&
attach_cgroup
[
ret
]
-
STRLITERALLEN
(
"/cgroup.procs"
);
*
slash
=
'\0'
;
ret
=
mkdirat
(
unified_fd
,
attach_cgroup
,
0755
);
if
(
ret
<
0
&&
errno
!=
EEXIST
)
return
error_log_errno
(
errno
,
"Failed to create cgroup %s"
,
attach_cgroup
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to create cgroup %s"
,
attach_cgroup
);
*
slash
=
'/'
;
ret
=
lxc_writeat
(
unified_fd
,
attach_cgroup
,
pidstr
,
pidstr_len
);
if
(
ret
==
0
)
return
0
;
/* this is a non-leaf node */
if
(
errno
!=
EBUSY
)
return
error_log_errno
(
errno
,
"Failed to attach to unified cgroup"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to attach to unified cgroup"
);
idx
++
;
}
while
(
idx
<
1000
);
return
-
1
;
return
log_error_errno
(
-
1
,
errno
,
"Failed to attach to unified cgroup"
)
;
}
int
cgroup_attach
(
const
char
*
name
,
const
char
*
lxcpath
,
int64_t
pid
)
...
...
@@ -2235,6 +2317,9 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name,
int
len
,
ret
;
char
pidstr
[
INTTYPE_TO_STRLEN
(
pid_t
)];
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
true
;
...
...
@@ -2262,10 +2347,10 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, const char *name,
fullpath
=
build_full_cgpath_from_monitorpath
(
h
,
path
,
"cgroup.procs"
);
ret
=
lxc_write_to_file
(
fullpath
,
pidstr
,
len
,
false
,
0666
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to attach %d to %s"
,
(
int
)
pid
,
fullpath
);
return
false
;
}
if
(
ret
<
0
)
return
log_error_errno
(
false
,
errno
,
"Failed to attach %d to %s"
,
(
int
)
pid
,
fullpath
);
}
return
true
;
...
...
@@ -2285,6 +2370,9 @@ __cgfsng_ops static int cgfsng_get(struct cgroup_ops *ops, const char *filename,
struct
hierarchy
*
h
;
int
ret
=
-
1
;
if
(
!
ops
)
return
ret_set_errno
(
-
1
,
ENOENT
);
controller
=
must_copy_string
(
filename
);
p
=
strchr
(
controller
,
'.'
);
if
(
p
)
...
...
@@ -2425,6 +2513,9 @@ __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops,
struct
hierarchy
*
h
;
int
ret
=
-
1
;
if
(
!
ops
)
return
ret_set_errno
(
-
1
,
ENOENT
);
controller
=
must_copy_string
(
key
);
p
=
strchr
(
controller
,
'.'
);
if
(
p
)
...
...
@@ -2435,7 +2526,7 @@ __cgfsng_ops static int cgfsng_set(struct cgroup_ops *ops,
ret
=
device_cgroup_rule_parse
(
&
device
,
key
,
value
);
if
(
ret
<
0
)
return
error_log_errno
(
EINVAL
,
"Failed to parse device string %s=%s"
,
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to parse device string %s=%s"
,
key
,
value
);
ret
=
lxc_cmd_add_bpf_device_cgroup
(
name
,
lxcpath
,
&
device
);
...
...
@@ -2546,12 +2637,10 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
const
char
*
value
)
{
__do_free
char
*
controller
=
NULL
;
__do_free
char
*
fullpath
=
NULL
;
char
*
p
;
/* "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max */
char
converted_value
[
50
];
struct
hierarchy
*
h
;
int
ret
=
0
;
controller
=
must_copy_string
(
filename
);
p
=
strchr
(
controller
,
'.'
);
...
...
@@ -2559,6 +2648,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
*
p
=
'\0'
;
if
(
strcmp
(
"devices.allow"
,
filename
)
==
0
&&
value
[
0
]
==
'/'
)
{
int
ret
;
ret
=
convert_devpath
(
value
,
converted_value
);
if
(
ret
<
0
)
return
ret
;
...
...
@@ -2575,9 +2666,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
return
-
ENOENT
;
}
fullpath
=
must_make_path
(
h
->
container_full_path
,
filename
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
value
,
strlen
(
value
),
false
,
0666
);
return
ret
;
return
lxc_write_openat
(
h
->
container_full_path
,
filename
,
value
,
strlen
(
value
));
}
__cgfsng_ops
static
bool
cgfsng_setup_limits_legacy
(
struct
cgroup_ops
*
ops
,
...
...
@@ -2590,11 +2679,18 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops,
struct
lxc_cgroup
*
cg
;
bool
ret
=
false
;
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
cgroup_settings
=
&
conf
->
cgroup
;
if
(
lxc_list_empty
(
cgroup_settings
))
return
true
;
if
(
!
ops
->
hierarchies
)
return
false
;
return
ret_set_errno
(
false
,
EINVAL
)
;
sorted_cgroup_settings
=
sort_cgroup_settings
(
cgroup_settings
);
if
(
!
sorted_cgroup_settings
)
...
...
@@ -2605,14 +2701,13 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops,
if
(
do_devices
==
!
strncmp
(
"devices"
,
cg
->
subsystem
,
7
))
{
if
(
cg_legacy_set_data
(
ops
,
cg
->
subsystem
,
cg
->
value
))
{
if
(
do_devices
&&
(
errno
==
EACCES
||
errno
==
EPERM
))
{
WARN
(
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
continue
;
}
WARN
(
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
goto
out
;
if
(
do_devices
&&
(
errno
==
EACCES
||
errno
==
EPERM
))
log_warn_errno
(
continue
,
errno
,
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
log_warn_errno
(
goto
out
,
errno
,
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
}
DEBUG
(
"Set controller
\"
%s
\"
set to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
...
...
@@ -2644,7 +2739,7 @@ static int bpf_device_cgroup_prepare(struct cgroup_ops *ops,
ret
=
device_cgroup_rule_parse
(
&
device_item
,
key
,
val
);
if
(
ret
<
0
)
return
error_log_errno
(
EINVAL
,
return
log_error_errno
(
-
1
,
EINVAL
,
"Failed to parse device string %s=%s"
,
key
,
val
);
...
...
@@ -2658,41 +2753,51 @@ static int bpf_device_cgroup_prepare(struct cgroup_ops *ops,
__cgfsng_ops
static
bool
cgfsng_setup_limits
(
struct
cgroup_ops
*
ops
,
struct
lxc_handler
*
handler
)
{
struct
lxc_list
*
iterator
;
struct
hierarchy
*
h
=
ops
->
unified
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
lxc_list
*
cgroup_settings
=
&
conf
->
cgroup2
;
struct
lxc_list
*
cgroup_settings
,
*
iterator
;
struct
hierarchy
*
h
;
struct
lxc_conf
*
conf
;
if
(
lxc_list_empty
(
cgroup_settings
))
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
!
h
)
if
(
!
ops
->
container_cgroup
)
return
ret_set_errno
(
false
,
EINVAL
);
if
(
!
handler
||
!
handler
->
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
conf
=
handler
->
conf
;
if
(
lxc_list_empty
(
&
conf
->
cgroup2
))
return
true
;
cgroup_settings
=
&
conf
->
cgroup2
;
if
(
!
ops
->
unified
)
return
false
;
h
=
ops
->
unified
;
lxc_list_for_each
(
iterator
,
cgroup_settings
)
{
__do_free
char
*
fullpath
=
NULL
;
int
ret
;
struct
lxc_cgroup
*
cg
=
iterator
->
elem
;
int
ret
;
if
(
strncmp
(
"devices"
,
cg
->
subsystem
,
7
)
==
0
)
{
ret
=
bpf_device_cgroup_prepare
(
ops
,
conf
,
cg
->
subsystem
,
cg
->
value
);
}
else
{
fullpath
=
must_make_path
(
h
->
container_full_path
,
cg
->
subsystem
,
NULL
);
ret
=
lxc_write_to_file
(
fullpath
,
cg
->
value
,
strlen
(
cg
->
value
),
false
,
0666
);
if
(
ret
<
0
)
{
SYSERROR
(
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
return
false
;
}
ret
=
lxc_write_openat
(
h
->
container_full_path
,
cg
->
subsystem
,
cg
->
value
,
strlen
(
cg
->
value
));
if
(
ret
<
0
)
return
log_error_errno
(
false
,
errno
,
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
}
TRACE
(
"Set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
}
INFO
(
"Limits for the unified cgroup hierarchy have been setup"
);
return
true
;
return
log_info
(
true
,
"Limits for the unified cgroup hierarchy have been setup"
);
}
__cgfsng_ops
bool
cgfsng_devices_activate
(
struct
cgroup_ops
*
ops
,
...
...
@@ -2700,12 +2805,26 @@ __cgfsng_ops bool cgfsng_devices_activate(struct cgroup_ops *ops,
{
#ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX
__do_bpf_program_free
struct
bpf_program
*
devices
=
NULL
;
struct
lxc_conf
*
conf
=
handler
->
conf
;
struct
hierarchy
*
unified
=
ops
->
unified
;
int
ret
;
struct
lxc_conf
*
conf
;
struct
hierarchy
*
unified
;
struct
lxc_list
*
it
;
struct
bpf_program
*
devices_old
;
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
if
(
!
ops
->
hierarchies
)
return
true
;
if
(
!
ops
->
container_cgroup
)
return
ret_set_errno
(
false
,
EEXIST
);
if
(
!
handler
||
!
handler
->
conf
)
return
ret_set_errno
(
false
,
EINVAL
);
conf
=
handler
->
conf
;
unified
=
ops
->
unified
;
if
(
!
unified
||
!
unified
->
bpf_device_controller
||
!
unified
->
container_full_path
||
lxc_list_empty
(
&
conf
->
devices
))
return
true
;
...
...
@@ -2806,10 +2925,10 @@ bool __cgfsng_delegate_controllers(struct cgroup_ops *ops, const char *cgroup)
base_path
=
must_append_path
(
base_path
,
parts
[
i
],
NULL
);
target
=
must_make_path
(
base_path
,
"cgroup.subtree_control"
,
NULL
);
ret
=
lxc_writeat
(
-
1
,
target
,
add_controllers
,
full_len
);
if
(
ret
<
0
)
{
SYSERROR
(
"Could not enable
\"
%s
\"
controllers in the unified cgroup
\"
%s
\"
"
,
add_controllers
,
target
);
goto
on_error
;
}
if
(
ret
<
0
)
log_error_errno
(
goto
on_error
,
errno
,
"Could not enable
\"
%s
\"
controllers in the unified cgroup
\"
%s
\"
"
,
add_controllers
,
target
);
TRACE
(
"Enable
\"
%s
\"
controllers in the unified cgroup
\"
%s
\"
"
,
add_controllers
,
target
);
}
...
...
@@ -2822,11 +2941,17 @@ on_error:
__cgfsng_ops
bool
cgfsng_monitor_delegate_controllers
(
struct
cgroup_ops
*
ops
)
{
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
return
__cgfsng_delegate_controllers
(
ops
,
ops
->
monitor_cgroup
);
}
__cgfsng_ops
bool
cgfsng_payload_delegate_controllers
(
struct
cgroup_ops
*
ops
)
{
if
(
!
ops
)
return
ret_set_errno
(
false
,
ENOENT
);
return
__cgfsng_delegate_controllers
(
ops
,
ops
->
container_cgroup
);
}
...
...
@@ -2858,37 +2983,37 @@ static bool cgroup_use_wants_controllers(const struct cgroup_ops *ops,
static
void
cg_unified_delegate
(
char
***
delegate
)
{
__do_free
char
*
tmp
=
NULL
;
int
idx
;
__do_free
char
*
buf
=
NULL
;
char
*
standard
[]
=
{
"cgroup.subtree_control"
,
"cgroup.threads"
,
NULL
};
char
*
token
;
int
idx
;
tmp
=
read_file
(
"/sys/kernel/cgroup/delegate"
);
if
(
!
tmp
)
{
buf
=
read_file
(
"/sys/kernel/cgroup/delegate"
);
if
(
!
buf
)
{
for
(
char
**
p
=
standard
;
p
&&
*
p
;
p
++
)
{
idx
=
append_null_to_list
((
void
***
)
delegate
);
(
*
delegate
)[
idx
]
=
must_copy_string
(
*
p
);
}
}
else
{
char
*
token
;
lxc_iterate_parts
(
token
,
tmp
,
"
\t\n
"
)
{
/*
* We always need to chown this for both cgroup and
* cgroup2.
*/
if
(
strcmp
(
token
,
"cgroup.procs"
)
==
0
)
continue
;
log_warn_errno
(
return
,
errno
,
"Failed to read /sys/kernel/cgroup/delegate"
);
}
idx
=
append_null_to_list
((
void
***
)
delegate
);
(
*
delegate
)[
idx
]
=
must_copy_string
(
token
);
}
lxc_iterate_parts
(
token
,
buf
,
"
\t\n
"
)
{
/*
* We always need to chown this for both cgroup and
* cgroup2.
*/
if
(
strcmp
(
token
,
"cgroup.procs"
)
==
0
)
continue
;
idx
=
append_null_to_list
((
void
***
)
delegate
);
(
*
delegate
)[
idx
]
=
must_copy_string
(
token
);
}
}
/* At startup, parse_hierarchies finds all the info we need about cgroup
* mountpoints and current cgroups, and stores it in @d.
*/
static
bool
cg_hybrid_init
(
struct
cgroup_ops
*
ops
,
bool
relative
,
bool
unprivileged
)
static
int
cg_hybrid_init
(
struct
cgroup_ops
*
ops
,
bool
relative
,
bool
unprivileged
)
{
__do_free
char
*
basecginfo
=
NULL
;
__do_free
char
*
line
=
NULL
;
...
...
@@ -2905,19 +3030,15 @@ static bool cg_hybrid_init(struct cgroup_ops *ops, bool relative,
else
basecginfo
=
read_file
(
"/proc/self/cgroup"
);
if
(
!
basecginfo
)
return
false
;
return
ret_set_errno
(
-
1
,
ENOMEM
)
;
ret
=
get_existing_subsystems
(
&
klist
,
&
nlist
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to retrieve available legacy cgroup controllers"
);
return
false
;
}
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to retrieve available legacy cgroup controllers"
);
f
=
fopen
(
"/proc/self/mountinfo"
,
"r"
);
if
(
!
f
)
{
ERROR
(
"Failed to open
\"
/proc/self/mountinfo
\"
"
);
return
false
;
}
if
(
!
f
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to open
\"
/proc/self/mountinfo
\"
"
);
lxc_cgfsng_print_basecg_debuginfo
(
basecginfo
,
klist
,
nlist
);
...
...
@@ -2954,22 +3075,18 @@ static bool cg_hybrid_init(struct cgroup_ops *ops, bool relative,
if
(
type
==
CGROUP_SUPER_MAGIC
)
if
(
controller_list_is_dup
(
ops
->
hierarchies
,
controller_list
))
goto
next
;
log_trace_errno
(
goto
next
,
EEXIST
,
"Skipping duplicating controller"
)
;
mountpoint
=
cg_hybrid_get_mountpoint
(
line
);
if
(
!
mountpoint
)
{
ERROR
(
"Failed parsing mountpoint from
\"
%s
\"
"
,
line
);
goto
next
;
}
if
(
!
mountpoint
)
log_error_errno
(
goto
next
,
EINVAL
,
"Failed parsing mountpoint from
\"
%s
\"
"
,
line
);
if
(
type
==
CGROUP_SUPER_MAGIC
)
base_cgroup
=
cg_hybrid_get_current_cgroup
(
basecginfo
,
controller_list
[
0
],
CGROUP_SUPER_MAGIC
);
else
base_cgroup
=
cg_hybrid_get_current_cgroup
(
basecginfo
,
NULL
,
CGROUP2_SUPER_MAGIC
);
if
(
!
base_cgroup
)
{
ERROR
(
"Failed to find current cgroup"
);
goto
next
;
}
if
(
!
base_cgroup
)
log_error_errno
(
goto
next
,
EINVAL
,
"Failed to find current cgroup"
);
trim
(
base_cgroup
);
prune_init_scope
(
base_cgroup
);
...
...
@@ -2978,7 +3095,7 @@ static bool cg_hybrid_init(struct cgroup_ops *ops, bool relative,
else
writeable
=
test_writeable_v1
(
mountpoint
,
base_cgroup
);
if
(
!
writeable
)
goto
next
;
log_trace_errno
(
goto
next
,
EROFS
,
"The %s group is not writeable"
,
base_cgroup
)
;
if
(
type
==
CGROUP2_SUPER_MAGIC
)
{
char
*
cgv2_ctrl_path
;
...
...
@@ -2998,7 +3115,7 @@ static bool cg_hybrid_init(struct cgroup_ops *ops, bool relative,
/* Exclude all controllers that cgroup use does not want. */
if
(
!
cgroup_use_wants_controllers
(
ops
,
controller_list
))
goto
next
;
log_trace_errno
(
goto
next
,
EINVAL
,
"Skipping controller"
)
;
new
=
add_hierarchy
(
&
ops
->
hierarchies
,
controller_list
,
mountpoint
,
base_cgroup
,
type
);
if
(
type
==
CGROUP2_SUPER_MAGIC
&&
!
ops
->
unified
)
{
...
...
@@ -3025,9 +3142,9 @@ static bool cg_hybrid_init(struct cgroup_ops *ops, bool relative,
* controllers are accounted for
*/
if
(
!
all_controllers_found
(
ops
))
return
false
;
return
log_error_errno
(
-
1
,
ENOENT
,
"Failed to find all required controllers"
)
;
return
true
;
return
0
;
}
/* Get current cgroup from /proc/self/cgroup for the cgroupfs v2 hierarchy. */
...
...
@@ -3072,20 +3189,21 @@ static int cg_unified_init(struct cgroup_ops *ops, bool relative,
ret
=
unified_cgroup_hierarchy
();
if
(
ret
==
-
ENOMEDIUM
)
return
-
ENOMEDIUM
;
return
ret_errno
(
ENOMEDIUM
)
;
if
(
ret
!=
CGROUP2_SUPER_MAGIC
)
return
0
;
base_cgroup
=
cg_unified_get_current_cgroup
(
relative
);
if
(
!
base_cgroup
)
return
-
EINVAL
;
return
ret_errno
(
EINVAL
)
;
if
(
!
relative
)
prune_init_scope
(
base_cgroup
);
/* We assume that we have already been given controllers to delegate
* further down the hierarchy. If not it is up to the user to delegate
* them to us.
/*
* 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.
*/
mountpoint
=
must_copy_string
(
DEFAULT_CGROUP_MOUNTPOINT
);
subtree_path
=
must_make_path
(
mountpoint
,
base_cgroup
,
"cgroup.controllers"
,
NULL
);
...
...
@@ -3103,7 +3221,7 @@ static int cg_unified_init(struct cgroup_ops *ops, bool relative,
*/
new
=
add_hierarchy
(
&
ops
->
hierarchies
,
delegatable
,
mountpoint
,
base_cgroup
,
CGROUP2_SUPER_MAGIC
);
if
(
!
unprivileged
)
if
(
unprivileged
)
cg_unified_delegate
(
&
new
->
cgroup2_chown
);
if
(
bpf_devices_cgroup_supported
())
...
...
@@ -3114,7 +3232,7 @@ static int cg_unified_init(struct cgroup_ops *ops, bool relative,
return
CGROUP2_SUPER_MAGIC
;
}
static
bool
cg_init
(
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
)
static
int
cg_init
(
struct
cgroup_ops
*
ops
,
struct
lxc_conf
*
conf
)
{
int
ret
;
const
char
*
tmp
;
...
...
@@ -3134,29 +3252,32 @@ static bool cg_init(struct cgroup_ops *ops, struct lxc_conf *conf)
ret
=
cg_unified_init
(
ops
,
relative
,
!
lxc_list_empty
(
&
conf
->
id_map
));
if
(
ret
<
0
)
return
false
;
return
-
1
;
if
(
ret
==
CGROUP2_SUPER_MAGIC
)
return
true
;
return
0
;
return
cg_hybrid_init
(
ops
,
relative
,
!
lxc_list_empty
(
&
conf
->
id_map
));
}
__cgfsng_ops
static
bool
cgfsng_data_init
(
struct
cgroup_ops
*
ops
)
__cgfsng_ops
static
int
cgfsng_data_init
(
struct
cgroup_ops
*
ops
)
{
const
char
*
cgroup_pattern
;
if
(
!
ops
)
return
ret_set_errno
(
-
1
,
ENOENT
);
/* copy system-wide cgroup information */
cgroup_pattern
=
lxc_global_config_value
(
"lxc.cgroup.pattern"
);
if
(
!
cgroup_pattern
)
{
/* lxc.cgroup.pattern is only NULL on error. */
ERROR
(
"Failed to retrieve cgroup pattern"
);
return
false
;
return
ret_set_errno
(
-
1
,
ENOMEM
)
;
}
ops
->
cgroup_pattern
=
must_copy_string
(
cgroup_pattern
);
ops
->
monitor_pattern
=
MONITOR_CGROUP
;
return
true
;
return
0
;
}
struct
cgroup_ops
*
cgfsng_ops_init
(
struct
lxc_conf
*
conf
)
...
...
@@ -3165,12 +3286,12 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
cgfsng_ops
=
malloc
(
sizeof
(
struct
cgroup_ops
));
if
(
!
cgfsng_ops
)
return
NULL
;
return
ret_set_errno
(
NULL
,
ENOMEM
)
;
memset
(
cgfsng_ops
,
0
,
sizeof
(
struct
cgroup_ops
));
cgfsng_ops
->
cgroup_layout
=
CGROUP_LAYOUT_UNKNOWN
;
if
(
!
cg_init
(
cgfsng_ops
,
conf
))
if
(
cg_init
(
cgfsng_ops
,
conf
))
return
NULL
;
cgfsng_ops
->
unified_fd
=
-
EBADF
;
...
...
src/lxc/cgroups/cgroup.c
View file @
7453799a
...
...
@@ -24,19 +24,16 @@ struct cgroup_ops *cgroup_init(struct lxc_conf *conf)
{
struct
cgroup_ops
*
cgroup_ops
;
if
(
!
conf
)
{
ERROR
(
"No valid conf given"
);
return
NULL
;
}
if
(
!
conf
)
return
log_error_errno
(
NULL
,
EINVAL
,
"No valid conf given"
);
cgroup_ops
=
cgfsng_ops_init
(
conf
);
if
(
!
cgroup_ops
)
{
ERROR
(
"Failed to initialize cgroup driver"
);
return
NULL
;
}
if
(
!
cgroup_ops
)
return
log_error_errno
(
NULL
,
errno
,
"Failed to initialize cgroup driver"
);
if
(
!
cgroup_ops
->
data_init
(
cgroup_ops
))
return
NULL
;
if
(
cgroup_ops
->
data_init
(
cgroup_ops
))
return
log_error_errno
(
NULL
,
errno
,
"Failed to initialize cgroup data"
);
TRACE
(
"Initialized cgroup driver %s"
,
cgroup_ops
->
driver
);
...
...
src/lxc/cgroups/cgroup.h
View file @
7453799a
...
...
@@ -132,7 +132,7 @@ struct cgroup_ops {
*/
cgroup_layout_t
cgroup_layout
;
bool
(
*
data_init
)(
struct
cgroup_ops
*
ops
);
int
(
*
data_init
)(
struct
cgroup_ops
*
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
);
...
...
src/lxc/cgroups/cgroup2_devices.c
View file @
7453799a
...
...
@@ -35,11 +35,11 @@ static int bpf_program_add_instructions(struct bpf_program *prog,
struct
bpf_insn
*
new_insn
;
if
(
prog
->
kernel_fd
>=
0
)
return
error_log_errno
(
EBUSY
,
"Refusing to update bpf cgroup program that's already loaded"
);
return
log_error_errno
(
-
1
,
EBUSY
,
"Refusing to update bpf cgroup program that's already loaded"
);
new_insn
=
realloc
(
prog
->
instructions
,
sizeof
(
struct
bpf_insn
)
*
(
count
+
prog
->
n_instructions
));
if
(
!
new_insn
)
return
error_log_errno
(
ENOMEM
,
"Failed to reallocate bpf cgroup program"
);
return
log_error_errno
(
-
1
,
ENOMEM
,
"Failed to reallocate bpf cgroup program"
);
prog
->
instructions
=
new_insn
;
memcpy
(
prog
->
instructions
+
prog
->
n_instructions
,
instructions
,
...
...
@@ -184,7 +184,7 @@ struct bpf_program *bpf_program_new(uint32_t prog_type)
int
bpf_program_init
(
struct
bpf_program
*
prog
)
{
if
(
!
prog
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
const
struct
bpf_insn
pre_insn
[]
=
{
/* load device type to r2 */
...
...
@@ -217,7 +217,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
int
device_type
;
if
(
!
prog
||
!
device
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
/* This is a global rule so no need to append anything. */
if
(
device
->
global_rule
>
LXC_BPF_DEVICE_CGROUP_LOCAL_RULE
)
{
...
...
@@ -227,7 +227,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
device_type
=
bpf_device_type
(
device
->
type
);
if
(
device_type
<
0
)
return
error_log_errno
(
EINVAL
,
"Invalid bpf cgroup device type %c"
,
device
->
type
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Invalid bpf cgroup device type %c"
,
device
->
type
);
if
(
device_type
>
0
)
jump_nr
++
;
...
...
@@ -249,7 +249,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
if
(
ret
)
return
error_log_errno
(
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
}
if
(
!
bpf_device_all_access
(
access_mask
))
{
...
...
@@ -262,7 +262,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
jump_nr
-=
3
;
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
if
(
ret
)
return
error_log_errno
(
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
}
if
(
device
->
major
>=
0
)
{
...
...
@@ -272,7 +272,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
if
(
ret
)
return
error_log_errno
(
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
}
if
(
device
->
minor
>=
0
)
{
...
...
@@ -282,13 +282,13 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
if
(
ret
)
return
error_log_errno
(
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
}
ret
=
bpf_program_add_instructions
(
prog
,
bpf_access_decision
,
ARRAY_SIZE
(
bpf_access_decision
));
if
(
ret
)
return
error_log_errno
(
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
0
;
}
...
...
@@ -301,7 +301,7 @@ int bpf_program_finalize(struct bpf_program *prog)
};
if
(
!
prog
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
TRACE
(
"Implementing %s bpf device cgroup program"
,
prog
->
device_list_type
==
LXC_BPF_DEVICE_CGROUP_BLACKLIST
...
...
@@ -332,7 +332,7 @@ static int bpf_program_load_kernel(struct bpf_program *prog, char *log_buf,
prog
->
kernel_fd
=
bpf
(
BPF_PROG_LOAD
,
&
attr
,
sizeof
(
attr
));
if
(
prog
->
kernel_fd
<
0
)
return
error_log_errno
(
errno
,
"Failed to load bpf program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to load bpf program"
);
return
0
;
}
...
...
@@ -346,17 +346,17 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
int
ret
;
if
(
!
prog
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
flags
&
~
(
BPF_F_ALLOW_OVERRIDE
,
BPF_F_ALLOW_MULTI
))
return
error_log_errno
(
EINVAL
,
"Invalid flags for bpf program"
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Invalid flags for bpf program"
);
if
(
prog
->
attached_path
)
{
if
(
prog
->
attached_type
!=
type
)
return
error_log_errno
(
EBUSY
,
"Wrong type for bpf program"
);
return
log_error_errno
(
-
1
,
EBUSY
,
"Wrong type for bpf program"
);
if
(
prog
->
attached_flags
!=
flags
)
return
error_log_errno
(
EBUSY
,
"Wrong flags for bpf program"
);
return
log_error_errno
(
-
1
,
EBUSY
,
"Wrong flags for bpf program"
);
if
(
flags
!=
BPF_F_ALLOW_OVERRIDE
)
return
true
;
...
...
@@ -364,15 +364,15 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
ret
=
bpf_program_load_kernel
(
prog
,
NULL
,
0
);
if
(
ret
<
0
)
return
error_log_errno
(
ret
,
"Failed to load bpf program"
);
return
log_error_errno
(
-
1
,
ret
,
"Failed to load bpf program"
);
copy
=
strdup
(
path
);
if
(
!
copy
)
return
error_log_errno
(
ENOMEM
,
"Failed to duplicate cgroup path %s"
,
path
);
return
log_error_errno
(
-
1
,
ENOMEM
,
"Failed to duplicate cgroup path %s"
,
path
);
fd
=
open
(
path
,
O_DIRECTORY
|
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
return
error_log_errno
(
errno
,
"Failed to open cgroup path %s"
,
path
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to open cgroup path %s"
,
path
);
attr
=
(
union
bpf_attr
){
.
attach_type
=
type
,
...
...
@@ -383,7 +383,7 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
ret
=
bpf
(
BPF_PROG_ATTACH
,
&
attr
,
sizeof
(
attr
));
if
(
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to attach bpf program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to attach bpf program"
);
free_replace_move_ptr
(
prog
->
attached_path
,
copy
);
prog
->
attached_type
=
type
;
...
...
@@ -407,7 +407,7 @@ int bpf_program_cgroup_detach(struct bpf_program *prog)
fd
=
open
(
prog
->
attached_path
,
O_DIRECTORY
|
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
{
if
(
errno
!=
ENOENT
)
return
error_log_errno
(
errno
,
"Failed to open attach cgroup %s"
,
return
log_error_errno
(
-
1
,
errno
,
"Failed to open attach cgroup %s"
,
prog
->
attached_path
);
}
else
{
union
bpf_attr
attr
;
...
...
@@ -420,7 +420,7 @@ int bpf_program_cgroup_detach(struct bpf_program *prog)
ret
=
bpf
(
BPF_PROG_DETACH
,
&
attr
,
sizeof
(
attr
));
if
(
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to detach bpf program from cgroup %s"
,
return
log_error_errno
(
-
1
,
errno
,
"Failed to detach bpf program from cgroup %s"
,
prog
->
attached_path
);
}
...
...
@@ -488,11 +488,11 @@ int bpf_list_add_device(struct lxc_conf *conf, struct device_item *device)
list_elem
=
malloc
(
sizeof
(
*
list_elem
));
if
(
!
list_elem
)
return
error_log_errno
(
ENOMEM
,
"Failed to allocate new device list"
);
return
log_error_errno
(
-
1
,
ENOMEM
,
"Failed to allocate new device list"
);
new_device
=
memdup
(
device
,
sizeof
(
struct
device_item
));
if
(
!
new_device
)
return
error_log_errno
(
ENOMEM
,
"Failed to allocate new device item"
);
return
log_error_errno
(
-
1
,
ENOMEM
,
"Failed to allocate new device item"
);
lxc_list_add_elem
(
list_elem
,
move_ptr
(
new_device
));
lxc_list_add_tail
(
&
conf
->
devices
,
move_ptr
(
list_elem
));
...
...
src/lxc/commands.c
View file @
7453799a
...
...
@@ -913,16 +913,16 @@ int lxc_cmd_add_bpf_device_cgroup(const char *name, const char *lxcpath,
int
ret
;
if
(
strlen
(
device
->
access
)
>
STRLITERALLEN
(
"rwm"
))
return
error_log_errno
(
EINVAL
,
"Invalid access mode specified %s"
,
return
log_error_errno
(
-
1
,
EINVAL
,
"Invalid access mode specified %s"
,
device
->
access
);
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
ret
<
0
||
cmd
.
rsp
.
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to add new bpf device cgroup rule"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add new bpf device cgroup rule"
);
return
0
;
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -1006,7 +1006,7 @@ reap_client_fd:
*/
return
1
;
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -1155,7 +1155,7 @@ int lxc_cmd_seccomp_notify_add_listener(const char *name, const char *lxcpath,
return
cmd
.
rsp
.
ret
;
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -1211,7 +1211,7 @@ int lxc_cmd_freeze(const char *name, const char *lxcpath, int timeout)
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
ret
<=
0
||
cmd
.
rsp
.
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to freeze container"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to freeze container"
);
return
cmd
.
rsp
.
ret
;
}
...
...
@@ -1244,7 +1244,7 @@ int lxc_cmd_unfreeze(const char *name, const char *lxcpath, int timeout)
ret
=
lxc_cmd
(
name
,
&
cmd
,
&
stopped
,
lxcpath
,
NULL
);
if
(
ret
<=
0
||
cmd
.
rsp
.
ret
<
0
)
return
error_log_errno
(
errno
,
"Failed to unfreeze container"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to unfreeze container"
);
return
cmd
.
rsp
.
ret
;
}
...
...
src/lxc/compiler.h
View file @
7453799a
...
...
@@ -45,6 +45,13 @@
#define __returns_twice __attribute__((returns_twice))
#endif
/* This attribute is required to silence clang warnings */
#if defined(__GNUC__)
#define __lxc_unused __attribute__ ((unused))
#else
#define __lxc_unused
#endif
#define __cgfsng_ops
#endif
/* __LXC_COMPILER_H */
src/lxc/confile.c
View file @
7453799a
...
...
@@ -401,11 +401,11 @@ static int set_config_net_l2proxy(const char *key, const char *value,
return
clr_config_net_l2proxy
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
ret
=
lxc_safe_uint
(
value
,
&
val
);
if
(
ret
<
0
)
return
minus_one_set_errno
(
-
ret
);
return
ret_set_errno
(
-
1
,
-
ret
);
switch
(
val
)
{
case
0
:
...
...
@@ -416,7 +416,7 @@ static int set_config_net_l2proxy(const char *key, const char *value,
return
0
;
}
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
static
int
set_config_net_name
(
const
char
*
key
,
const
char
*
value
,
...
...
@@ -485,11 +485,11 @@ static int set_config_net_ipvlan_mode(const char *key, const char *value,
return
clr_config_net_ipvlan_mode
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
{
SYSERROR
(
"Invalid ipvlan mode
\"
%s
\"
, can only be used with ipvlan network"
,
value
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
return
lxc_ipvlan_mode_to_flag
(
&
netdev
->
priv
.
ipvlan_attr
.
mode
,
value
);
...
...
@@ -504,11 +504,11 @@ static int set_config_net_ipvlan_isolation(const char *key, const char *value,
return
clr_config_net_ipvlan_isolation
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
{
SYSERROR
(
"Invalid ipvlan isolation
\"
%s
\"
, can only be used with ipvlan network"
,
value
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
return
lxc_ipvlan_isolation_to_flag
(
&
netdev
->
priv
.
ipvlan_attr
.
isolation
,
value
);
...
...
@@ -729,11 +729,11 @@ static int set_config_net_veth_ipv4_route(const char *key, const char *value,
return
clr_config_net_veth_ipv4_route
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
{
SYSERROR
(
"Invalid ipv4 route
\"
%s
\"
, can only be used with veth network"
,
value
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
inetdev
=
malloc
(
sizeof
(
*
inetdev
));
...
...
@@ -754,22 +754,22 @@ static int set_config_net_veth_ipv4_route(const char *key, const char *value,
slash
=
strchr
(
valdup
,
'/'
);
if
(
!
slash
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
*
slash
=
'\0'
;
slash
++
;
if
(
*
slash
==
'\0'
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
netmask
=
slash
;
ret
=
lxc_safe_uint
(
netmask
,
&
inetdev
->
prefix
);
if
(
ret
<
0
||
inetdev
->
prefix
>
32
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
ret
=
inet_pton
(
AF_INET
,
valdup
,
&
inetdev
->
addr
);
if
(
!
ret
||
ret
<
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
lxc_list_add_tail
(
&
netdev
->
priv
.
veth_attr
.
ipv4_routes
,
list
);
move_ptr
(
inetdev
);
...
...
@@ -900,11 +900,11 @@ static int set_config_net_veth_ipv6_route(const char *key, const char *value,
return
clr_config_net_veth_ipv6_route
(
key
,
lxc_conf
,
data
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
{
SYSERROR
(
"Invalid ipv6 route
\"
%s
\"
, can only be used with veth network"
,
value
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
inet6dev
=
malloc
(
sizeof
(
*
inet6dev
));
...
...
@@ -925,22 +925,22 @@ static int set_config_net_veth_ipv6_route(const char *key, const char *value,
slash
=
strchr
(
valdup
,
'/'
);
if
(
!
slash
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
*
slash
=
'\0'
;
slash
++
;
if
(
*
slash
==
'\0'
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
netmask
=
slash
;
ret
=
lxc_safe_uint
(
netmask
,
&
inet6dev
->
prefix
);
if
(
ret
<
0
||
inet6dev
->
prefix
>
128
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
ret
=
inet_pton
(
AF_INET6
,
valdup
,
&
inet6dev
->
addr
);
if
(
!
ret
||
ret
<
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
lxc_list_add_tail
(
&
netdev
->
priv
.
veth_attr
.
ipv6_routes
,
list
);
move_ptr
(
inet6dev
);
...
...
@@ -1004,7 +1004,7 @@ static int set_config_seccomp_allow_nesting(const char *key, const char *value,
return
-
1
;
if
(
lxc_conf
->
seccomp
.
allow_nesting
>
1
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
return
0
;
#else
...
...
@@ -1019,7 +1019,7 @@ static int set_config_seccomp_notify_cookie(const char *key, const char *value,
#ifdef HAVE_SECCOMP_NOTIFY
return
set_config_string_item
(
&
lxc_conf
->
seccomp
.
notifier
.
cookie
,
value
);
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -1033,7 +1033,7 @@ static int set_config_seccomp_notify_proxy(const char *key, const char *value,
return
clr_config_seccomp_notify_proxy
(
key
,
lxc_conf
,
NULL
);
if
(
strncmp
(
value
,
"unix:"
,
5
)
!=
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
offset
=
value
+
5
;
if
(
lxc_unix_sockaddr
(
&
lxc_conf
->
seccomp
.
notifier
.
proxy_addr
,
offset
)
<
0
)
...
...
@@ -1041,7 +1041,7 @@ static int set_config_seccomp_notify_proxy(const char *key, const char *value,
return
0
;
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -3985,7 +3985,7 @@ static int get_config_seccomp_notify_cookie(const char *key, char *retv, int inl
#ifdef HAVE_SECCOMP_NOTIFY
return
lxc_get_conf_str
(
retv
,
inlen
,
c
->
seccomp
.
notifier
.
cookie
);
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -3998,7 +3998,7 @@ static int get_config_seccomp_notify_proxy(const char *key, char *retv, int inle
?
&
c
->
seccomp
.
notifier
.
proxy_addr
.
sun_path
[
0
]
:
&
c
->
seccomp
.
notifier
.
proxy_addr
.
sun_path
[
1
]);
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -4611,7 +4611,7 @@ static inline int clr_config_seccomp_notify_cookie(const char *key,
c
->
seccomp
.
notifier
.
cookie
=
NULL
;
return
0
;
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -4623,7 +4623,7 @@ static inline int clr_config_seccomp_notify_proxy(const char *key,
sizeof
(
c
->
seccomp
.
notifier
.
proxy_addr
));
return
0
;
#else
return
minus_one_set_errno
(
ENOSYS
);
return
ret_set_errno
(
-
1
,
ENOSYS
);
#endif
}
...
...
@@ -5064,7 +5064,7 @@ static int clr_config_net_l2proxy(const char *key, struct lxc_conf *lxc_conf,
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
netdev
->
l2proxy
=
false
;
...
...
@@ -5093,7 +5093,7 @@ static int clr_config_net_ipvlan_mode(const char *key,
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
...
...
@@ -5109,7 +5109,7 @@ static int clr_config_net_ipvlan_isolation(const char *key,
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
...
...
@@ -5125,7 +5125,7 @@ static int clr_config_net_veth_mode(const char *key,
struct
lxc_netdev
*
netdev
=
data
;
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
return
0
;
...
...
@@ -5493,7 +5493,7 @@ static int get_config_net_ipvlan_mode(const char *key, char *retv, int inlen,
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
...
...
@@ -5532,7 +5532,7 @@ static int get_config_net_ipvlan_isolation(const char *key, char *retv, int inle
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_IPVLAN
)
return
0
;
...
...
@@ -5571,7 +5571,7 @@ static int get_config_net_veth_mode(const char *key, char *retv, int inlen,
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
return
0
;
...
...
@@ -5800,7 +5800,7 @@ static int get_config_net_veth_ipv4_route(const char *key, char *retv, int inlen
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
return
0
;
...
...
@@ -5891,7 +5891,7 @@ static int get_config_net_veth_ipv6_route(const char *key, char *retv, int inlen
memset
(
retv
,
0
,
inlen
);
if
(
!
netdev
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
if
(
netdev
->
type
!=
LXC_NET_VETH
)
return
0
;
...
...
src/lxc/confile_utils.c
View file @
7453799a
...
...
@@ -503,7 +503,7 @@ int lxc_veth_mode_to_flag(int *mode, const char *value)
return
0
;
}
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
static
struct
lxc_macvlan_mode
{
...
...
src/lxc/file_utils.c
View file @
7453799a
...
...
@@ -18,6 +18,27 @@
#include "string_utils.h"
#include "utils.h"
int
lxc_open_dirfd
(
const
char
*
dir
)
{
return
open
(
dir
,
O_DIRECTORY
|
O_RDONLY
|
O_CLOEXEC
);
}
int
lxc_readat
(
int
dirfd
,
const
char
*
filename
,
void
*
buf
,
size_t
count
)
{
__do_close_prot_errno
int
fd
=
-
EBADF
;
ssize_t
ret
;
fd
=
openat
(
dirfd
,
filename
,
O_RDONLY
|
O_CLOEXEC
);
if
(
fd
<
0
)
return
-
1
;
ret
=
lxc_read_nointr
(
fd
,
buf
,
count
);
if
(
ret
<
0
||
(
size_t
)
ret
!=
count
)
return
-
1
;
return
0
;
}
int
lxc_writeat
(
int
dirfd
,
const
char
*
filename
,
const
void
*
buf
,
size_t
count
)
{
__do_close_prot_errno
int
fd
=
-
EBADF
;
...
...
@@ -34,6 +55,18 @@ int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count)
return
0
;
}
int
lxc_write_openat
(
const
char
*
dir
,
const
char
*
filename
,
const
void
*
buf
,
size_t
count
)
{
__do_close_prot_errno
int
dirfd
=
-
EBADF
;
dirfd
=
open
(
dir
,
O_DIRECTORY
|
O_RDONLY
|
O_CLOEXEC
);
if
(
dirfd
<
0
)
return
-
1
;
return
lxc_writeat
(
dirfd
,
filename
,
buf
,
count
);
}
int
lxc_write_to_file
(
const
char
*
filename
,
const
void
*
buf
,
size_t
count
,
bool
add_newline
,
mode_t
mode
)
{
...
...
src/lxc/file_utils.h
View file @
7453799a
...
...
@@ -15,8 +15,11 @@
/* read and write whole files */
extern
int
lxc_write_to_file
(
const
char
*
filename
,
const
void
*
buf
,
size_t
count
,
bool
add_newline
,
mode_t
mode
);
extern
int
lxc_readat
(
int
dirfd
,
const
char
*
filename
,
void
*
buf
,
size_t
count
);
extern
int
lxc_writeat
(
int
dirfd
,
const
char
*
filename
,
const
void
*
buf
,
size_t
count
);
extern
int
lxc_write_openat
(
const
char
*
dir
,
const
char
*
filename
,
const
void
*
buf
,
size_t
count
);
extern
int
lxc_read_from_file
(
const
char
*
filename
,
void
*
buf
,
size_t
count
);
/* send and receive buffers completely */
...
...
@@ -47,5 +50,6 @@ extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset,
size_t
count
);
extern
char
*
file_to_buf
(
char
*
path
,
size_t
*
length
);
extern
int
fd_to_fd
(
int
from
,
int
to
);
extern
int
lxc_open_dirfd
(
const
char
*
dir
);
#endif
/* __LXC_FILE_UTILS_H */
src/lxc/log.h
View file @
7453799a
...
...
@@ -26,13 +26,6 @@
#define LXC_LOG_PREFIX_SIZE 32
#define LXC_LOG_BUFFER_SIZE 4096
/* This attribute is required to silence clang warnings */
#if defined(__GNUC__)
#define ATTR_UNUSED __attribute__ ((unused))
#else
#define ATTR_UNUSED
#endif
/* predefined lxc log priorities. */
enum
lxc_loglevel
{
LXC_LOG_LEVEL_TRACE
,
...
...
@@ -245,10 +238,10 @@ static inline void __lxc_log(const struct lxc_log_category *category,
*/
#define lxc_log_priority_define(acategory, LEVEL) \
\
ATTR_UNUSED
__attribute__ ((format (printf, 2, 3))) \
__lxc_unused
__attribute__ ((format (printf, 2, 3))) \
static inline void LXC_##LEVEL(struct lxc_log_locinfo *, const char *, ...); \
\
ATTR_UNUSED
static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
__lxc_unused
static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
const char* format, ...) \
{ \
if (lxc_log_priority_is_enabled(acategory, LXC_LOG_LEVEL_##LEVEL)) { \
...
...
@@ -484,19 +477,6 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
} while (0)
#endif
#define error_log_errno(__errno__, format, ...) \
({ \
errno = __errno__; \
SYSERROR(format, ##__VA_ARGS__); \
-1; \
})
#define log_trace(__ret__, format, ...) \
({ \
TRACE(format, ##__VA_ARGS__); \
__ret__; \
})
#define log_error_errno(__ret__, __errno__, format, ...) \
({ \
errno = __errno__; \
...
...
@@ -510,6 +490,19 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
__ret__; \
})
#define log_trace_errno(__ret__, __errno__, format, ...) \
({ \
errno = __errno__; \
SYSTRACE(format, ##__VA_ARGS__); \
__ret__; \
})
#define log_trace(__ret__, format, ...) \
({ \
TRACE(format, ##__VA_ARGS__); \
__ret__; \
})
#define log_warn_errno(__ret__, __errno__, format, ...) \
({ \
errno = __errno__; \
...
...
@@ -517,16 +510,30 @@ ATTR_UNUSED static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
__ret__; \
})
#define log_debug_errno(__ret__, __errno__, format, ...) \
({ \
errno = __errno__; \
SYSDEBUG(format, ##__VA_ARGS__); \
__ret__; \
})
#define log_debug(__ret__, format, ...) \
({ \
DEBUG(format, ##__VA_ARGS__); \
__ret__; \
})
#define log_debug_errno(__ret__, __errno__, format, ...) \
({ \
SYSDEBUG(format, ##__VA_ARGS__); \
__ret__; \
#define log_info_errno(__ret__, __errno__, format, ...) \
({ \
errno = __errno__; \
SYSINFO(format, ##__VA_ARGS__); \
__ret__; \
})
#define log_info(__ret__, format, ...) \
({ \
INFO(format, ##__VA_ARGS__); \
__ret__; \
})
extern
int
lxc_log_fd
;
...
...
src/lxc/lxccontainer.c
View file @
7453799a
...
...
@@ -5262,7 +5262,7 @@ out:
static
int
do_lxcapi_seccomp_notify_fd
(
struct
lxc_container
*
c
)
{
if
(
!
c
||
!
c
->
lxc_conf
)
return
minus_one_set_errno
(
-
EINVAL
);
return
ret_set_errno
(
-
1
,
-
EINVAL
);
return
lxc_seccomp_get_notify_fd
(
&
c
->
lxc_conf
->
seccomp
);
}
...
...
src/lxc/macro.h
View file @
7453799a
...
...
@@ -442,18 +442,18 @@ enum {
__internal_fd__; \
})
#define minus_one_set_errno(__errno__) \
({ \
errno = __errno__; \
-1; \
})
#define ret_set_errno(__ret__, __errno__) \
({ \
errno = __errno__; \
__ret__; \
})
#define ret_errno(__errno__) \
({ \
errno = __errno__; \
-__errno__; \
})
#define free_replace_move_ptr(a, b) \
({ \
free(a); \
...
...
src/lxc/network.c
View file @
7453799a
...
...
@@ -131,7 +131,7 @@ static int lxc_setup_ipv4_routes(struct lxc_list *ip, int ifindex)
if
(
err
)
{
SYSERROR
(
"Failed to setup ipv4 route for network device "
"with ifindex %d"
,
ifindex
);
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
...
...
@@ -150,7 +150,7 @@ static int lxc_setup_ipv6_routes(struct lxc_list *ip, int ifindex)
if
(
err
)
{
SYSERROR
(
"Failed to setup ipv6 route for network device "
"with ifindex %d"
,
ifindex
);
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
...
...
@@ -168,7 +168,7 @@ static int setup_ipv4_addr_routes(struct lxc_list *ip, int ifindex)
err
=
lxc_ipv4_dest_add
(
ifindex
,
&
inetdev
->
addr
,
32
);
if
(
err
)
return
error_log_errno
(
err
,
return
log_error_errno
(
-
1
,
err
,
"Failed to setup ipv4 address route for network device with eifindex %d"
,
ifindex
);
}
...
...
@@ -186,7 +186,7 @@ static int setup_ipv6_addr_routes(struct lxc_list *ip, int ifindex)
err
=
lxc_ipv6_dest_add
(
ifindex
,
&
inet6dev
->
addr
,
128
);
if
(
err
)
return
error_log_errno
(
err
,
return
log_error_errno
(
-
1
,
err
,
"Failed to setup ipv6 address route for network device with eifindex %d"
,
ifindex
);
}
...
...
@@ -258,13 +258,13 @@ static int lxc_is_ip_forwarding_enabled(const char *ifname, int family)
char
buf
[
1
]
=
""
;
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
"forwarding"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
return
minus_one_set_errno
(
E2BIG
);
return
ret_set_errno
(
-
1
,
E2BIG
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
}
...
...
@@ -401,19 +401,19 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
if
(
netdev
->
ipv4_gateway
)
{
char
bufinet4
[
INET_ADDRSTRLEN
];
if
(
!
inet_ntop
(
AF_INET
,
netdev
->
ipv4_gateway
,
bufinet4
,
sizeof
(
bufinet4
)))
{
error_log_errno
(
-
errno
,
"Failed to convert gateway ipv4 address on
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
-
errno
,
"Failed to convert gateway ipv4 address on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to activate ipv4 forwarding on
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
err
,
"Failed to activate ipv4 forwarding on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_add_ip_neigh_proxy
(
bufinet4
,
veth1
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to add gateway ipv4 proxy on
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
err
,
"Failed to add gateway ipv4 proxy on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
}
...
...
@@ -422,7 +422,7 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
char
bufinet6
[
INET6_ADDRSTRLEN
];
if
(
!
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
)))
{
error_log_errno
(
-
errno
,
"Failed to convert gateway ipv6 address on
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
-
errno
,
"Failed to convert gateway ipv6 address on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
...
...
@@ -431,25 +431,25 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
*/
err
=
lxc_is_ip_forwarding_enabled
(
"all"
,
AF_INET6
);
if
(
err
)
{
error_log_errno
(
err
,
"Requires sysctl net.ipv6.conf.all.forwarding=1"
);
log_error_errno
(
-
1
,
err
,
"Requires sysctl net.ipv6.conf.all.forwarding=1"
);
goto
out_delete
;
}
err
=
lxc_ip_forwarding_on
(
veth1
,
AF_INET6
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to activate ipv6 forwarding on
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
err
,
"Failed to activate ipv6 forwarding on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_neigh_proxy_on
(
veth1
,
AF_INET6
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to activate proxy ndp on
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
err
,
"Failed to activate proxy ndp on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
err
=
lxc_add_ip_neigh_proxy
(
bufinet6
,
veth1
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to add gateway ipv6 proxy on
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
err
,
"Failed to add gateway ipv6 proxy on
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
}
...
...
@@ -457,14 +457,14 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
/* setup ipv4 address routes on the host interface */
err
=
setup_ipv4_addr_routes
(
&
netdev
->
ipv4
,
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
/* setup ipv6 address routes on the host interface */
err
=
setup_ipv6_addr_routes
(
&
netdev
->
ipv6
,
netdev
->
priv
.
veth_attr
.
ifindex
);
if
(
err
)
{
error_log_errno
(
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
log_error_errno
(
-
1
,
err
,
"Failed to setup ip address routes for network device
\"
%s
\"
"
,
veth1
);
goto
out_delete
;
}
}
...
...
@@ -580,19 +580,19 @@ static int lxc_ipvlan_create(const char *master, const char *name, int mode, int
len
=
strlen
(
master
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
len
=
strlen
(
name
);
if
(
len
==
1
||
len
>=
IFNAMSIZ
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
index
=
if_nametoindex
(
master
);
if
(
!
index
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
err
=
netlink_open
(
&
nlh
,
NETLINK_ROUTE
);
if
(
err
)
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
err
=
-
ENOMEM
;
nlmsg
=
nlmsg_alloc
(
NLMSG_GOOD_SIZE
);
...
...
@@ -653,7 +653,7 @@ out:
nlmsg_free
(
answer
);
nlmsg_free
(
nlmsg
);
if
(
err
<
0
)
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
return
0
;
}
...
...
@@ -846,7 +846,7 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
mtu_orig
=
netdev_get_mtu
(
netdev
->
ifindex
);
if
(
mtu_orig
<
0
)
{
SYSERROR
(
"Failed to get original mtu for interface
\"
%s
\"
"
,
netdev
->
link
);
return
minus_one_set_errno
(
-
mtu_orig
);
return
ret_set_errno
(
-
1
,
-
mtu_orig
);
}
netdev
->
priv
.
phys_attr
.
mtu
=
mtu_orig
;
...
...
@@ -2007,13 +2007,13 @@ static int lxc_is_ip_neigh_proxy_enabled(const char *ifname, int family)
char
buf
[
1
]
=
""
;
if
(
family
!=
AF_INET
&&
family
!=
AF_INET6
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
ret
=
snprintf
(
path
,
PATH_MAX
,
"/proc/sys/net/%s/conf/%s/%s"
,
family
==
AF_INET
?
"ipv4"
:
"ipv6"
,
ifname
,
family
==
AF_INET
?
"proxy_arp"
:
"proxy_ndp"
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
PATH_MAX
)
return
minus_one_set_errno
(
E2BIG
);
return
ret_set_errno
(
-
1
,
E2BIG
);
return
lxc_read_file_expect
(
path
,
buf
,
1
,
"1"
);
}
...
...
@@ -3047,7 +3047,7 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* Check for net.ipv4.conf.[link].forwarding=1 */
if
(
lxc_is_ip_forwarding_enabled
(
netdev
->
link
,
AF_INET
)
<
0
)
{
ERROR
(
"Requires sysctl net.ipv4.conf.%s.forwarding=1"
,
netdev
->
link
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
}
...
...
@@ -3056,13 +3056,13 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* Check for net.ipv6.conf.[link].proxy_ndp=1 */
if
(
lxc_is_ip_neigh_proxy_enabled
(
netdev
->
link
,
AF_INET6
)
<
0
)
{
ERROR
(
"Requires sysctl net.ipv6.conf.%s.proxy_ndp=1"
,
netdev
->
link
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* Check for net.ipv6.conf.[link].forwarding=1 */
if
(
lxc_is_ip_forwarding_enabled
(
netdev
->
link
,
AF_INET6
)
<
0
)
{
ERROR
(
"Requires sysctl net.ipv6.conf.%s.forwarding=1"
,
netdev
->
link
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
}
...
...
@@ -3071,31 +3071,31 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
/* Check mode is l3s as other modes do not work with l2proxy. */
if
(
netdev
->
priv
.
ipvlan_attr
.
mode
!=
IPVLAN_MODE_L3S
)
{
ERROR
(
"Requires ipvlan mode on dev
\"
%s
\"
be l3s when used with l2proxy"
,
netdev
->
link
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* Retrieve local-loopback interface index for use with IPVLAN static routes. */
lo_ifindex
=
if_nametoindex
(
loop_device
);
if
(
lo_ifindex
==
0
)
{
ERROR
(
"Failed to retrieve ifindex for
\"
%s
\"
routing cleanup"
,
loop_device
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
}
lxc_list_for_each_safe
(
cur
,
&
netdev
->
ipv4
,
next
)
{
inet4dev
=
cur
->
elem
;
if
(
!
inet_ntop
(
AF_INET
,
&
inet4dev
->
addr
,
bufinet4
,
sizeof
(
bufinet4
)))
return
minus_one_set_errno
(
-
errno
);
return
ret_set_errno
(
-
1
,
-
errno
);
if
(
lxc_add_ip_neigh_proxy
(
bufinet4
,
netdev
->
link
)
<
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
err
=
lxc_ipv4_dest_add
(
lo_ifindex
,
&
inet4dev
->
addr
,
32
);
if
(
err
<
0
)
{
ERROR
(
"Failed to add ipv4 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet4
,
loop_device
);
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
}
...
...
@@ -3103,17 +3103,17 @@ static int lxc_setup_l2proxy(struct lxc_netdev *netdev) {
lxc_list_for_each_safe
(
cur
,
&
netdev
->
ipv6
,
next
)
{
inet6dev
=
cur
->
elem
;
if
(
!
inet_ntop
(
AF_INET6
,
&
inet6dev
->
addr
,
bufinet6
,
sizeof
(
bufinet6
)))
return
minus_one_set_errno
(
-
errno
);
return
ret_set_errno
(
-
1
,
-
errno
);
if
(
lxc_add_ip_neigh_proxy
(
bufinet6
,
netdev
->
link
)
<
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
/* IPVLAN requires a route to local-loopback to trigger l2proxy. */
if
(
netdev
->
type
==
LXC_NET_IPVLAN
)
{
err
=
lxc_ipv6_dest_add
(
lo_ifindex
,
&
inet6dev
->
addr
,
128
);
if
(
err
<
0
)
{
ERROR
(
"Failed to add ipv6 dest
\"
%s
\"
for network device
\"
%s
\"
"
,
bufinet6
,
loop_device
);
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
}
...
...
@@ -3127,7 +3127,7 @@ static int lxc_delete_ipv4_l2proxy(struct in_addr *ip, char *link, unsigned int
if
(
!
inet_ntop
(
AF_INET
,
ip
,
bufinet4
,
sizeof
(
bufinet4
)))
{
SYSERROR
(
"Failed to convert IP for l2proxy ipv4 removal on dev
\"
%s
\"
"
,
link
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
...
...
@@ -3145,7 +3145,7 @@ static int lxc_delete_ipv4_l2proxy(struct in_addr *ip, char *link, unsigned int
}
if
(
errCount
>
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
return
0
;
}
...
...
@@ -3156,7 +3156,7 @@ static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int
if
(
!
inet_ntop
(
AF_INET6
,
ip
,
bufinet6
,
sizeof
(
bufinet6
)))
{
SYSERROR
(
"Failed to convert IP for l2proxy ipv6 removal on dev
\"
%s
\"
"
,
link
);
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
}
/* If a local-loopback ifindex supplied remove the static route to the lo device. */
...
...
@@ -3174,7 +3174,7 @@ static int lxc_delete_ipv6_l2proxy(struct in6_addr *ip, char *link, unsigned int
}
if
(
errCount
>
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
return
0
;
}
...
...
@@ -3209,7 +3209,7 @@ static int lxc_delete_l2proxy(struct lxc_netdev *netdev) {
}
if
(
errCount
>
0
)
return
minus_one_set_errno
(
EINVAL
);
return
ret_set_errno
(
-
1
,
EINVAL
);
return
0
;
}
...
...
@@ -3766,12 +3766,12 @@ static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev *netdev)
if
(
err
<
0
)
{
SYSERROR
(
"Failed to setup ipv4 gateway to network device
\"
%s
\"
"
,
current_ifname
);
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
else
{
/* Check the gateway address is valid */
if
(
!
inet_ntop
(
AF_INET
,
netdev
->
ipv4_gateway
,
bufinet4
,
sizeof
(
bufinet4
)))
return
minus_one_set_errno
(
errno
);
return
ret_set_errno
(
-
1
,
errno
);
/* Try adding a default route to the gateway address */
err
=
lxc_ipv4_gateway_add
(
netdev
->
ifindex
,
netdev
->
ipv4_gateway
);
...
...
@@ -3820,12 +3820,12 @@ static int lxc_setup_netdev_in_child_namespaces(struct lxc_netdev *netdev)
if
(
err
<
0
)
{
SYSERROR
(
"Failed to setup ipv6 gateway to network device
\"
%s
\"
"
,
current_ifname
);
return
minus_one_set_errno
(
-
err
);
return
ret_set_errno
(
-
1
,
-
err
);
}
}
else
{
/* Check the gateway address is valid */
if
(
!
inet_ntop
(
AF_INET6
,
netdev
->
ipv6_gateway
,
bufinet6
,
sizeof
(
bufinet6
)))
return
minus_one_set_errno
(
errno
);
return
ret_set_errno
(
-
1
,
errno
);
/* Try adding a default route to the gateway address */
err
=
lxc_ipv6_gateway_add
(
netdev
->
ifindex
,
netdev
->
ipv6_gateway
);
...
...
src/lxc/start.c
View file @
7453799a
...
...
@@ -1119,8 +1119,8 @@ void lxc_abort(const char *name, struct lxc_handler *handler)
static
int
do_start
(
void
*
data
)
{
struct
lxc_handler
*
handler
=
data
;
ATTR_UNUSED
__do_close_prot_errno
int
data_sock0
=
handler
->
data_sock
[
0
],
data_sock1
=
handler
->
data_sock
[
1
];
__lxc_unused
__do_close_prot_errno
int
data_sock0
=
handler
->
data_sock
[
0
],
data_sock1
=
handler
->
data_sock
[
1
];
__do_close_prot_errno
int
status_fd
=
-
EBADF
;
int
ret
;
uid_t
new_uid
;
...
...
@@ -1132,7 +1132,7 @@ static int do_start(void *data)
lxc_sync_fini_parent
(
handler
);
if
(
lxc_abstract_unix_recv_fds
(
handler
->
data_sock
[
1
]
,
&
status_fd
,
1
,
NULL
,
0
)
<
0
)
{
if
(
lxc_abstract_unix_recv_fds
(
data_sock1
,
&
status_fd
,
1
,
NULL
,
0
)
<
0
)
{
ERROR
(
"Failed to receive status file descriptor to child process"
);
goto
out_warn_father
;
}
...
...
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