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.hal...@ubuntu.com>

Acked-by: Stéphane Graber <stgra...@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

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to