]> git.proxmox.com Git - mirror_lxc.git/commitdiff
MAKEDEV call, add autodev hooks, add environment variables for hook scripts.
authorMichael H. Warfield <mhw@WittsEnd.com>
Mon, 14 Jan 2013 16:59:36 +0000 (11:59 -0500)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 14 Jan 2013 20:04:09 +0000 (14:04 -0600)
Ok...  Here's the patch again.  Since Serge is removing the loglevel
structure member, this patch no longer references that element.

From the original description:

1) Removes run_makedev() and the call to it from conf.c per discussion.

2) Adds an lxc.hook.autodev hook.

Note: This hook is very close (one routine level abstracted) from where
the run_makedev was called.  Anyone really rrreeeaaalllyyy needing
MAKEDEV can add it in with a small shim script to do whatever they want
under whatever distro they're using, so no functionality is lost there.

3) Added a number of environment variables for all the hook scripts to
reference to assist in execution.  Things like LXC_ROOTFS_MOUNT could be
very useful but others were added as well.  Room for more if anyone has
an itch.  All in one spot in lxc_start.c.

4) clearenv and putenv( "container=lxc" ) calls were moved to just after
the "start" hook in the container just prior to actually firing up the
container so we could use environment variables prior to that and have
them flushed them before firing up init.  Nice side effect is that you
can define environment variables and then call lxc-start and have them
show up in those hooks scripts.

5) I actually DID update the man page for lxc.conf!  I guess I lied when
I said I wouldn't get that done.

[... and ...]

I added the rcfile to the lxc_conf structure as suggested and moved the
setenv bundle from lxc-start.c over to start.c just prior to calling
run_lxc_hooks for the pre-start hook.

Signed-off-by: Michael H. Warfield <mhw@WittsEnd.com>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
doc/lxc.conf.sgml.in
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/lxc_start.c
src/lxc/start.c

index 96dea89f3b3c1956afcca1600656478222777da0..1298143da254383190bbfbb99c93793f1a576d62 100644 (file)
@@ -510,6 +510,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
        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 100k) 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.  Addional
+        devices in the containers /dev directory may be created through the
+        use of the <option>lxc.hook.autodev</option> hook.
       </para>
       <variablelist>
        <varlistentry>
@@ -734,6 +738,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
          </listitem>
        </varlistentry>
       </variablelist>
+      <variablelist>
+       <varlistentry>
+         <term>
+           <option>lxc.hook.autodev</option>
+         </term>
+         <listitem>
+           <para>
+             A hook to be run in the container's namespace after
+             mounting has been done and after any mount hooks have
+             run, but before the pivot_root, if
+             <option>lxc.autodev</option> == 1.
+             The purpose of this hook is to assist in populating the
+             /dev directory of the container when using the autodev
+             option for systemd based containers.  The container's /dev
+             directory is relative to the
+             ${<option>LXC_ROOTFS_MOUNT</option>} environment
+             variable available when the hook is run.
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
       <variablelist>
        <varlistentry>
          <term>
@@ -763,6 +788,103 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
       </variablelist>
     </refsect2>
 
+    <refsect2>
+      <title>Startup hooks Environment Variables</title>
+      <para>
+        A number of environment variables are made available to the startup
+        hooks to provide configuration information and assist in the
+        functioning of the hooks.  Not all variables are valid in all
+        contexts.  In particular, all paths are relative to the host system
+        and, as such, not valid during the <option>lxc.hook.start</option> hook.
+      </para>
+      <variablelist>
+       <varlistentry>
+         <term>
+           <option>LXC_NAME</option>
+         </term>
+         <listitem>
+           <para>
+             The LXC name of the container.  Useful for logging messages
+             in commmon log environments.  [<option>-n</option>]
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+      <variablelist>
+       <varlistentry>
+         <term>
+           <option>LXC_CONFIG_FILE</option>
+         </term>
+         <listitem>
+           <para>
+             Host relative path to the container configuration file.  This
+             gives the container to reference the original, top level,
+             configuration file for the container in order to locate any
+             addotional configuration information not otherwise made
+             available.  [<option>-f</option>]
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+      <variablelist>
+       <varlistentry>
+         <term>
+           <option>LXC_CONSOLE</option>
+         </term>
+         <listitem>
+           <para>
+             The path to the console output of the container if not NULL.
+             [<option>-c</option>] [<option>lxc.console</option>]
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+      <variablelist>
+       <varlistentry>
+         <term>
+           <option>LXC_CONSOLE_LOGPATH</option>
+         </term>
+         <listitem>
+           <para>
+             The path to the console log output of the container if not NULL.
+             [<option>-L</option>]
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+      <variablelist>
+       <varlistentry>
+         <term>
+           <option>LXC_ROOTFS_MOUNT</option>
+         </term>
+         <listitem>
+           <para>
+             The mount location to which the container is initially bound.
+             This will be the host relative path to the container rootfs
+             for the container instance being started and is where changes
+             should be made for that instance.
+             [<option>lxc.rootfs.mount</option>]
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+      <variablelist>
+       <varlistentry>
+         <term>
+           <option>LXC_ROOTFS_PATH</option>
+         </term>
+         <listitem>
+           <para>
+             The host relative path to the container root which has been
+             mounted to the rootfs.mount location.
+             [<option>lxc.rootfs</option>]
+           </para>
+         </listitem>
+       </varlistentry>
+      </variablelist>
+
+    </refsect2>
+
   </refsect1>
 
   <refsect1>
