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
ed20740b
Unverified
Commit
ed20740b
authored
Dec 11, 2017
by
Christian Brauner
Committed by
GitHub
Dec 11, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2009 from lifeng68/add_sysctl
confile: add lxc.sysctl config
parents
9f3b360c
7edd0540
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
304 additions
and
10 deletions
+304
-10
lxc.container.conf.sgml.in
doc/lxc.container.conf.sgml.in
+28
-0
conf.c
src/lxc/conf.c
+69
-0
conf.h
src/lxc/conf.h
+15
-0
confile.c
src/lxc/confile.c
+116
-7
get_item.c
src/tests/get_item.c
+69
-3
parse_config_file.c
src/tests/parse_config_file.c
+7
-0
No files found.
doc/lxc.container.conf.sgml.in
View file @
ed20740b
...
...
@@ -1390,6 +1390,34 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</refsect2>
<refsect2>
<title>Sysctl</title>
<para>
Configure kernel parameters for the container.
</para>
<variablelist>
<varlistentry>
<term>
<option>lxc.sysctl.[kernel parameters name]</option>
</term>
<listitem>
<para>
Specify the kernel parameters to be set. The parameters available
are those listed under /proc/sys/.
Note that not all sysctls are namespaced.Changing Non-namespaced
sysctls will cause the system-wide setting to be modified.
<citerefentry>
<refentrytitle><command>sysctl</command></refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>.
If used with no value, lxc will clear the parameters specified up
to this point.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>Apparmor profile</title>
<para>
If lxc was compiled and installed with apparmor support, and the host
...
...
src/lxc/conf.c
View file @
ed20740b
...
...
@@ -2366,6 +2366,38 @@ int setup_resource_limits(struct lxc_list *limits, pid_t pid) {
return
0
;
}
int
setup_sysctl_parameters
(
struct
lxc_list
*
sysctls
)
{
struct
lxc_list
*
it
;
struct
lxc_sysctl
*
elem
;
char
*
tmp
=
NULL
;
char
filename
[
MAXPATHLEN
]
=
{
0
};
int
ret
=
0
;
lxc_list_for_each
(
it
,
sysctls
)
{
elem
=
it
->
elem
;
tmp
=
lxc_string_replace
(
"."
,
"/"
,
elem
->
key
);
if
(
!
tmp
)
{
ERROR
(
"Failed to replace key %s"
,
elem
->
key
);
return
-
1
;
}
ret
=
snprintf
(
filename
,
sizeof
(
filename
),
"/proc/sys/%s"
,
tmp
);
free
(
tmp
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
sizeof
(
filename
))
{
ERROR
(
"Error setting up sysctl parameters path"
);
return
-
1
;
}
ret
=
lxc_write_to_file
(
filename
,
elem
->
value
,
strlen
(
elem
->
value
),
false
);
if
(
ret
<
0
)
{
ERROR
(
"Failed to setup sysctl parameters %s to %s"
,
elem
->
key
,
elem
->
value
);
return
-
1
;
}
}
return
0
;
}
static
char
*
default_rootfs_mount
=
LXCROOTFSMOUNT
;
struct
lxc_conf
*
lxc_conf_init
(
void
)
...
...
@@ -2416,6 +2448,7 @@ struct lxc_conf *lxc_conf_init(void)
lxc_list_init
(
&
new
->
aliens
);
lxc_list_init
(
&
new
->
environment
);
lxc_list_init
(
&
new
->
limits
);
lxc_list_init
(
&
new
->
sysctls
);
for
(
i
=
0
;
i
<
NUM_LXC_HOOKS
;
i
++
)
lxc_list_init
(
&
new
->
hooks
[
i
]);
lxc_list_init
(
&
new
->
groups
);
...
...
@@ -3164,6 +3197,15 @@ int lxc_setup(struct lxc_handler *handler)
return
-
1
;
}
/* set sysctl value to a path under /proc/sys as determined from the key.
* For e.g. net.ipv4.ip_forward translated to /proc/sys/net/ipv4/ip_forward.
*/
if
(
!
lxc_list_empty
(
&
lxc_conf
->
sysctls
))
{
ret
=
setup_sysctl_parameters
(
&
lxc_conf
->
sysctls
);
if
(
ret
<
0
)
return
-
1
;
}
if
(
!
lxc_list_empty
(
&
lxc_conf
->
keepcaps
))
{
if
(
!
lxc_list_empty
(
&
lxc_conf
->
caps
))
{
ERROR
(
"Container requests lxc.cap.drop and lxc.cap.keep: either use lxc.cap.drop or lxc.cap.keep, not both."
);
...
...
@@ -3315,6 +3357,32 @@ int lxc_clear_limits(struct lxc_conf *c, const char *key)
return
0
;
}
int
lxc_clear_sysctls
(
struct
lxc_conf
*
c
,
const
char
*
key
)
{
struct
lxc_list
*
it
,
*
next
;
bool
all
=
false
;
const
char
*
k
=
NULL
;
if
(
strcmp
(
key
,
"lxc.sysctl"
)
==
0
)
all
=
true
;
else
if
(
strncmp
(
key
,
"lxc.sysctl."
,
sizeof
(
"lxc.sysctl."
)
-
1
)
==
0
)
k
=
key
+
sizeof
(
"lxc.sysctl."
)
-
1
;
else
return
-
1
;
lxc_list_for_each_safe
(
it
,
&
c
->
sysctls
,
next
)
{
struct
lxc_sysctl
*
elem
=
it
->
elem
;
if
(
!
all
&&
strcmp
(
elem
->
key
,
k
)
!=
0
)
continue
;
lxc_list_del
(
it
);
free
(
elem
->
key
);
free
(
elem
->
value
);
free
(
elem
);
free
(
it
);
}
return
0
;
}
int
lxc_clear_groups
(
struct
lxc_conf
*
c
)
{
struct
lxc_list
*
it
,
*
next
;
...
...
@@ -3454,6 +3522,7 @@ void lxc_conf_free(struct lxc_conf *conf)
lxc_clear_aliens
(
conf
);
lxc_clear_environment
(
conf
);
lxc_clear_limits
(
conf
,
"lxc.prlimit"
);
lxc_clear_sysctls
(
conf
,
"lxc.sysctl"
);
free
(
conf
->
cgroup_meta
.
dir
);
free
(
conf
->
cgroup_meta
.
controllers
);
free
(
conf
);
...
...
src/lxc/conf.h
View file @
ed20740b
...
...
@@ -96,6 +96,16 @@ enum idtype {
};
/*
* Defines a structure to configure kernel parameters at runtime.
* @key : the kernel parameters will be configured without the "lxc.sysctl" prefix
* @value : the value to set
*/
struct
lxc_sysctl
{
char
*
key
;
char
*
value
;
};
/*
* id_map is an id map entry. Form in confile is:
* lxc.idmap = u 0 9800 100
* lxc.idmap = u 1000 9900 100
...
...
@@ -370,6 +380,9 @@ struct lxc_conf {
/* A list of clients registered to be informed about a container state. */
struct
lxc_list
state_clients
;
/* sysctls */
struct
lxc_list
sysctls
;
};
int
write_id_mapping
(
enum
idtype
idtype
,
pid_t
pid
,
const
char
*
buf
,
...
...
@@ -428,5 +441,7 @@ extern unsigned long add_required_remount_flags(const char *s, const char *d,
extern
int
run_script
(
const
char
*
name
,
const
char
*
section
,
const
char
*
script
,
...);
extern
int
in_caplist
(
int
cap
,
struct
lxc_list
*
caps
);
extern
int
setup_sysctl_parameters
(
struct
lxc_list
*
sysctls
);
extern
int
lxc_clear_sysctls
(
struct
lxc_conf
*
c
,
const
char
*
key
);
#endif
/* __LXC_CONF_H */
src/lxc/confile.c
View file @
ed20740b
...
...
@@ -141,6 +141,7 @@ lxc_config_define(start);
lxc_config_define
(
tty_max
);
lxc_config_define
(
tty_dir
);
lxc_config_define
(
uts_name
);
lxc_config_define
(
sysctl
);
static
struct
lxc_config_t
config
[]
=
{
/* REMOVE in LXC 3.0 */
...
...
@@ -241,6 +242,7 @@ static struct lxc_config_t config[] = {
{
"lxc.tty.dir"
,
false
,
set_config_tty_dir
,
get_config_tty_dir
,
clr_config_tty_dir
,
},
{
"lxc.tty.max"
,
false
,
set_config_tty_max
,
get_config_tty_max
,
clr_config_tty_max
,
},
{
"lxc.uts.name"
,
false
,
set_config_uts_name
,
get_config_uts_name
,
clr_config_uts_name
,
},
{
"lxc.sysctl"
,
false
,
set_config_sysctl
,
get_config_sysctl
,
clr_config_sysctl
,
},
/* [START]: REMOVE IN LXC 3.0 */
{
"lxc.pts"
,
true
,
set_config_pty_max
,
get_config_pty_max
,
clr_config_pty_max
,
},
...
...
@@ -1456,8 +1458,7 @@ static int set_config_prlimit(const char *key, const char *value,
}
/* find existing list element */
lxc_list_for_each
(
iter
,
&
lxc_conf
->
limits
)
{
lxc_list_for_each
(
iter
,
&
lxc_conf
->
limits
)
{
limelem
=
iter
->
elem
;
if
(
!
strcmp
(
key
,
limelem
->
resource
))
{
limelem
->
limit
=
limit
;
...
...
@@ -1468,25 +1469,25 @@ static int set_config_prlimit(const char *key, const char *value,
/* allocate list element */
limlist
=
malloc
(
sizeof
(
*
limlist
));
if
(
!
limlist
)
goto
o
ut
;
goto
o
n_error
;
limelem
=
malloc
(
sizeof
(
*
limelem
));
if
(
!
limelem
)
goto
o
ut
;
goto
o
n_error
;
memset
(
limelem
,
0
,
sizeof
(
*
limelem
));
limelem
->
resource
=
strdup
(
key
);
if
(
!
limelem
->
resource
)
goto
o
ut
;
goto
o
n_error
;
limelem
->
limit
=
limit
;
l
imlist
->
elem
=
limelem
;
l
xc_list_add_elem
(
limlist
,
limelem
);
;
lxc_list_add_tail
(
&
lxc_conf
->
limits
,
limlist
);
return
0
;
o
ut
:
o
n_error
:
free
(
limlist
);
if
(
limelem
)
{
free
(
limelem
->
resource
);
...
...
@@ -1495,6 +1496,71 @@ out:
return
-
1
;
}
static
int
set_config_sysctl
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
struct
lxc_list
*
iter
;
struct
lxc_list
*
sysctl_list
=
NULL
;
struct
lxc_sysctl
*
sysctl_elem
=
NULL
;
char
*
replace_value
=
NULL
;
if
(
lxc_config_value_empty
(
value
))
return
lxc_clear_sysctls
(
lxc_conf
,
key
);
if
(
strncmp
(
key
,
"lxc.sysctl."
,
sizeof
(
"lxc.sysctl."
)
-
1
)
!=
0
)
return
-
1
;
key
+=
sizeof
(
"lxc.sysctl."
)
-
1
;
/* find existing list element */
lxc_list_for_each
(
iter
,
&
lxc_conf
->
sysctls
)
{
sysctl_elem
=
iter
->
elem
;
if
(
strcmp
(
key
,
sysctl_elem
->
key
)
==
0
)
{
replace_value
=
strdup
(
value
);
if
(
!
replace_value
)
return
-
1
;
free
(
sysctl_elem
->
value
);
sysctl_elem
->
value
=
replace_value
;
return
0
;
}
}
/* allocate list element */
sysctl_list
=
malloc
(
sizeof
(
*
sysctl_list
));
if
(
!
sysctl_list
)
goto
on_error
;
sysctl_elem
=
malloc
(
sizeof
(
*
sysctl_elem
));
if
(
!
sysctl_elem
)
goto
on_error
;
memset
(
sysctl_elem
,
0
,
sizeof
(
*
sysctl_elem
));
sysctl_elem
->
key
=
strdup
(
key
);
if
(
!
sysctl_elem
->
key
)
goto
on_error
;
sysctl_elem
->
value
=
strdup
(
value
);
if
(
!
sysctl_elem
->
value
)
goto
on_error
;
lxc_list_add_elem
(
sysctl_list
,
sysctl_elem
);
lxc_list_add_tail
(
&
lxc_conf
->
sysctls
,
sysctl_list
);
return
0
;
on_error:
free
(
sysctl_list
);
if
(
sysctl_elem
)
{
free
(
sysctl_elem
->
key
);
free
(
sysctl_elem
->
value
);
free
(
sysctl_elem
);
}
return
-
1
;
}
static
int
set_config_idmaps
(
const
char
*
key
,
const
char
*
value
,
struct
lxc_conf
*
lxc_conf
,
void
*
data
)
{
...
...
@@ -3310,6 +3376,43 @@ static int get_config_prlimit(const char *key, char *retv, int inlen,
return
fulllen
;
}
/* If you ask for a specific value, i.e. lxc.sysctl.net.ipv4.ip_forward, then just the value
* will be printed. If you ask for 'lxc.sysctl', then all sysctl entries will be
* printed, in 'lxc.sysctl.key = value' format.
*/
static
int
get_config_sysctl
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
int
len
;
struct
lxc_list
*
it
;
int
fulllen
=
0
;
bool
get_all
=
false
;
if
(
!
retv
)
inlen
=
0
;
else
memset
(
retv
,
0
,
inlen
);
if
(
strcmp
(
key
,
"lxc.sysctl"
)
==
0
)
get_all
=
true
;
else
if
(
strncmp
(
key
,
"lxc.sysctl."
,
sizeof
(
"lxc.sysctl."
)
-
1
)
==
0
)
key
+=
sizeof
(
"lxc.sysctl."
)
-
1
;
else
return
-
1
;
lxc_list_for_each
(
it
,
&
c
->
sysctls
)
{
struct
lxc_sysctl
*
elem
=
it
->
elem
;
if
(
get_all
)
{
strprint
(
retv
,
inlen
,
"lxc.sysctl.%s = %s
\n
"
,
elem
->
key
,
elem
->
value
);
}
else
if
(
strcmp
(
elem
->
key
,
key
)
==
0
)
{
strprint
(
retv
,
inlen
,
"%s"
,
elem
->
value
);
}
}
return
fulllen
;
}
static
int
get_config_noop
(
const
char
*
key
,
char
*
retv
,
int
inlen
,
struct
lxc_conf
*
c
,
void
*
data
)
{
...
...
@@ -3687,6 +3790,12 @@ static inline int clr_config_prlimit(const char *key, struct lxc_conf *c,
return
lxc_clear_limits
(
c
,
key
);
}
static
inline
int
clr_config_sysctl
(
const
char
*
key
,
struct
lxc_conf
*
c
,
void
*
data
)
{
return
lxc_clear_sysctls
(
c
,
key
);
}
static
inline
int
clr_config_includefiles
(
const
char
*
key
,
struct
lxc_conf
*
c
,
void
*
data
)
{
...
...
src/tests/get_item.c
View file @
ed20740b
...
...
@@ -34,8 +34,9 @@
int
main
(
int
argc
,
char
*
argv
[])
{
int
ret
=
EXIT_FAILURE
;
int
ret
;
struct
lxc_container
*
c
;
int
fret
=
EXIT_FAILURE
;
char
v1
[
2
],
v2
[
256
],
v3
[
2048
];
if
((
c
=
lxc_container_new
(
"testxyz"
,
NULL
))
==
NULL
)
{
...
...
@@ -243,6 +244,71 @@ int main(int argc, char *argv[])
}
printf
(
"lxc.limit returned %d %s
\n
"
,
ret
,
v3
);
#define SYSCTL_SOMAXCONN "lxc.sysctl.net.core.somaxconn = 256\n"
#define ALL_SYSCTLS "lxc.sysctl.net.ipv4.ip_forward = 1\n" SYSCTL_SOMAXCONN
ret
=
c
->
get_config_item
(
c
,
"lxc.sysctl"
,
v3
,
2047
);
if
(
ret
!=
0
)
{
fprintf
(
stderr
,
"%d: get_config_item(sysctl) returned %d
\n
"
,
__LINE__
,
ret
);
goto
out
;
}
if
(
!
c
->
set_config_item
(
c
,
"lxc.sysctl.net.ipv4.ip_forward"
,
"1"
))
{
fprintf
(
stderr
,
"%d: failed to set lxc.sysctl.net.ipv4.ip_forward
\n
"
,
__LINE__
);
goto
out
;
}
ret
=
c
->
get_config_item
(
c
,
"lxc.sysctl.net.ipv4.ip_forward"
,
v2
,
255
);
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"%d: get_config_item(lxc.sysctl.net.ipv4.ip_forward) returned %d
\n
"
,
__LINE__
,
ret
);
goto
out
;
}
if
(
strcmp
(
v2
,
"1"
))
{
fprintf
(
stderr
,
"%d: lxc.sysctl.net.ipv4.ip_forward returned wrong value: %d %s not 1
\n
"
,
__LINE__
,
ret
,
v2
);
goto
out
;
}
printf
(
"lxc.sysctl.net.ipv4.ip_forward returned %d %s
\n
"
,
ret
,
v2
);
if
(
!
c
->
set_config_item
(
c
,
"lxc.sysctl.net.core.somaxconn"
,
"256"
))
{
fprintf
(
stderr
,
"%d: failed to set lxc.sysctl.net.core.somaxconn
\n
"
,
__LINE__
);
goto
out
;
}
ret
=
c
->
get_config_item
(
c
,
"lxc.sysctl.net.core.somaxconn"
,
v2
,
255
);
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"%d: get_config_item(lxc.sysctl.net.core.somaxconn) returned %d
\n
"
,
__LINE__
,
ret
);
goto
out
;
}
if
(
strcmp
(
v2
,
"256"
))
{
fprintf
(
stderr
,
"%d: lxc.sysctl.net.core.somaxconn returned wrong value: %d %s not 256
\n
"
,
__LINE__
,
ret
,
v2
);
goto
out
;
}
printf
(
"lxc.sysctl.net.core.somaxconn returned %d %s
\n
"
,
ret
,
v2
);
ret
=
c
->
get_config_item
(
c
,
"lxc.sysctl"
,
v3
,
2047
);
if
(
ret
!=
sizeof
(
ALL_SYSCTLS
)
-
1
)
{
fprintf
(
stderr
,
"%d: get_config_item(sysctl) returned %d
\n
"
,
__LINE__
,
ret
);
goto
out
;
}
if
(
strcmp
(
v3
,
ALL_SYSCTLS
))
{
fprintf
(
stderr
,
"%d: lxc.sysctl returned wrong value: %d %s not %d %s
\n
"
,
__LINE__
,
ret
,
v3
,
(
int
)
sizeof
(
ALL_SYSCTLS
)
-
1
,
ALL_SYSCTLS
);
goto
out
;
}
printf
(
"lxc.sysctl returned %d %s
\n
"
,
ret
,
v3
);
if
(
!
c
->
clear_config_item
(
c
,
"lxc.sysctl.net.ipv4.ip_forward"
))
{
fprintf
(
stderr
,
"%d: failed clearing lxc.sysctl.net.ipv4.ip_forward
\n
"
,
__LINE__
);
goto
out
;
}
ret
=
c
->
get_config_item
(
c
,
"lxc.sysctl"
,
v3
,
2047
);
if
(
ret
!=
sizeof
(
SYSCTL_SOMAXCONN
)
-
1
)
{
fprintf
(
stderr
,
"%d: get_config_item(sysctl) returned %d
\n
"
,
__LINE__
,
ret
);
goto
out
;
}
if
(
strcmp
(
v3
,
SYSCTL_SOMAXCONN
))
{
fprintf
(
stderr
,
"%d: lxc.sysctl returned wrong value: %d %s not %d %s
\n
"
,
__LINE__
,
ret
,
v3
,
(
int
)
sizeof
(
SYSCTL_SOMAXCONN
)
-
1
,
SYSCTL_SOMAXCONN
);
goto
out
;
}
printf
(
"lxc.sysctl returned %d %s
\n
"
,
ret
,
v3
);
if
(
!
c
->
set_config_item
(
c
,
"lxc.aa_profile"
,
"unconfined"
))
{
fprintf
(
stderr
,
"%d: failed to set aa_profile
\n
"
,
__LINE__
);
goto
out
;
...
...
@@ -424,9 +490,9 @@ int main(int argc, char *argv[])
}
printf
(
"All get_item tests passed
\n
"
);
ret
=
EXIT_SUCCESS
;
f
ret
=
EXIT_SUCCESS
;
out:
c
->
destroy
(
c
);
lxc_container_put
(
c
);
exit
(
ret
);
exit
(
f
ret
);
}
src/tests/parse_config_file.c
View file @
ed20740b
...
...
@@ -922,6 +922,13 @@ int main(int argc, char *argv[])
goto
non_test_error
;
}
/* lxc.sysctl */
if
(
set_get_compare_clear_save_load
(
c
,
"lxc.sysctl.net.core.somaxconn"
,
"256"
,
tmpf
,
true
)
<
0
)
{
lxc_error
(
"%s
\n
"
,
"lxc.sysctl.net.core.somaxconn"
);
goto
non_test_error
;
}
/* REMOVE IN LXC 3.0
legacy lxc.limit.* key
*/
...
...
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