mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-13 11:14:46 +00:00
config : add lxc.hook.destroy option
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
This commit is contained in:
parent
b219dcecd7
commit
37cf711b28
@ -1359,6 +1359,18 @@ mknod errno 0
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>lxc.hook.destroy</option>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
A hook to be run when the container is destroyed.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
|
||||||
<refsect2>
|
<refsect2>
|
||||||
|
@ -163,7 +163,7 @@ return -1;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *lxchook_names[NUM_LXC_HOOKS] = {
|
char *lxchook_names[NUM_LXC_HOOKS] = {
|
||||||
"pre-start", "pre-mount", "mount", "autodev", "start", "post-stop", "clone" };
|
"pre-start", "pre-mount", "mount", "autodev", "start", "post-stop", "clone", "destroy" };
|
||||||
|
|
||||||
typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *);
|
typedef int (*instantiate_cb)(struct lxc_handler *, struct lxc_netdev *);
|
||||||
|
|
||||||
@ -3977,6 +3977,8 @@ int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf,
|
|||||||
which = LXCHOOK_POSTSTOP;
|
which = LXCHOOK_POSTSTOP;
|
||||||
else if (strcmp(hook, "clone") == 0)
|
else if (strcmp(hook, "clone") == 0)
|
||||||
which = LXCHOOK_CLONE;
|
which = LXCHOOK_CLONE;
|
||||||
|
else if (strcmp(hook, "destroy") == 0)
|
||||||
|
which = LXCHOOK_DESTROY;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
lxc_list_for_each(it, &conf->hooks[which]) {
|
lxc_list_for_each(it, &conf->hooks[which]) {
|
||||||
|
@ -279,7 +279,8 @@ enum {
|
|||||||
*/
|
*/
|
||||||
enum lxchooks {
|
enum lxchooks {
|
||||||
LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_AUTODEV,
|
LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_AUTODEV,
|
||||||
LXCHOOK_START, LXCHOOK_POSTSTOP, LXCHOOK_CLONE, NUM_LXC_HOOKS};
|
LXCHOOK_START, LXCHOOK_POSTSTOP, LXCHOOK_CLONE, LXCHOOK_DESTROY,
|
||||||
|
NUM_LXC_HOOKS};
|
||||||
extern char *lxchook_names[NUM_LXC_HOOKS];
|
extern char *lxchook_names[NUM_LXC_HOOKS];
|
||||||
|
|
||||||
struct saved_nic {
|
struct saved_nic {
|
||||||
|
@ -132,6 +132,7 @@ static struct lxc_config_t config[] = {
|
|||||||
{ "lxc.hook.start", config_hook },
|
{ "lxc.hook.start", config_hook },
|
||||||
{ "lxc.hook.post-stop", config_hook },
|
{ "lxc.hook.post-stop", config_hook },
|
||||||
{ "lxc.hook.clone", config_hook },
|
{ "lxc.hook.clone", config_hook },
|
||||||
|
{ "lxc.hook.destroy", config_hook },
|
||||||
{ "lxc.hook", config_hook },
|
{ "lxc.hook", config_hook },
|
||||||
{ "lxc.network.type", config_network_type },
|
{ "lxc.network.type", config_network_type },
|
||||||
{ "lxc.network.flags", config_network_flags },
|
{ "lxc.network.flags", config_network_flags },
|
||||||
@ -1002,6 +1003,8 @@ static int config_hook(const char *key, const char *value,
|
|||||||
return add_hook(lxc_conf, LXCHOOK_POSTSTOP, copy);
|
return add_hook(lxc_conf, LXCHOOK_POSTSTOP, copy);
|
||||||
else if (strcmp(key, "lxc.hook.clone") == 0)
|
else if (strcmp(key, "lxc.hook.clone") == 0)
|
||||||
return add_hook(lxc_conf, LXCHOOK_CLONE, copy);
|
return add_hook(lxc_conf, LXCHOOK_CLONE, copy);
|
||||||
|
else if (strcmp(key, "lxc.hook.destroy") == 0)
|
||||||
|
return add_hook(lxc_conf, LXCHOOK_DESTROY, copy);
|
||||||
SYSERROR("Unknown key: %s", key);
|
SYSERROR("Unknown key: %s", key);
|
||||||
free(copy);
|
free(copy);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2154,6 +2154,7 @@ static bool container_destroy(struct lxc_container *c)
|
|||||||
{
|
{
|
||||||
bool bret = false;
|
bool bret = false;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct lxc_conf *conf = c->lxc_conf;
|
||||||
|
|
||||||
if (!c || !do_lxcapi_is_defined(c))
|
if (!c || !do_lxcapi_is_defined(c))
|
||||||
return false;
|
return false;
|
||||||
@ -2167,19 +2168,47 @@ static bool container_destroy(struct lxc_container *c)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_config && c->lxc_conf == current_config) {
|
if (!lxc_list_empty(&conf->hooks[LXCHOOK_DESTROY])) {
|
||||||
current_config = NULL;
|
/* Start of environment variable setup for hooks */
|
||||||
if (c->lxc_conf->logfd != -1) {
|
if (setenv("LXC_NAME", c->name, 1)) {
|
||||||
close(c->lxc_conf->logfd);
|
SYSERROR("failed to set environment variable for container name");
|
||||||
c->lxc_conf->logfd = -1;
|
}
|
||||||
|
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(c->name, "destroy", conf, c->get_config_path(c), NULL)) {
|
||||||
|
ERROR("Error executing clone hook for %s", c->name);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->lxc_conf && c->lxc_conf->rootfs.path && c->lxc_conf->rootfs.mount) {
|
if (current_config && conf == current_config) {
|
||||||
|
current_config = NULL;
|
||||||
|
if (conf->logfd != -1) {
|
||||||
|
close(conf->logfd);
|
||||||
|
conf->logfd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conf && conf->rootfs.path && conf->rootfs.mount) {
|
||||||
if (am_unpriv())
|
if (am_unpriv())
|
||||||
ret = userns_exec_1(c->lxc_conf, bdev_destroy_wrapper, c->lxc_conf);
|
ret = userns_exec_1(conf, bdev_destroy_wrapper, conf);
|
||||||
else
|
else
|
||||||
ret = do_bdev_destroy(c->lxc_conf);
|
ret = do_bdev_destroy(conf);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ERROR("Error destroying rootfs for %s", c->name);
|
ERROR("Error destroying rootfs for %s", c->name);
|
||||||
goto out;
|
goto out;
|
||||||
@ -2192,7 +2221,7 @@ static bool container_destroy(struct lxc_container *c)
|
|||||||
char *path = alloca(strlen(p1) + strlen(c->name) + 2);
|
char *path = alloca(strlen(p1) + strlen(c->name) + 2);
|
||||||
sprintf(path, "%s/%s", p1, c->name);
|
sprintf(path, "%s/%s", p1, c->name);
|
||||||
if (am_unpriv())
|
if (am_unpriv())
|
||||||
ret = userns_exec_1(c->lxc_conf, lxc_rmdir_onedev_wrapper, path);
|
ret = userns_exec_1(conf, lxc_rmdir_onedev_wrapper, path);
|
||||||
else
|
else
|
||||||
ret = lxc_rmdir_onedev(path, "snaps");
|
ret = lxc_rmdir_onedev(path, "snaps");
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user