index ea0fcf6fc6c78c42db212f6d2d9f4ad3703dca90..d448d59f5f99bfa9dae8b99d45579729e1ea0387 100644 (file)
@@ -172,7 +172,7 @@ return -1;
 #endif
 
 char *lxchook_names[NUM_LXC_HOOKS] = {
-       "pre-start", "pre-mount", "mount", "start", "post-stop" };
+       "pre-start", "pre-mount", "mount", "autodev", "start", "post-stop" };
 
 typedef int (*instanciate_cb)(struct lxc_handler *, struct lxc_netdev *);
 
@@ -971,33 +971,6 @@ static int mount_autodev(char *root)
        return 0;
 }
 
-/*
- * Try to run MAKEDEV console in the container.  If something fails,
- * continue anyway as it should not be detrimental to the container.
- * This makes sure that things like /dev/vcs* exist.
- * (Pass devpath in to reduce stack usage)
- */
-static void run_makedev(char *devpath)
-{
-       int curd;
-       int ret;
-
-       curd = open(".", O_RDONLY);
-       if (curd < 0)
-               return;
-       ret = chdir(devpath);
-       if (ret) {
-               close(curd);
-               return;
-       }
-       if (run_buffer("/sbin/MAKEDEV console"))
-               INFO("Error running MAKEDEV console in %s", devpath);
-       ret = fchdir(curd);
-       if (ret)
-               INFO("Error returning to original directory: expect breakage");
-       close(curd);
-}
-
 struct lxc_devs {
        char *name;
        mode_t mode;
@@ -1029,8 +1002,7 @@ static int setup_autodev(char *root)
        if (ret < 0 || ret >= MAXPATHLEN) {
                ERROR("Error calculating container /dev location");
                return -1;
-       } else
-               run_makedev(path);
+       }
 
        INFO("Populating /dev under %s\n", root);
        cmask = umask(S_IXUSR | S_IXGRP | S_IXOTH);
