2013/1/12 Michael H. Warfield <m...@wittsend.com>: > Ok... > > My patch to deal with the MAKDEV and hook script stuff after discussion > and valuable input from Serge. > > To reiterate - Does several things (that are closely intertwined so > separate patches are not justified)... > > 1) Removes run_makedev() and the call to it from conf.c per discussion. > > 2) Adds an lxc.hook.autodev hook. > > 3) Added a number of environment variables for all the hook scripts to > reference to assist in execution. > > 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. > > 5) Documentation updated as appropriate. > > Patch below my signature block. In addition to signing off, this > message is PGP signed (as are most of my messages) and, as such, > authenticated to me. > > Signed-off-by: Michael H. Warfield <m...@wittsend.com> > > Regards, > Mike > -- > Michael H. Warfield (AI4NB) | (770) 985-6132 | m...@wittsend.com > /\/\|=mhw=|\/\/ | (678) 463-0932 | http://www.wittsend.com/mhw/ > NIC whois: MHW9 | An optimist believes we live in the best of all > PGP Key: 0x674627FF | possible worlds. A pessimist is sure of it! > > -- > diff --git a/doc/lxc.conf.sgml.in b/doc/lxc.conf.sgml.in > index 96dea89..1298143 100644 > --- a/doc/lxc.conf.sgml.in > +++ b/doc/lxc.conf.sgml.in > @@ -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 There's a typo at the end of line
> + devices in the containers /dev directory may be created through the > + use of the <option>lxc.hook.autodev</option> hook. > </para> > <variablelist> > <varlistentry> > @@ -737,6 +741,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA > 02111-1307 USA > <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> > <option>lxc.hook.start</option> > </term> > <listitem> > @@ -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> > diff --git a/src/lxc/conf.c b/src/lxc/conf.c > index 1c02850..699011a 100644 > --- a/src/lxc/conf.c > +++ b/src/lxc/conf.c > @@ -116,7 +116,7 @@ lxc_log_define(lxc_conf, lxc); > #endif > > char *lxchook_names[NUM_LXC_HOOKS] = { > - "pre-start", "pre-mount", "mount", "start", "post-stop" }; > + "pre-start", "pre-mount", "mount", "autodev", "start", "post-stop" }; > > extern int pivot_root(const char * new_root, const char * put_old); > > @@ -913,33 +913,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; > @@ -971,8 +944,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); > @@ -2553,6 +2525,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; > @@ -2628,6 +2604,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) > diff --git a/src/lxc/conf.h b/src/lxc/conf.h > index b576893..45161e1 100644 > --- a/src/lxc/conf.h > +++ b/src/lxc/conf.h > @@ -213,8 +213,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 { > @@ -257,6 +257,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); > diff --git a/src/lxc/confile.c b/src/lxc/confile.c > index 1d87227..8cef8be 100644 > --- a/src/lxc/confile.c > +++ b/src/lxc/confile.c > @@ -104,6 +104,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 }, > @@ -821,6 +822,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) > @@ -1265,6 +1268,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); > } > > diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c > index 184fb04..a97dcca 100644 > --- a/src/lxc/lxc_start.c > +++ b/src/lxc/lxc_start.c > @@ -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; > diff --git a/src/lxc/start.c b/src/lxc/start.c > index 82a74d8..ffc7c5b 100644 > --- a/src/lxc/start.c > +++ b/src/lxc/start.c > @@ -391,6 +391,34 @@ 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"); > + } > + { > + char loglevel[16]; > + snprintf( loglevel, 14, "%d", conf->loglevel ); > + if (setenv("LXC_LOGLEVEL", loglevel, 1)) { > + SYSERROR("failed to set environment variable for log > level mount"); > + } > + } > + /* 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; > @@ -575,6 +603,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 > > > ------------------------------------------------------------------------------ > Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and > much more. Get web development skills now with LearnDevNow - > 350+ hours of step-by-step video tutorials by Microsoft MVPs and experts. > SALE $99.99 this month only -- learn more at: > http://p.sf.net/sfu/learnmore_122812 > _______________________________________________ > Lxc-devel mailing list > Lxc-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/lxc-devel > ------------------------------------------------------------------------------ Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and much more. Get web development skills now with LearnDevNow - 350+ hours of step-by-step video tutorials by Microsoft MVPs and experts. SALE $99.99 this month only -- learn more at: http://p.sf.net/sfu/learnmore_122812 _______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel