<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 defined in lxc.autodev.tmpfs.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
</para>
</listitem>
</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>
</refsect2>
* error, log it but don't fail yet.
*/
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;
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", (autodevtmpfssize != 0) ? autodevtmpfssize : 500000);
+ DEBUG("Using mount options: %s", mount_options);
ret = snprintf(path, clen, "%s/dev", rootfs->path ? rootfs->mount : "");
if (ret < 0 || (size_t)ret >= clen)
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;
}
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) {
ERROR("Failed to mount \"/dev\"");
return -1;
struct lxc_seccomp seccomp;
int maincmd_fd;
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 rebootsignal; /* signal used to reboot container */
int stopsignal; /* signal used to hard stop container */
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_autodev_tmpfs_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);
void *);
lxc_config_define(autodev);
+lxc_config_define(autodev_tmpfs_size);
lxc_config_define(apparmor_allow_incomplete);
lxc_config_define(apparmor_allow_nesting);
lxc_config_define(apparmor_profile);
{ "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.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.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, },
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,
struct lxc_conf *lxc_conf, void *data)
{
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,
struct lxc_conf *c, void *data)
{
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,
void *data)
{
strprint(retv, inlen, "name\n");
} else if (!strcmp(key, "lxc.hook")) {
strprint(retv, inlen, "autodev\n");
+ strprint(retv, inlen, "autodevtmpfssize\n");
strprint(retv, inlen, "clone\n");
strprint(retv, inlen, "destroy\n");
strprint(retv, inlen, "mount\n");
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) <
0) {
lxc_error("%s\n", "lxc.autodev");