mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-14 19:09:16 +00:00
autostart: Define lxc.start.* and lxc.group
First patch in the set of changes required for container autostart. This commit adds the new configuration keys and parsers that will then be used by lxc-start and lxc-stop. Signed-off-by: Stéphane Graber <stgraber@ubuntu.com> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com> Acked-by: Dwight Engen <dwight.engen@oracle.com>
This commit is contained in:
parent
b543ce9624
commit
ee1e7aa0eb
@ -1246,7 +1246,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|||||||
|
|
||||||
</refsect2>
|
</refsect2>
|
||||||
<refsect2>
|
<refsect2>
|
||||||
<title> Logging</title>
|
<title>Logging</title>
|
||||||
<para>
|
<para>
|
||||||
Logging can be configured on a per-container basis. By default,
|
Logging can be configured on a per-container basis. By default,
|
||||||
depending upon how the lxc package was compiled, container startup
|
depending upon how the lxc package was compiled, container startup
|
||||||
@ -1294,6 +1294,63 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
|
<refsect2>
|
||||||
|
<title>Autostart</title>
|
||||||
|
<para>
|
||||||
|
The autostart options support marking which containers should be
|
||||||
|
auto-started and in what order. These options may be used by LXC tools
|
||||||
|
directly or by external tooling provided by the distributions.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>lxc.start.auto</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Whether the container should be auto-started.
|
||||||
|
Valid values are 0 (off) and 1 (on).
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>lxc.start.delay</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
How long to wait (in seconds) after the container is
|
||||||
|
started before starting the next one.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>lxc.start.order</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
An integer used to sort the containers when auto-starting
|
||||||
|
a series of containers at once.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>lxc.group</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A multi-value key (can be used multiple times) to put the
|
||||||
|
container in a container group. Those groups can then be
|
||||||
|
used (amongst other things) to start a series of related
|
||||||
|
containers.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect2>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -2642,6 +2642,7 @@ struct lxc_conf *lxc_conf_init(void)
|
|||||||
lxc_list_init(&new->id_map);
|
lxc_list_init(&new->id_map);
|
||||||
for (i=0; i<NUM_LXC_HOOKS; i++)
|
for (i=0; i<NUM_LXC_HOOKS; i++)
|
||||||
lxc_list_init(&new->hooks[i]);
|
lxc_list_init(&new->hooks[i]);
|
||||||
|
lxc_list_init(&new->groups);
|
||||||
new->lsm_aa_profile = NULL;
|
new->lsm_aa_profile = NULL;
|
||||||
new->lsm_se_context = NULL;
|
new->lsm_se_context = NULL;
|
||||||
new->lsm_umount_proc = 0;
|
new->lsm_umount_proc = 0;
|
||||||
@ -3883,6 +3884,18 @@ int lxc_clear_cgroups(struct lxc_conf *c, const char *key)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lxc_clear_groups(struct lxc_conf *c)
|
||||||
|
{
|
||||||
|
struct lxc_list *it,*next;
|
||||||
|
|
||||||
|
lxc_list_for_each_safe(it, &c->groups, next) {
|
||||||
|
lxc_list_del(it);
|
||||||
|
free(it->elem);
|
||||||
|
free(it);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int lxc_clear_mount_entries(struct lxc_conf *c)
|
int lxc_clear_mount_entries(struct lxc_conf *c)
|
||||||
{
|
{
|
||||||
struct lxc_list *it,*next;
|
struct lxc_list *it,*next;
|
||||||
@ -3970,6 +3983,7 @@ void lxc_conf_free(struct lxc_conf *conf)
|
|||||||
lxc_clear_mount_entries(conf);
|
lxc_clear_mount_entries(conf);
|
||||||
lxc_clear_saved_nics(conf);
|
lxc_clear_saved_nics(conf);
|
||||||
lxc_clear_idmaps(conf);
|
lxc_clear_idmaps(conf);
|
||||||
|
lxc_clear_groups(conf);
|
||||||
free(conf);
|
free(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,6 +323,11 @@ struct lxc_conf {
|
|||||||
int loglevel; // loglevel as specifed in config (if any)
|
int loglevel; // loglevel as specifed in config (if any)
|
||||||
|
|
||||||
int inherit_ns_fd[LXC_NS_MAX];
|
int inherit_ns_fd[LXC_NS_MAX];
|
||||||
|
|
||||||
|
int start_auto;
|
||||||
|
int start_delay;
|
||||||
|
int start_order;
|
||||||
|
struct lxc_list groups;
|
||||||
};
|
};
|
||||||
|
|
||||||
int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf,
|
int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf,
|
||||||
@ -356,6 +361,7 @@ extern int lxc_clear_cgroups(struct lxc_conf *c, const char *key);
|
|||||||
extern int lxc_clear_mount_entries(struct lxc_conf *c);
|
extern int lxc_clear_mount_entries(struct lxc_conf *c);
|
||||||
extern int lxc_clear_hooks(struct lxc_conf *c, const char *key);
|
extern int lxc_clear_hooks(struct lxc_conf *c, const char *key);
|
||||||
extern int lxc_clear_idmaps(struct lxc_conf *c);
|
extern int lxc_clear_idmaps(struct lxc_conf *c);
|
||||||
|
extern int lxc_clear_groups(struct lxc_conf *c);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configure the container from inside
|
* Configure the container from inside
|
||||||
|
@ -92,6 +92,8 @@ static int config_includefile(const char *, const char *, struct lxc_conf *);
|
|||||||
static int config_network_nic(const char *, const char *, struct lxc_conf *);
|
static int config_network_nic(const char *, const char *, struct lxc_conf *);
|
||||||
static int config_autodev(const char *, const char *, struct lxc_conf *);
|
static int config_autodev(const char *, const char *, struct lxc_conf *);
|
||||||
static int config_stopsignal(const char *, const char *, struct lxc_conf *);
|
static int config_stopsignal(const char *, const char *, struct lxc_conf *);
|
||||||
|
static int config_start(const char *, const char *, struct lxc_conf *);
|
||||||
|
static int config_group(const char *, const char *, struct lxc_conf *);
|
||||||
|
|
||||||
static struct lxc_config_t config[] = {
|
static struct lxc_config_t config[] = {
|
||||||
|
|
||||||
@ -142,6 +144,10 @@ static struct lxc_config_t config[] = {
|
|||||||
{ "lxc.include", config_includefile },
|
{ "lxc.include", config_includefile },
|
||||||
{ "lxc.autodev", config_autodev },
|
{ "lxc.autodev", config_autodev },
|
||||||
{ "lxc.stopsignal", config_stopsignal },
|
{ "lxc.stopsignal", config_stopsignal },
|
||||||
|
{ "lxc.start.auto", config_start },
|
||||||
|
{ "lxc.start.delay", config_start },
|
||||||
|
{ "lxc.start.order", config_start },
|
||||||
|
{ "lxc.group", config_group },
|
||||||
};
|
};
|
||||||
|
|
||||||
struct signame {
|
struct signame {
|
||||||
@ -925,6 +931,71 @@ static int config_pts(const char *key, const char *value,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int config_start(const char *key, const char *value,
|
||||||
|
struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
if(strcmp(key, "lxc.start.auto") == 0) {
|
||||||
|
lxc_conf->start_auto = atoi(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (strcmp(key, "lxc.start.delay") == 0) {
|
||||||
|
lxc_conf->start_delay = atoi(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (strcmp(key, "lxc.start.order") == 0) {
|
||||||
|
lxc_conf->start_order = atoi(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SYSERROR("Unknown key: %s", key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int config_group(const char *key, const char *value,
|
||||||
|
struct lxc_conf *lxc_conf)
|
||||||
|
{
|
||||||
|
char *groups, *groupptr, *sptr, *token;
|
||||||
|
struct lxc_list *grouplist;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!strlen(value))
|
||||||
|
return lxc_clear_groups(lxc_conf);
|
||||||
|
|
||||||
|
groups = strdup(value);
|
||||||
|
if (!groups) {
|
||||||
|
SYSERROR("failed to dup '%s'", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* in case several groups are specified in a single line
|
||||||
|
* split these groups in a single element for the list */
|
||||||
|
for (groupptr = groups;;groupptr = NULL) {
|
||||||
|
token = strtok_r(groupptr, " \t", &sptr);
|
||||||
|
if (!token) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
grouplist = malloc(sizeof(*grouplist));
|
||||||
|
if (!grouplist) {
|
||||||
|
SYSERROR("failed to allocate groups list");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
grouplist->elem = strdup(token);
|
||||||
|
if (!grouplist->elem) {
|
||||||
|
SYSERROR("failed to dup '%s'", token);
|
||||||
|
free(grouplist);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lxc_list_add_tail(&lxc_conf->groups, grouplist);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(groups);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int config_tty(const char *key, const char *value,
|
static int config_tty(const char *key, const char *value,
|
||||||
struct lxc_conf *lxc_conf)
|
struct lxc_conf *lxc_conf)
|
||||||
{
|
{
|
||||||
@ -1729,6 +1800,22 @@ static int lxc_get_item_hooks(struct lxc_conf *c, char *retv, int inlen,
|
|||||||
return fulllen;
|
return fulllen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lxc_get_item_groups(struct lxc_conf *c, char *retv, int inlen)
|
||||||
|
{
|
||||||
|
int len, fulllen = 0;
|
||||||
|
struct lxc_list *it;
|
||||||
|
|
||||||
|
if (!retv)
|
||||||
|
inlen = 0;
|
||||||
|
else
|
||||||
|
memset(retv, 0, inlen);
|
||||||
|
|
||||||
|
lxc_list_for_each(it, &c->groups) {
|
||||||
|
strprint(retv, inlen, "%s\n", (char *)it->elem);
|
||||||
|
}
|
||||||
|
return fulllen;
|
||||||
|
}
|
||||||
|
|
||||||
static int lxc_get_item_cap_drop(struct lxc_conf *c, char *retv, int inlen)
|
static int lxc_get_item_cap_drop(struct lxc_conf *c, char *retv, int inlen)
|
||||||
{
|
{
|
||||||
int len, fulllen = 0;
|
int len, fulllen = 0;
|
||||||
@ -1952,6 +2039,14 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv,
|
|||||||
return lxc_get_item_network(c, retv, inlen);
|
return lxc_get_item_network(c, retv, inlen);
|
||||||
else if (strncmp(key, "lxc.network.", 12) == 0)
|
else if (strncmp(key, "lxc.network.", 12) == 0)
|
||||||
return lxc_get_item_nic(c, retv, inlen, key + 12);
|
return lxc_get_item_nic(c, retv, inlen, key + 12);
|
||||||
|
else if (strcmp(key, "lxc.start.auto") == 0)
|
||||||
|
return lxc_get_conf_int(c, retv, inlen, c->start_auto);
|
||||||
|
else if (strcmp(key, "lxc.start.delay") == 0)
|
||||||
|
return lxc_get_conf_int(c, retv, inlen, c->start_delay);
|
||||||
|
else if (strcmp(key, "lxc.start.order") == 0)
|
||||||
|
return lxc_get_conf_int(c, retv, inlen, c->start_order);
|
||||||
|
else if (strcmp(key, "lxc.group") == 0)
|
||||||
|
return lxc_get_item_groups(c, retv, inlen);
|
||||||
else return -1;
|
else return -1;
|
||||||
|
|
||||||
if (!v)
|
if (!v)
|
||||||
@ -1977,6 +2072,8 @@ int lxc_clear_config_item(struct lxc_conf *c, const char *key)
|
|||||||
return lxc_clear_mount_entries(c);
|
return lxc_clear_mount_entries(c);
|
||||||
else if (strncmp(key, "lxc.hook", 8) == 0)
|
else if (strncmp(key, "lxc.hook", 8) == 0)
|
||||||
return lxc_clear_hooks(c, key);
|
return lxc_clear_hooks(c, key);
|
||||||
|
else if (strncmp(key, "lxc.group", 9) == 0)
|
||||||
|
return lxc_clear_groups(c);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user