mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 10:51:24 +00:00
Add lxc.autodev
Add a container config option to mount and populate /dev in a container. We might want to add options to specify a max size for /dev other than the default 100k, and to specify other devices to create. And maybe someone can think of a better name than autodev. Changelog: Don't error out if we couldn't mknod a /dev/ttyN. Changelog: Describe the option in lxc.conf manpage. Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
parent
69c478daf1
commit
c6883f383e
@ -501,6 +501,31 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
|
<refsect2>
|
||||||
|
<title>/dev directory</title>
|
||||||
|
<para>
|
||||||
|
By default, lxc does nothing with the container's
|
||||||
|
<filename>/dev</filename>. This allows the container's
|
||||||
|
<filename>/dev</filename> to be set up as needed in the container
|
||||||
|
rootfs. If lxc.autodev is to 1, then after mounting the container's
|
||||||
|
rootfs LXC will mount a fresh tmpfs under <filename>/dev</filename>
|
||||||
|
(limited to 100k) and fill in a minimal set of initial devices.
|
||||||
|
</para>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>lxc.autodev</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Set this to 1 to have LXC mount and populate a minimal
|
||||||
|
<filename>/dev</filename> when starting the container.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect2>
|
||||||
|
|
||||||
<refsect2>
|
<refsect2>
|
||||||
<title>Mount points</title>
|
<title>Mount points</title>
|
||||||
<para>
|
<para>
|
||||||
|
@ -653,6 +653,15 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* If we populated /dev, then we need to create /dev/ttyN */
|
||||||
|
if (access(path, F_OK)) {
|
||||||
|
ret = creat(path, 0660);
|
||||||
|
if (ret==-1) {
|
||||||
|
SYSERROR("error creating %s\n", path);
|
||||||
|
/* this isn't fatal, continue */
|
||||||
|
} else
|
||||||
|
close(ret);
|
||||||
|
}
|
||||||
if (mount(pty_info->name, path, "none", MS_BIND, 0)) {
|
if (mount(pty_info->name, path, "none", MS_BIND, 0)) {
|
||||||
WARN("failed to mount '%s'->'%s'",
|
WARN("failed to mount '%s'->'%s'",
|
||||||
pty_info->name, path);
|
pty_info->name, path);
|
||||||
@ -860,6 +869,67 @@ static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct lxc_devs {
|
||||||
|
char *name;
|
||||||
|
mode_t mode;
|
||||||
|
int maj;
|
||||||
|
int min;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lxc_devs lxc_devs[] = {
|
||||||
|
{ "null", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 3 },
|
||||||
|
{ "zero", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 5 },
|
||||||
|
{ "full", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 7 },
|
||||||
|
{ "urandom", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 9 },
|
||||||
|
{ "random", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 1, 8 },
|
||||||
|
{ "tty", S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, 5, 0 },
|
||||||
|
{ "console", S_IFCHR | S_IRUSR | S_IWUSR, 5, 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do we want to add options for max size of /dev and a file to
|
||||||
|
* specify which devices to create?
|
||||||
|
*/
|
||||||
|
static int setup_autodev(char *root)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct lxc_devs *d;
|
||||||
|
char path[MAXPATHLEN];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
INFO("Creating and populating /dev under %s\n", root);
|
||||||
|
ret = snprintf(path, MAXPATHLEN, "%s/dev", root);
|
||||||
|
if (ret < 0 || ret > MAXPATHLEN)
|
||||||
|
return -1;
|
||||||
|
ret = mount("none", path, "tmpfs", 0, "size=100000");
|
||||||
|
if (ret) {
|
||||||
|
SYSERROR("Failed to mount /dev at %s\n", root);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < sizeof(lxc_devs) / sizeof(lxc_devs[0]); i++) {
|
||||||
|
d = &lxc_devs[i];
|
||||||
|
ret = snprintf(path, MAXPATHLEN, "%s/dev/%s", root, d->name);
|
||||||
|
if (ret < 0 || ret >= MAXPATHLEN)
|
||||||
|
return -1;
|
||||||
|
ret = mknod(path, d->mode, makedev(d->maj, d->min));
|
||||||
|
if (ret) {
|
||||||
|
SYSERROR("Error creating %s\n", d->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = snprintf(path, MAXPATHLEN, "%s/dev/pts", root);
|
||||||
|
if (ret < 0 || ret >= MAXPATHLEN)
|
||||||
|
return -1;
|
||||||
|
ret = mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||||
|
if (ret) {
|
||||||
|
SYSERROR("Failed to create /dev/pts in container");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO("Populated /dev under %s\n", root);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int setup_rootfs(const struct lxc_rootfs *rootfs)
|
static int setup_rootfs(const struct lxc_rootfs *rootfs)
|
||||||
{
|
{
|
||||||
if (!rootfs->path)
|
if (!rootfs->path)
|
||||||
@ -2265,6 +2335,13 @@ int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lxc_conf->autodev) {
|
||||||
|
if (setup_autodev(lxc_conf->rootfs.mount)) {
|
||||||
|
ERROR("failed to set up /dev in the container");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab, name)) {
|
if (setup_mount(&lxc_conf->rootfs, lxc_conf->fstab, name)) {
|
||||||
ERROR("failed to setup the mounts for '%s'", name);
|
ERROR("failed to setup the mounts for '%s'", name);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -237,6 +237,7 @@ struct lxc_conf {
|
|||||||
#endif
|
#endif
|
||||||
char *seccomp; // filename with the seccomp rules
|
char *seccomp; // filename with the seccomp rules
|
||||||
int maincmd_fd;
|
int maincmd_fd;
|
||||||
|
int autodev; // if 1, mount and fill a /dev at start
|
||||||
};
|
};
|
||||||
|
|
||||||
int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf);
|
int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf);
|
||||||
|
@ -79,6 +79,7 @@ static int config_console(const char *, char *, struct lxc_conf *);
|
|||||||
static int config_seccomp(const char *, char *, struct lxc_conf *);
|
static int config_seccomp(const char *, char *, struct lxc_conf *);
|
||||||
static int config_includefile(const char *, char *, struct lxc_conf *);
|
static int config_includefile(const char *, char *, struct lxc_conf *);
|
||||||
static int config_network_nic(const char *, char *, struct lxc_conf *);
|
static int config_network_nic(const char *, char *, struct lxc_conf *);
|
||||||
|
static int config_autodev(const char *, char *, struct lxc_conf *);
|
||||||
|
|
||||||
static struct lxc_config_t config[] = {
|
static struct lxc_config_t config[] = {
|
||||||
|
|
||||||
@ -121,6 +122,7 @@ static struct lxc_config_t config[] = {
|
|||||||
{ "lxc.console", config_console },
|
{ "lxc.console", config_console },
|
||||||
{ "lxc.seccomp", config_seccomp },
|
{ "lxc.seccomp", config_seccomp },
|
||||||
{ "lxc.include", config_includefile },
|
{ "lxc.include", config_includefile },
|
||||||
|
{ "lxc.autodev", config_autodev },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const size_t config_size = sizeof(config)/sizeof(struct lxc_config_t);
|
static const size_t config_size = sizeof(config)/sizeof(struct lxc_config_t);
|
||||||
@ -881,6 +883,16 @@ static int config_aa_profile(const char *key, char *value, struct lxc_conf *lxc_
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int config_autodev(const char *key, char *value,
|
||||||
|
struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
int v = atoi(value);
|
||||||
|
|
||||||
|
lxc_conf->autodev = v;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int config_cgroup(const char *key, char *value, struct lxc_conf *lxc_conf)
|
static int config_cgroup(const char *key, char *value, struct lxc_conf *lxc_conf)
|
||||||
{
|
{
|
||||||
char *token = "lxc.cgroup.";
|
char *token = "lxc.cgroup.";
|
||||||
|
Loading…
Reference in New Issue
Block a user