The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/3128
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Second try's a charm. Sorry. Closed the other PR in favour for this PR. This PR wants to solve an issue with a limited size of the `/dev` tmpfs, which already happened a while ago in https://github.com/lxc/lxc/issues/781. Back then the size of the `/dev` tmpfs was increased but with a fixed size. Under some rare but real circumstances, the `/dev` tmpfs can run out of space. Here from a real container in production: ``` root@irnsrvc16 ~ # df -h /dev Filesystem Type Size Used Avail Use% Mounted on none tmpfs 492K 492K 0 100% /dev ``` The reason in this case is that this specific container is used as central syslog server (using syslog-ng) for a couple dozen other LXC containers. syslog-ng uses its console logging to /dev/tty10, which just uses up the whole space ``` root@irnsrvc16 ~ # ll /dev/tt* crw-rw-rw- 1 root root 5, 0 Aug 21 2018 /dev/tty crw--w---- 1 root tty 136, 0 Aug 21 2018 /dev/tty1 -rw-r----- 1 root adm 503808 Aug 23 09:21 /dev/tty10 crw--w---- 1 root tty 136, 1 Aug 21 2018 /dev/tty2 crw--w---- 1 root tty 136, 2 Aug 21 2018 /dev/tty3 crw--w---- 1 root tty 136, 3 Aug 21 2018 /dev/tty4 ``` This is just one practical example. There may be other uses cases where `/dev` may run out of space. Important: The current default of 500K as tmpfs size will stay unless `lxc.devfs_size` is used to overwrite that value. This way security to protect against a misbehaving software spamming `/dev` is in place, yet the admin has the freedom to increase (or decrease) the default size for his own reasons.
From e92d6840ff2700e6183450b2089886c342bc5024 Mon Sep 17 00:00:00 2001 From: Claudio Kuenzler <c...@claudiokuenzler.com> Date: Wed, 28 Aug 2019 04:01:00 -0700 Subject: [PATCH] Add devfs_size config parameter Signed-off-by: Claudio Kuenzler <c...@claudiokuenzler.com> --- doc/lxc.container.conf.sgml.in | 17 ++++++++++++++++- src/lxc/conf.c | 11 +++++++---- src/lxc/conf.h | 2 ++ src/lxc/confile.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in index a24ee3bae6..9ca451e49d 100644 --- a/doc/lxc.container.conf.sgml.in +++ b/doc/lxc.container.conf.sgml.in @@ -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 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> - (limited to 500k) and fill in a minimal set of initial devices. + (limited to 500K by default, unless limit defined in lxc.devfs_size) and + fill in a minimal set of initial devices. This is generally required when starting a container containing a "systemd" based "init" but may be optional at other times. Additional devices in the containers /dev directory may be created through the @@ -1083,6 +1084,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA </listitem> </varlistentry> </variablelist> + + <varlistentry> + <term> + <option>lxc.devfs_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> </refsect2> <refsect2> diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 97da012d38..85539057ae 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -1135,18 +1135,21 @@ static int lxc_create_ttys(struct lxc_handler *handler) * error, log it but don't fail yet. */ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, - const char *lxcpath) + int devfs_size, const char *lxcpath) { __do_free char *path = NULL; int ret; size_t clen; mode_t cur_mask; + char mount_options[128]; INFO("Preparing \"/dev\""); /* $(rootfs->mount) + "/dev/pts" + '\0' */ clen = (rootfs->path ? strlen(rootfs->mount) : 0) + 9; path = must_realloc(NULL, clen); + sprintf(mount_options, "size=%d,mode=755", (devfs_size != 0) ? devfs_size : 500000); + INFO("Using mount options: %s", mount_options); ret = snprintf(path, clen, "%s/dev", rootfs->path ? rootfs->mount : ""); if (ret < 0 || (size_t)ret >= clen) @@ -1160,8 +1163,8 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, goto reset_umask; } - ret = safe_mount("none", path, "tmpfs", 0, "size=500000,mode=755", - rootfs->path ? rootfs->mount : NULL); + ret = safe_mount("none", path, "tmpfs", 0, mount_options, + rootfs->path ? rootfs->mount : NULL ); if (ret < 0) { SYSERROR("Failed to mount tmpfs on \"%s\"", path); goto reset_umask; @@ -3579,7 +3582,7 @@ int lxc_setup(struct lxc_handler *handler) } if (lxc_conf->autodev > 0) { - ret = mount_autodev(name, &lxc_conf->rootfs, lxcpath); + ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->devfs_size, lxcpath); if (ret < 0) { ERROR("Failed to mount \"/dev\""); return -1; diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 2664a1527c..da55f1dda3 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -299,6 +299,7 @@ struct lxc_conf { struct lxc_seccomp seccomp; int maincmd_fd; unsigned int autodev; /* if 1, mount and fill a /dev at start */ + int devfs_size; /* size of the /dev tmpfs */ int haltsignal; /* signal used to halt container */ int rebootsignal; /* signal used to reboot 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_limits(struct lxc_conf *c, const char *key); extern int lxc_delete_autodev(struct lxc_handler *handler); +extern int lxc_clear_devfs_size(struct lxc_conf *c); extern void lxc_clear_includes(struct lxc_conf *conf); extern int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, const char *name, const char *lxcpath); diff --git a/src/lxc/confile.c b/src/lxc/confile.c index c0cba7c547..4856f50903 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -98,6 +98,7 @@ lxc_config_define(console_logfile); lxc_config_define(console_path); lxc_config_define(console_rotate); lxc_config_define(console_size); +lxc_config_define(devfs_size); lxc_config_define(environment); lxc_config_define(ephemeral); lxc_config_define(execute_cmd); @@ -185,6 +186,7 @@ static struct lxc_config_t config_jump_table[] = { { "lxc.console.path", set_config_console_path, get_config_console_path, clr_config_console_path, }, { "lxc.console.rotate", set_config_console_rotate, get_config_console_rotate, clr_config_console_rotate, }, { "lxc.console.size", set_config_console_size, get_config_console_size, clr_config_console_size, }, + { "lxc.devfs_size", set_config_devfs_size, get_config_devfs_size, clr_config_devfs_size, }, { "lxc.environment", set_config_environment, get_config_environment, clr_config_environment, }, { "lxc.ephemeral", set_config_ephemeral, get_config_ephemeral, clr_config_ephemeral, }, { "lxc.execute.cmd", set_config_execute_cmd, get_config_execute_cmd, clr_config_execute_cmd, }, @@ -1552,6 +1554,20 @@ static int set_config_autodev(const char *key, const char *value, return 0; } +static int set_config_devfs_size(const char *key, const char *value, + struct lxc_conf *lxc_conf, void *data) +{ + if (lxc_config_value_empty(value)) { + lxc_conf->devfs_size = 500000; + return 0; + } + + if (lxc_safe_int(value, &lxc_conf->devfs_size) < 0) + lxc_conf->devfs_size = 500000; + + return 0; +} + static int set_config_signal_halt(const char *key, const char *value, 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); } +static int get_config_devfs_size(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) +{ + return lxc_get_conf_int(c, retv, inlen, c->devfs_size); +} + static int get_config_signal_halt(const char *key, char *retv, int inlen, 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; } +static inline int clr_config_devfs_size(const char *key, struct lxc_conf *c, + void *data) +{ + c->devfs_size = 500000; + return 0; +} + static inline int clr_config_signal_halt(const char *key, struct lxc_conf *c, void *data) { @@ -5956,6 +5985,7 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv, strprint(retv, inlen, "name\n"); } else if (!strcmp(key, "lxc.hook")) { strprint(retv, inlen, "autodev\n"); + strprint(retv, inlen, "devfs_size\n"); strprint(retv, inlen, "clone\n"); strprint(retv, inlen, "destroy\n"); strprint(retv, inlen, "mount\n");
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel