Add autodev.tmpfs.size config parameter

Signed-off-by: Claudio Kuenzler <ck@claudiokuenzler.com>
This commit is contained in:
Claudio Kuenzler 2019-08-28 04:01:00 -07:00 committed by Serge Hallyn
parent 72f22067d9
commit 63012bdd00
5 changed files with 59 additions and 5 deletions

View File

@ -1064,7 +1064,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<filename>/dev</filename> to be set up as needed in the container <filename>/dev</filename> to be set up as needed in the container
rootfs. If lxc.autodev is set to 1, then after mounting the container's rootfs. If lxc.autodev is set to 1, then after mounting the container's
rootfs LXC will mount a fresh tmpfs under <filename>/dev</filename> rootfs LXC will mount a fresh tmpfs under <filename>/dev</filename>
(limited to 500k) and fill in a minimal set of initial devices. (limited to 500K by default, unless defined in lxc.autodev.tmpfs.size)
and fill in a minimal set of initial devices.
This is generally required when starting a container containing This is generally required when starting a container containing
a "systemd" based "init" but may be optional at other times. Additional a "systemd" based "init" but may be optional at other times. Additional
devices in the containers /dev directory may be created through the devices in the containers /dev directory may be created through the
@ -1082,6 +1083,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>lxc.autodev.tmpfs.size</option>
</term>
<listitem>
<para>
Set this to define the size of the /dev tmpfs.
The default value is 500000 (500K). If the parameter is used
but without value, the default value is used.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect2> </refsect2>

View File

@ -1135,18 +1135,21 @@ on_error:
* error, log it but don't fail yet. * error, log it but don't fail yet.
*/ */
static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs,
const char *lxcpath) int autodevtmpfssize, const char *lxcpath)
{ {
__do_free char *path = NULL; __do_free char *path = NULL;
int ret; int ret;
size_t clen; size_t clen;
mode_t cur_mask; mode_t cur_mask;
char mount_options[128];
INFO("Preparing \"/dev\""); INFO("Preparing \"/dev\"");
/* $(rootfs->mount) + "/dev/pts" + '\0' */ /* $(rootfs->mount) + "/dev/pts" + '\0' */
clen = (rootfs->path ? strlen(rootfs->mount) : 0) + 9; clen = (rootfs->path ? strlen(rootfs->mount) : 0) + 9;
path = must_realloc(NULL, clen); path = must_realloc(NULL, clen);
sprintf(mount_options, "size=%d,mode=755", (autodevtmpfssize != 0) ? autodevtmpfssize : 500000);
DEBUG("Using mount options: %s", mount_options);
ret = snprintf(path, clen, "%s/dev", rootfs->path ? rootfs->mount : ""); ret = snprintf(path, clen, "%s/dev", rootfs->path ? rootfs->mount : "");
if (ret < 0 || (size_t)ret >= clen) if (ret < 0 || (size_t)ret >= clen)
@ -1160,7 +1163,7 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs,
goto reset_umask; goto reset_umask;
} }
ret = safe_mount("none", path, "tmpfs", 0, "size=500000,mode=755", ret = safe_mount("none", path, "tmpfs", 0, mount_options,
rootfs->path ? rootfs->mount : NULL ); rootfs->path ? rootfs->mount : NULL );
if (ret < 0) { if (ret < 0) {
SYSERROR("Failed to mount tmpfs on \"%s\"", path); SYSERROR("Failed to mount tmpfs on \"%s\"", path);
@ -3579,7 +3582,7 @@ int lxc_setup(struct lxc_handler *handler)
} }
if (lxc_conf->autodev > 0) { if (lxc_conf->autodev > 0) {
ret = mount_autodev(name, &lxc_conf->rootfs, lxcpath); ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->autodevtmpfssize, lxcpath);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to mount \"/dev\""); ERROR("Failed to mount \"/dev\"");
return -1; return -1;

View File

@ -299,6 +299,7 @@ struct lxc_conf {
struct lxc_seccomp seccomp; struct lxc_seccomp seccomp;
int maincmd_fd; int maincmd_fd;
unsigned int autodev; /* if 1, mount and fill a /dev at start */ unsigned int autodev; /* if 1, mount and fill a /dev at start */
int autodevtmpfssize; /* size of the /dev tmpfs */
int haltsignal; /* signal used to halt container */ int haltsignal; /* signal used to halt container */
int rebootsignal; /* signal used to reboot container */ int rebootsignal; /* signal used to reboot container */
int stopsignal; /* signal used to hard stop container */ int stopsignal; /* signal used to hard stop container */
@ -423,6 +424,7 @@ extern int lxc_clear_groups(struct lxc_conf *c);
extern int lxc_clear_environment(struct lxc_conf *c); extern int lxc_clear_environment(struct lxc_conf *c);
extern int lxc_clear_limits(struct lxc_conf *c, const char *key); extern int lxc_clear_limits(struct lxc_conf *c, const char *key);
extern int lxc_delete_autodev(struct lxc_handler *handler); extern int lxc_delete_autodev(struct lxc_handler *handler);
extern int lxc_clear_autodev_tmpfs_size(struct lxc_conf *c);
extern void lxc_clear_includes(struct lxc_conf *conf); extern void lxc_clear_includes(struct lxc_conf *conf);
extern int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, extern int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf,
const char *name, const char *lxcpath); const char *name, const char *lxcpath);

View File

@ -83,6 +83,7 @@ lxc_log_define(confile, lxc);
void *); void *);
lxc_config_define(autodev); lxc_config_define(autodev);
lxc_config_define(autodev_tmpfs_size);
lxc_config_define(apparmor_allow_incomplete); lxc_config_define(apparmor_allow_incomplete);
lxc_config_define(apparmor_allow_nesting); lxc_config_define(apparmor_allow_nesting);
lxc_config_define(apparmor_profile); lxc_config_define(apparmor_profile);
@ -173,6 +174,7 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.apparmor.allow_incomplete", set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, }, { "lxc.apparmor.allow_incomplete", set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, },
{ "lxc.apparmor.allow_nesting", set_config_apparmor_allow_nesting, get_config_apparmor_allow_nesting, clr_config_apparmor_allow_nesting, }, { "lxc.apparmor.allow_nesting", set_config_apparmor_allow_nesting, get_config_apparmor_allow_nesting, clr_config_apparmor_allow_nesting, },
{ "lxc.apparmor.raw", set_config_apparmor_raw, get_config_apparmor_raw, clr_config_apparmor_raw, }, { "lxc.apparmor.raw", set_config_apparmor_raw, get_config_apparmor_raw, clr_config_apparmor_raw, },
{ "lxc.autodev.tmpfs.size", set_config_autodev_tmpfs_size, get_config_autodev_tmpfs_size, clr_config_autodev_tmpfs_size, },
{ "lxc.autodev", set_config_autodev, get_config_autodev, clr_config_autodev, }, { "lxc.autodev", set_config_autodev, get_config_autodev, clr_config_autodev, },
{ "lxc.cap.drop", set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, }, { "lxc.cap.drop", set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, },
{ "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, }, { "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, },
@ -1552,6 +1554,20 @@ static int set_config_autodev(const char *key, const char *value,
return 0; return 0;
} }
static int set_config_autodev_tmpfs_size(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
if (lxc_config_value_empty(value)) {
lxc_conf->autodevtmpfssize = 500000;
return 0;
}
if (lxc_safe_int(value, &lxc_conf->autodevtmpfssize) < 0)
lxc_conf->autodevtmpfssize = 500000;
return 0;
}
static int set_config_signal_halt(const char *key, const char *value, static int set_config_signal_halt(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
@ -4020,6 +4036,12 @@ static int get_config_autodev(const char *key, char *retv, int inlen,
return lxc_get_conf_int(c, retv, inlen, c->autodev); return lxc_get_conf_int(c, retv, inlen, c->autodev);
} }
static int get_config_autodev_tmpfs_size(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return lxc_get_conf_int(c, retv, inlen, c->autodevtmpfssize);
}
static int get_config_signal_halt(const char *key, char *retv, int inlen, static int get_config_signal_halt(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
@ -4642,6 +4664,13 @@ static inline int clr_config_autodev(const char *key, struct lxc_conf *c,
return 0; return 0;
} }
static inline int clr_config_autodev_tmpfs_size(const char *key, struct lxc_conf *c,
void *data)
{
c->autodevtmpfssize = 500000;
return 0;
}
static inline int clr_config_signal_halt(const char *key, struct lxc_conf *c, static inline int clr_config_signal_halt(const char *key, struct lxc_conf *c,
void *data) void *data)
{ {
@ -5956,6 +5985,7 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
strprint(retv, inlen, "name\n"); strprint(retv, inlen, "name\n");
} else if (!strcmp(key, "lxc.hook")) { } else if (!strcmp(key, "lxc.hook")) {
strprint(retv, inlen, "autodev\n"); strprint(retv, inlen, "autodev\n");
strprint(retv, inlen, "autodevtmpfssize\n");
strprint(retv, inlen, "clone\n"); strprint(retv, inlen, "clone\n");
strprint(retv, inlen, "destroy\n"); strprint(retv, inlen, "destroy\n");
strprint(retv, inlen, "mount\n"); strprint(retv, inlen, "mount\n");

View File

@ -560,6 +560,11 @@ int main(int argc, char *argv[])
goto non_test_error; goto non_test_error;
} }
if (set_get_compare_clear_save_load(c, "lxc.autodev.tmpfs.size", "1", tmpf, true) < 0) {
lxc_error("%s\n", "lxc.autodev.tmpfs.size");
goto non_test_error;
}
if (set_get_compare_clear_save_load(c, "lxc.autodev", "1", tmpf, true) < if (set_get_compare_clear_save_load(c, "lxc.autodev", "1", tmpf, true) <
0) { 0) {
lxc_error("%s\n", "lxc.autodev"); lxc_error("%s\n", "lxc.autodev");