mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 03:44:32 +00:00
MAKEDEV call, add autodev hooks, add environment variables for hook scripts.
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>
This commit is contained in:
parent
9ea87d5ded
commit
f7bee6c6f3
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user