@@ -2612,6 +2584,10 @@ int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
        }
 
        if (lxc_conf->autodev) {
+               if (run_lxc_hooks(name, "autodev", lxc_conf)) {
+                       ERROR("failed to run autodev hooks for container '%s'.", name);
+                       return -1;
+               }
                if (setup_autodev(lxc_conf->rootfs.mount)) {
                        ERROR("failed to populate /dev in the container");
                        return -1;
@@ -2687,6 +2663,8 @@ int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf)
                which = LXCHOOK_PREMOUNT;
        else if (strcmp(hook, "mount") == 0)
                which = LXCHOOK_MOUNT;
+       else if (strcmp(hook, "autodev") == 0)
+               which = LXCHOOK_AUTODEV;
        else if (strcmp(hook, "start") == 0)
                which = LXCHOOK_START;
        else if (strcmp(hook, "post-stop") == 0)
index 83de84aabeacfc05e53472d979b6ce4da07e5631..e2268596645ba9d59d0a56292b70cba94f8381da 100644 (file)
@@ -214,8 +214,8 @@ struct lxc_rootfs {
 #endif
  */
 enum lxchooks {
-       LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_START,
-       LXCHOOK_POSTSTOP, NUM_LXC_HOOKS};
+       LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_AUTODEV,
+       LXCHOOK_START, LXCHOOK_POSTSTOP, NUM_LXC_HOOKS};
 extern char *lxchook_names[NUM_LXC_HOOKS];
 
 struct saved_nic {
@@ -256,6 +256,7 @@ struct lxc_conf {
 #endif
        int maincmd_fd;
        int autodev;  // if 1, mount and fill a /dev at start
+       char *rcfile;   // Copy of the top level rcfile we read
 };
 
 int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf);
index 7372a347b5787c6f3d26a94aa1a04acfd8afe045..034136ef52845c68687a2575174dd8c857d46bfb 100644 (file)
@@ -107,6 +107,7 @@ static struct lxc_config_t config[] = {
        { "lxc.hook.pre-start",       config_hook                 },
        { "lxc.hook.pre-mount",       config_hook                 },
        { "lxc.hook.mount",           config_hook                 },
+       { "lxc.hook.autodev",         config_hook                 },
        { "lxc.hook.start",           config_hook                 },
        { "lxc.hook.post-stop",       config_hook                 },
        { "lxc.network.type",         config_network_type         },
@@ -833,6 +834,8 @@ static int config_hook(const char *key, const char *value,
                return add_hook(lxc_conf, LXCHOOK_PRESTART, copy);
        else if (strcmp(key, "lxc.hook.pre-mount") == 0)
                return add_hook(lxc_conf, LXCHOOK_PREMOUNT, copy);
+       else if (strcmp(key, "lxc.hook.autodev") == 0)
+               return add_hook(lxc_conf, LXCHOOK_AUTODEV, copy);
        else if (strcmp(key, "lxc.hook.mount") == 0)
                return add_hook(lxc_conf, LXCHOOK_MOUNT, copy);
        else if (strcmp(key, "lxc.hook.start") == 0)
@@ -1262,6 +1265,10 @@ int lxc_config_readline(char *buffer, struct lxc_conf *conf)
 
 int lxc_config_read(const char *file, struct lxc_conf *conf)
 {
+       /* Catch only the top level config file name in the structure */
+       if( ! conf->rcfile ) {
+               conf->rcfile = strdup( file );
+       }
        return lxc_file_for_each_line(file, parse_line, conf);
 }
 
index 184fb04c6902c931e0baa2aa3929b5129cecfd7f..a97dccaa86cbb78245d472daa90bd12673781f06 100644 (file)
@@ -168,15 +168,6 @@ int main(int argc, char *argv[])
                         my_args.progname, my_args.quiet))
                return err;
 
-       if (clearenv()) {
-               SYSERROR("failed to clear environment");
-               /* don't error out though */
-       }
-       if (putenv("container=lxc")) {
-               SYSERROR("failed to set environment variable");
-               return err;
-       }
-
        /* rcfile is specified in the cli option */
        if (my_args.rcfile)
                rcfile = (char *)my_args.rcfile;
index a539703d5748ab125b3c38c0f6248a787cf8d381..e78f685df6f42204b23c4c36c95d8cc87f0f68c2 100644 (file)
@@ -401,6 +401,27 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf)
                goto out_free_name;
        }
 
+       /* Start of environment variable setup for hooks */
+       if (setenv("LXC_NAME", name, 1)) {
+               SYSERROR("failed to set environment variable for container name");
+       }
+       if (setenv("LXC_CONFIG_FILE", conf->rcfile, 1)) {
+               SYSERROR("failed to set environment variable for config path");
+       }
+       if (setenv("LXC_ROOTFS_MOUNT", conf->rootfs.mount, 1)) {
+               SYSERROR("failed to set environment variable for rootfs mount");
+       }
+       if (setenv("LXC_ROOTFS_PATH", conf->rootfs.path, 1)) {
+               SYSERROR("failed to set environment variable for rootfs mount");
+       }
+       if (conf->console.path && setenv("LXC_CONSOLE", conf->console.path, 1)) {
+               SYSERROR("failed to set environment variable for console path");
+       }
+       if (conf->console.log_path && setenv("LXC_CONSOLE_LOGPATH", conf->console.log_path, 1)) {
+               SYSERROR("failed to set environment variable for console log");
+       }
+       /* End of environment variable setup for hooks */
+
        if (run_lxc_hooks(name, "pre-start", conf)) {
                ERROR("failed to run pre-start hooks for container '%s'.", name);
                goto out_aborting;
@@ -587,6 +608,21 @@ static int do_start(void *data)
                goto out_warn_father;
        }
 
+       /* The clearenv() and putenv() calls have been moved here
+        * to allow us to use enviroment variables passed to the various
+        * hooks, such as the start hook above.  Not all of the
+        * variables like CONFIG_PATH or ROOTFS are valid in this
+        * context but others are. */
+       if (clearenv()) {
+               SYSERROR("failed to clear environment");
+               /* don't error out though */
+       }
+
+       if (putenv("container=lxc")) {
+               SYSERROR("failed to set environment variable");
+               return -1;
+       }
+
        close(handler->sigfd);
 
        /* after this call, we are in error because this