[lxc-devel] [PATCH] Add lxc.autodev (v2)
Stéphane Graber
stgraber at ubuntu.com
Mon Nov 26 16:44:38 UTC 2012
On 11/23/2012 03:16 PM, Serge Hallyn wrote:
> 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 at ubuntu.com>
Acked-by: Stéphane Graber <stgraber at ubuntu.com>
I'll push the fix I highlighted below too.
This change is now in the staging branch.
Thanks
> ---
> doc/lxc.conf.sgml.in | 25 ++++++++++++++++
> src/lxc/conf.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++
> src/lxc/conf.h | 1 +
> src/lxc/confile.c | 12 ++++++++
> 4 files changed, 115 insertions(+)
>
> diff --git a/doc/lxc.conf.sgml.in b/doc/lxc.conf.sgml.in
> index 6c3d7b2..eed07fc 100644
> --- a/doc/lxc.conf.sgml.in
> +++ b/doc/lxc.conf.sgml.in
> @@ -502,6 +502,31 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> </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
Should be "If lxc.autodev is set to 1"
> + 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>
> <title>Mount points</title>
> <para>
> The mount points section specifies the different places to be
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index fe574ac..f1c41f1 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -653,6 +653,15 @@ static int setup_tty(const struct lxc_rootfs *rootfs,
> return -1;
> }
> } 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)) {
> WARN("failed to mount '%s'->'%s'",
> pty_info->name, path);
> @@ -860,6 +869,67 @@ static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir)
> 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)
> {
> if (!rootfs->path)
> @@ -2265,6 +2335,13 @@ int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
> 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)) {
> ERROR("failed to setup the mounts for '%s'", name);
> return -1;
> diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> index dccc176..76bf19d 100644
> --- a/src/lxc/conf.h
> +++ b/src/lxc/conf.h
> @@ -237,6 +237,7 @@ struct lxc_conf {
> #endif
> char *seccomp; // filename with the seccomp rules
> 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);
> diff --git a/src/lxc/confile.c b/src/lxc/confile.c
> index cf1c891..3d9f36e 100644
> --- a/src/lxc/confile.c
> +++ b/src/lxc/confile.c
> @@ -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_includefile(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[] = {
>
> @@ -121,6 +122,7 @@ static struct lxc_config_t config[] = {
> { "lxc.console", config_console },
> { "lxc.seccomp", config_seccomp },
> { "lxc.include", config_includefile },
> + { "lxc.autodev", config_autodev },
> };
>
> 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
>
> +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)
> {
> char *token = "lxc.cgroup.";
>
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 899 bytes
Desc: OpenPGP digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20121126/140f704a/attachment.pgp>
More information about the lxc-devel
mailing list