Unverified Commit 81b10e37 by Serge Hallyn Committed by GitHub

Merge pull request #2026 from brauner/2017-12-12/lxc_hook_version

confile: add lxc.hook.version
parents 45acc1bd 990b9ac3
......@@ -308,84 +308,167 @@ static int run_buffer(char *buffer)
f = lxc_popen(buffer);
if (!f) {
SYSERROR("Failed to popen() %s.", buffer);
SYSERROR("Failed to popen() %s", buffer);
return -1;
}
output = malloc(LXC_LOG_BUFFER_SIZE);
if (!output) {
ERROR("Failed to allocate memory for %s.", buffer);
ERROR("Failed to allocate memory for %s", buffer);
lxc_pclose(f);
return -1;
}
while (fgets(output, LXC_LOG_BUFFER_SIZE, f->f))
DEBUG("Script %s with output: %s.", buffer, output);
DEBUG("Script %s with output: %s", buffer, output);
free(output);
ret = lxc_pclose(f);
if (ret == -1) {
SYSERROR("Script exited with error.");
SYSERROR("Script exited with error");
return -1;
} else if (WIFEXITED(ret) && WEXITSTATUS(ret) != 0) {
ERROR("Script exited with status %d.", WEXITSTATUS(ret));
ERROR("Script exited with status %d", WEXITSTATUS(ret));
return -1;
} else if (WIFSIGNALED(ret)) {
ERROR("Script terminated by signal %d.", WTERMSIG(ret));
ERROR("Script terminated by signal %d", WTERMSIG(ret));
return -1;
}
return 0;
}
static int run_script_argv(const char *name, const char *section,
const char *script, const char *hook,
const char *lxcpath, char **argsin)
int run_script_argv(const char *name, unsigned int hook_version,
const char *section, const char *script,
const char *hookname, char **argsin)
{
int ret, i;
int buf_pos, i, ret;
char *buffer;
size_t size = 0;
INFO("Executing script \"%s\" for container \"%s\", config section \"%s\".",
script, name, section);
if (hook_version == 0)
INFO("Executing script \"%s\" for container \"%s\", config "
"section \"%s\"", script, name, section);
else
INFO("Executing script \"%s\" for container \"%s\"", script, name);
for (i = 0; argsin && argsin[i]; i++)
size += strlen(argsin[i]) + 1;
size += strlen(hook) + 1;
size += strlen("exec");
size += sizeof("exec");
size += strlen(script);
size += strlen(name);
size += strlen(section);
size += 4;
size++;
if (size > INT_MAX)
return -1;
return -EFBIG;
buffer = alloca(size);
if (!buffer) {
ERROR("Failed to allocate memory.");
return -1;
}
ret =
snprintf(buffer, size, "exec %s %s %s %s", script, name, section, hook);
if (ret < 0 || (size_t)ret >= size) {
ERROR("Script name too long.");
return -1;
if (hook_version == 0) {
size += strlen(hookname);
size++;
size += strlen(name);
size++;
size += strlen(section);
size++;
if (size > INT_MAX)
return -EFBIG;
buf_pos = snprintf(buffer, size, "exec %s %s %s %s", script, name, section, hookname);
if (buf_pos < 0 || (size_t)buf_pos >= size) {
ERROR("Failed to create command line for script \"%s\"", script);
return -1;
}
} else {
buf_pos = snprintf(buffer, size, "exec %s", script);
if (buf_pos < 0 || (size_t)buf_pos >= size) {
ERROR("Failed to create command line for script \"%s\"", script);
return -1;
}
ret = setenv("LXC_HOOK_TYPE", hookname, 1);
if (ret < 0) {
SYSERROR("Failed to set environment variable: "
"LXC_HOOK_TYPE=%s", hookname);
return -1;
}
TRACE("Set environment variable: LXC_HOOK_TYPE=%s", section);
ret = setenv("LXC_HOOK_SECTION", section, 1);
if (ret < 0) {
SYSERROR("Failed to set environment variable: "
"LXC_HOOK_SECTION=%s", section);
return -1;
}
TRACE("Set environment variable: LXC_HOOK_SECTION=%s", section);
if (strcmp(section, "net") == 0) {
char *parent;
if (!argsin[0])
return -EINVAL;
ret = setenv("LXC_NET_TYPE", argsin[0], 1);
if (ret < 0) {
SYSERROR("Failed to set environment variable: "
"LXC_NET_TYPE=%s", argsin[0]);
return -1;
}
TRACE("Set environment variable: LXC_NET_TYPE=%s", argsin[0]);
parent = argsin[1] ? argsin[1] : "";
if (strcmp(argsin[0], "macvlan")) {
ret = setenv("LXC_NET_PARENT", parent, 1);
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent);
return -1;
}
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent);
} else if (strcmp(argsin[0], "phys")) {
ret = setenv("LXC_NET_PARENT", parent, 1);
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent);
return -1;
}
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent);
} else if (strcmp(argsin[0], "veth")) {
char *peer = argsin[2] ? argsin[2] : "";
ret = setenv("LXC_NET_PEER", peer, 1);
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PEER=%s", peer);
return -1;
}
TRACE("Set environment variable: LXC_NET_PEER=%s", peer);
ret = setenv("LXC_NET_PARENT", parent, 1);
if (ret < 0) {
SYSERROR("Failed to set environment "
"variable: LXC_NET_PARENT=%s", parent);
return -1;
}
TRACE("Set environment variable: LXC_NET_PARENT=%s", parent);
}
}
}
for (i = 0; argsin && argsin[i]; i++) {
int len = size - ret;
int rc;
rc = snprintf(buffer + ret, len, " %s", argsin[i]);
if (rc < 0 || rc >= len) {
ERROR("Script args too long.");
size_t len = size - buf_pos;
ret = snprintf(buffer + buf_pos, len, " %s", argsin[i]);
if (ret < 0 || (size_t)ret >= len) {
ERROR("Failed to create command line for script \"%s\"", script);
return -1;
}
ret += rc;
buf_pos += ret;
}
return run_buffer(buffer);
......@@ -2484,6 +2567,7 @@ struct lxc_conf *lxc_conf_init(void)
lxc_list_init(&new->limits);
lxc_list_init(&new->sysctls);
lxc_list_init(&new->procs);
new->hooks_version = 0;
for (i = 0; i < NUM_LXC_HOOKS; i++)
lxc_list_init(&new->hooks[i]);
lxc_list_init(&new->groups);
......@@ -3068,7 +3152,7 @@ int do_rootfs_setup(struct lxc_conf *conf, const char *name, const char *lxcpath
remount_all_slave();
if (run_lxc_hooks(name, "pre-mount", conf, lxcpath, NULL)) {
if (run_lxc_hooks(name, "pre-mount", conf, NULL)) {
ERROR("failed to run pre-mount hooks for container '%s'.", name);
return -1;
}
......@@ -3177,13 +3261,13 @@ int lxc_setup(struct lxc_handler *handler)
return -1;
}
if (run_lxc_hooks(name, "mount", lxc_conf, lxcpath, NULL)) {
if (run_lxc_hooks(name, "mount", lxc_conf, NULL)) {
ERROR("failed to run mount hooks for container '%s'.", name);
return -1;
}
if (lxc_conf->autodev > 0) {
if (run_lxc_hooks(name, "autodev", lxc_conf, lxcpath, NULL)) {
if (run_lxc_hooks(name, "autodev", lxc_conf, NULL)) {
ERROR("failed to run autodev hooks for container '%s'.", name);
return -1;
}
......@@ -3260,41 +3344,45 @@ int lxc_setup(struct lxc_handler *handler)
return 0;
}
int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf,
const char *lxcpath, char *argv[])
int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf,
char *argv[])
{
int which = -1;
struct lxc_list *it;
int which = -1;
if (strcmp(hook, "pre-start") == 0)
if (strcmp(hookname, "pre-start") == 0)
which = LXCHOOK_PRESTART;
else if (strcmp(hook, "start-host") == 0)
else if (strcmp(hookname, "start-host") == 0)
which = LXCHOOK_START_HOST;
else if (strcmp(hook, "pre-mount") == 0)
else if (strcmp(hookname, "pre-mount") == 0)
which = LXCHOOK_PREMOUNT;
else if (strcmp(hook, "mount") == 0)
else if (strcmp(hookname, "mount") == 0)
which = LXCHOOK_MOUNT;
else if (strcmp(hook, "autodev") == 0)
else if (strcmp(hookname, "autodev") == 0)
which = LXCHOOK_AUTODEV;
else if (strcmp(hook, "start") == 0)
else if (strcmp(hookname, "start") == 0)
which = LXCHOOK_START;
else if (strcmp(hook, "stop") == 0)
else if (strcmp(hookname, "stop") == 0)
which = LXCHOOK_STOP;
else if (strcmp(hook, "post-stop") == 0)
else if (strcmp(hookname, "post-stop") == 0)
which = LXCHOOK_POSTSTOP;
else if (strcmp(hook, "clone") == 0)
else if (strcmp(hookname, "clone") == 0)
which = LXCHOOK_CLONE;
else if (strcmp(hook, "destroy") == 0)
else if (strcmp(hookname, "destroy") == 0)
which = LXCHOOK_DESTROY;
else
return -1;
lxc_list_for_each(it, &conf->hooks[which]) {
int ret;
char *hookname = it->elem;
ret = run_script_argv(name, "lxc", hookname, hook, lxcpath, argv);
if (ret)
return ret;
char *hook = it->elem;
ret = run_script_argv(name, conf->hooks_version, "lxc", hook,
hookname, argv);
if (ret < 0)
return -1;
}
return 0;
}
......
......@@ -295,7 +295,11 @@ struct lxc_conf {
struct lxc_rootfs rootfs;
char *ttydir;
int close_all_fds;
struct lxc_list hooks[NUM_LXC_HOOKS];
struct {
unsigned int hooks_version;
struct lxc_list hooks[NUM_LXC_HOOKS];
};
char *lsm_aa_profile;
unsigned int lsm_aa_allow_incomplete;
......@@ -408,7 +412,7 @@ extern struct lxc_conf *current_config;
#endif
extern int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf,
const char *lxcpath, char *argv[]);
char *argv[]);
extern int detect_shared_rootfs(void);
extern struct lxc_conf *lxc_conf_init(void);
extern void lxc_conf_free(struct lxc_conf *conf);
......@@ -453,6 +457,9 @@ extern unsigned long add_required_remount_flags(const char *s, const char *d,
unsigned long flags);
extern int run_script(const char *name, const char *section, const char *script,
...);
extern int run_script_argv(const char *name, unsigned int hook_version,
const char *section, const char *script,
const char *hookname, char **argsin);
extern int in_caplist(int cap, struct lxc_list *caps);
extern int setup_sysctl_parameters(struct lxc_list *sysctls);
extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key);
......
......@@ -92,6 +92,7 @@ lxc_config_define(ephemeral);
lxc_config_define(execute_cmd);
lxc_config_define(group);
lxc_config_define(hooks);
lxc_config_define(hooks_version);
lxc_config_define(idmaps);
lxc_config_define(includefiles);
lxc_config_define(init_cmd);
......@@ -168,11 +169,12 @@ static struct lxc_config_t config[] = {
{ "lxc.hook.destroy", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.mount", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.post-stop", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.start-host", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.pre-start", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.pre-mount", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.pre-start", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.start", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.start-host", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.stop", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.hook.version", false, set_config_hooks_version, get_config_hooks_version, clr_config_hooks_version, },
{ "lxc.hook", false, set_config_hooks, get_config_hooks, clr_config_hooks, },
{ "lxc.idmap", false, set_config_idmaps, get_config_idmaps, clr_config_idmaps, },
{ "lxc.include", false, set_config_includefiles, get_config_includefiles, clr_config_includefiles, },
......@@ -980,6 +982,29 @@ static int set_config_hooks(const char *key, const char *value,
return -1;
}
static int set_config_hooks_version(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
int ret;
unsigned int tmp;
if (lxc_config_value_empty(value))
return clr_config_hooks_version(key, lxc_conf, NULL);
ret = lxc_safe_uint(value, &tmp);
if (ret < 0)
return -1;
if (tmp > 1) {
ERROR("Invalid hook version specified. Currently only 0 "
"(legacy) and 1 are supported");
return -1;
}
lxc_conf->hooks_version = tmp;
return 0;
}
static int set_config_personality(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
......@@ -3154,6 +3179,12 @@ static int get_config_hooks(const char *key, char *retv, int inlen,
return fulllen;
}
static int get_config_hooks_version(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return lxc_get_conf_int(c, retv, inlen, c->hooks_version);
}
static int get_config_net(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
......@@ -3688,6 +3719,14 @@ static inline int clr_config_hooks(const char *key, struct lxc_conf *c,
return lxc_clear_hooks(c, key);
}
static inline int clr_config_hooks_version(const char *key, struct lxc_conf *c,
void *data)
{
/* default to legacy hooks version */
c->hooks_version = 0;
return 0;
}
static inline int clr_config_net(const char *key, struct lxc_conf *c,
void *data)
{
......
......@@ -2746,7 +2746,7 @@ static bool container_destroy(struct lxc_container *c,
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)) {
if (run_lxc_hooks(c->name, "destroy", conf, NULL)) {
ERROR("Failed to execute clone hook for \"%s\"", c->name);
goto out;
}
......@@ -3458,7 +3458,7 @@ static int clone_update_rootfs(struct clone_update_data *data)
SYSERROR("failed to set environment variable for rootfs mount");
}
if (run_lxc_hooks(c->name, "clone", conf, c->get_config_path(c), hookargs)) {
if (run_lxc_hooks(c->name, "clone", conf, hookargs)) {
ERROR("Error executing clone hook for %s", c->name);
storage_put(bdev);
return -1;
......
......@@ -87,13 +87,13 @@ pid_t lxc_clone(int (*fn)(void *), void *arg, int flags)
* linux/fs/namespace.c:mntns_install().
*/
const struct ns_info ns_info[LXC_NS_MAX] = {
[LXC_NS_USER] = {"user", CLONE_NEWUSER, "CLONE_NEWUSER"},
[LXC_NS_MNT] = {"mnt", CLONE_NEWNS, "CLONE_NEWNS"},
[LXC_NS_PID] = {"pid", CLONE_NEWPID, "CLONE_NEWPID"},
[LXC_NS_UTS] = {"uts", CLONE_NEWUTS, "CLONE_NEWUTS"},
[LXC_NS_IPC] = {"ipc", CLONE_NEWIPC, "CLONE_NEWIPC"},
[LXC_NS_NET] = {"net", CLONE_NEWNET, "CLONE_NEWNET"},
[LXC_NS_CGROUP] = {"cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP"}
[LXC_NS_USER] = { "user", CLONE_NEWUSER, "CLONE_NEWUSER", "LXC_USER_NS" },
[LXC_NS_MNT] = { "mnt", CLONE_NEWNS, "CLONE_NEWNS", "LXC_MNT_NS" },
[LXC_NS_PID] = { "pid", CLONE_NEWPID, "CLONE_NEWPID", "LXC_PID_NS" },
[LXC_NS_UTS] = { "uts", CLONE_NEWUTS, "CLONE_NEWUTS", "LXC_UTS_NS" },
[LXC_NS_IPC] = { "ipc", CLONE_NEWIPC, "CLONE_NEWIPC", "LXC_IPC_NS" },
[LXC_NS_NET] = { "net", CLONE_NEWNET, "CLONE_NEWNET", "LXC_NET_NS" },
[LXC_NS_CGROUP] = { "cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP", "LXC_CGROUP_NS" }
};
int lxc_namespace_2_cloneflag(const char *namespace)
......
......@@ -68,6 +68,7 @@ extern const struct ns_info {
const char *proc_name;
int clone_flag;
const char *flag_name;
const char *env_name;
} ns_info[LXC_NS_MAX];
#if defined(__ia64__)
......
......@@ -204,9 +204,17 @@ static int instantiate_veth(struct lxc_handler *handler, struct lxc_netdev *netd
}
if (netdev->upscript) {
err = run_script(handler->name, "net", netdev->upscript, "up",
"veth", veth1, (char*) NULL);
if (err)
char *argv[] = {
"veth",
netdev->link,
veth1,
NULL,
};
err = run_script_argv(handler->name,
handler->conf->hooks_version, "net",
netdev->upscript, "up", argv);
if (err < 0)
goto out_delete;
}
......@@ -254,9 +262,16 @@ static int instantiate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n
}
if (netdev->upscript) {
err = run_script(handler->name, "net", netdev->upscript, "up",
"macvlan", netdev->link, (char*) NULL);
if (err)
char *argv[] = {
"macvlan",
netdev->link,
NULL,
};
err = run_script_argv(handler->name,
handler->conf->hooks_version, "net",
netdev->upscript, "up", argv);
if (err < 0)
goto on_error;
}
......@@ -323,6 +338,13 @@ static int instantiate_vlan(struct lxc_handler *handler, struct lxc_netdev *netd
static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
int ret;
char *argv[] = {
"phys",
netdev->link,
NULL,
};
if (netdev->link[0] == '\0') {
ERROR("No link for physical interface specified");
return -1;
......@@ -346,27 +368,34 @@ static int instantiate_phys(struct lxc_handler *handler, struct lxc_netdev *netd
*/
netdev->priv.phys_attr.ifindex = netdev->ifindex;
if (netdev->upscript) {
int err;
err = run_script(handler->name, "net", netdev->upscript,
"up", "phys", netdev->link, (char*) NULL);
if (err)
return -1;
}
if (!netdev->upscript)
return 0;
ret = run_script_argv(handler->name, handler->conf->hooks_version,
"net", netdev->upscript, "up", argv);
if (ret < 0)
return -1;
return 0;
}
static int instantiate_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
int ret;
char *argv[] = {
"empty",
NULL,
};
netdev->ifindex = 0;
if (netdev->upscript) {
int err;
err = run_script(handler->name, "net", netdev->upscript,
"up", "empty", (char*) NULL);
if (err)
return -1;
}
if (!netdev->upscript)
return 0;
ret = run_script_argv(handler->name, handler->conf->hooks_version,
"net", netdev->upscript, "up", argv);
if (ret < 0)
return -1;
return 0;
}
......@@ -387,34 +416,48 @@ static instantiate_cb netdev_conf[LXC_NET_MAXCONFTYPE + 1] = {
static int shutdown_veth(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
char *veth1;
int err;
int ret;
char *argv[] = {
"veth",
netdev->link,
NULL,
NULL,
};
if (!netdev->downscript)
return 0;
if (netdev->priv.veth_attr.pair[0] != '\0')
veth1 = netdev->priv.veth_attr.pair;
argv[2] = netdev->priv.veth_attr.pair;
else
veth1 = netdev->priv.veth_attr.veth1;
argv[2] = netdev->priv.veth_attr.veth1;
ret = run_script_argv(handler->name,
handler->conf->hooks_version, "net",
netdev->downscript, "down", argv);
if (ret < 0)
return -1;
if (netdev->downscript) {
err = run_script(handler->name, "net", netdev->downscript,
"down", "veth", veth1, (char*) NULL);
if (err)
return -1;
}
return 0;
}
static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
int err;
int ret;
char *argv[] = {
"macvlan",
netdev->link,
NULL,
};
if (!netdev->downscript)
return 0;
ret = run_script_argv(handler->name, handler->conf->hooks_version,
"net", netdev->downscript, "down", argv);
if (ret < 0)
return -1;
if (netdev->downscript) {
err = run_script(handler->name, "net", netdev->downscript,
"down", "macvlan", netdev->link,
(char*) NULL);
if (err)
return -1;
}
return 0;
}
......@@ -425,27 +468,40 @@ static int shutdown_vlan(struct lxc_handler *handler, struct lxc_netdev *netdev)
static int shutdown_phys(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
int err;
int ret;
char *argv[] = {
"phys",
netdev->link,
NULL,
};
if (!netdev->downscript)
return 0;
ret = run_script_argv(handler->name, handler->conf->hooks_version,
"net", netdev->downscript, "down", argv);
if (ret < 0)
return -1;
if (netdev->downscript) {
err = run_script(handler->name, "net", netdev->downscript,
"down", "phys", netdev->link, (char*) NULL);
if (err)
return -1;
}
return 0;
}
static int shutdown_empty(struct lxc_handler *handler, struct lxc_netdev *netdev)
{
int err;
int ret;
char *argv[] = {
"empty",
NULL,
};
if (!netdev->downscript)
return 0;
ret = run_script_argv(handler->name, handler->conf->hooks_version,
"net", netdev->downscript, "down", argv);
if (ret < 0)
return -1;
if (netdev->downscript) {
err = run_script(handler->name, "net", netdev->downscript,
"down", "empty", (char*) NULL);
if (err)
return -1;
}
return 0;
}
......
......@@ -612,6 +612,7 @@ on_error:
int lxc_init(const char *name, struct lxc_handler *handler)
{
int ret;
const char *loglevel;
struct lxc_conf *conf = handler->conf;
......@@ -656,11 +657,18 @@ int lxc_init(const char *name, struct lxc_handler *handler)
loglevel = lxc_log_priority_to_string(lxc_log_get_level());
if (setenv("LXC_LOG_LEVEL", loglevel, 1))
SYSERROR("Failed to set environment variable LXC_LOG_LEVEL=%s", loglevel);
if (conf->hooks_version == 0)
ret = setenv("LXC_HOOK_VERSION", "0", 1);
else
ret = setenv("LXC_HOOK_VERSION", "1", 1);
if (ret < 0)
SYSERROR("Failed to set environment variable LXC_HOOK_VERSION=%u", conf->hooks_version);
/* End of environment variable setup for hooks. */
TRACE("set environment variables");
if (run_lxc_hooks(name, "pre-start", conf, handler->lxcpath, NULL)) {
if (run_lxc_hooks(name, "pre-start", conf, NULL)) {
ERROR("Failed to run lxc.hook.pre-start for container \"%s\".", name);
goto out_aborting;
}
......@@ -708,8 +716,8 @@ out_close_maincmd_fd:
void lxc_fini(const char *name, struct lxc_handler *handler)
{
int i, rc;
pid_t self;
struct lxc_list *cur, *next;
pid_t self = getpid();
char *namespaces[LXC_NS_MAX + 1];
size_t namespace_count = 0;
......@@ -718,16 +726,37 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
*/
lxc_set_state(name, handler, STOPPING);
self = getpid();
for (i = 0; i < LXC_NS_MAX; i++) {
if (handler->nsfd[i] != -1) {
rc = asprintf(&namespaces[namespace_count], "%s:/proc/%d/fd/%d",
ns_info[i].proc_name, self, handler->nsfd[i]);
if (rc == -1) {
SYSERROR("Failed to allocate memory.");
break;
}
++namespace_count;
if (handler->nsfd[i] < 0)
continue;
if (handler->conf->hooks_version == 0)
rc = asprintf(&namespaces[namespace_count],
"%s:/proc/%d/fd/%d", ns_info[i].proc_name,
self, handler->nsfd[i]);
else
rc = asprintf(&namespaces[namespace_count],
"/proc/%d/fd/%d", self, handler->nsfd[i]);
if (rc == -1) {
SYSERROR("Failed to allocate memory.");
break;
}
if (handler->conf->hooks_version == 0) {
namespace_count++;
continue;
}
rc = setenv(ns_info[i].env_name, namespaces[namespace_count], 1);
if (rc < 0)
SYSERROR("Failed to set environment variable %s=%s",
ns_info[i].env_name, namespaces[namespace_count]);
else
TRACE("Set environment variable %s=%s",
ns_info[i].env_name, namespaces[namespace_count]);
namespace_count++;
}
namespaces[namespace_count] = NULL;
......@@ -737,8 +766,10 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
if (!handler->conf->reboot && setenv("LXC_TARGET", "stop", 1))
SYSERROR("Failed to set environment variable: LXC_TARGET=stop.");
if (run_lxc_hooks(name, "stop", handler->conf, handler->lxcpath, namespaces))
ERROR("Failed to run lxc.hook.stop for container \"%s\".", name);
if (handler->conf->hooks_version == 0)
rc = run_lxc_hooks(name, "stop", handler->conf, namespaces);
else
rc = run_lxc_hooks(name, "stop", handler->conf, NULL);
while (namespace_count--)
free(namespaces[namespace_count]);
......@@ -761,7 +792,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
handler->conf->maincmd_fd = -1;
}
if (run_lxc_hooks(name, "post-stop", handler->conf, handler->lxcpath, NULL)) {
if (run_lxc_hooks(name, "post-stop", handler->conf, NULL)) {
ERROR("Failed to run lxc.hook.post-stop for container \"%s\".", name);
if (handler->conf->reboot) {
WARN("Container will be stopped instead of rebooted.");
......@@ -1022,7 +1053,7 @@ static int do_start(void *data)
if (lxc_seccomp_load(handler->conf) != 0)
goto out_warn_father;
if (run_lxc_hooks(handler->name, "start", handler->conf, handler->lxcpath, NULL)) {
if (run_lxc_hooks(handler->name, "start", handler->conf, NULL)) {
ERROR("Failed to run lxc.hook.start for container \"%s\".", handler->name);
goto out_warn_father;
}
......@@ -1482,7 +1513,7 @@ static int lxc_spawn(struct lxc_handler *handler)
SYSERROR("Failed to set environment variable: LXC_PID=%s.", pidstr);
/* Run any host-side start hooks */
if (run_lxc_hooks(name, "start-host", conf, handler->lxcpath, NULL)) {
if (run_lxc_hooks(name, "start-host", conf, NULL)) {
ERROR("Failed to run lxc.hook.start-host for container \"%s\".", name);
return -1;
}
......
......@@ -301,16 +301,16 @@ static int set_get_compare_clear_save_load_network(
int main(int argc, char *argv[])
{
int ret;
struct lxc_container *c;
int fd = -1;
int ret = EXIT_FAILURE;
int fd = -1, fret = EXIT_FAILURE;
char tmpf[] = "lxc-parse-config-file-XXXXXX";
char retval[4096] = {0};
fd = mkstemp(tmpf);
if (fd < 0) {
lxc_error("%s\n", "Could not create temporary file");
exit(ret);
exit(fret);
}
close(fd);
......@@ -1110,10 +1110,23 @@ int main(int argc, char *argv[])
goto non_test_error;
}
ret = EXIT_SUCCESS;
ret = set_get_compare_clear_save_load(c, "lxc.hook.version", "1", tmpf, true);
if (ret < 0) {
lxc_error("%s\n", "lxc.hook.version");
goto non_test_error;
}
ret = set_get_compare_clear_save_load(c, "lxc.hook.version", "2", tmpf, true);
if (ret == 0) {
lxc_error("%s\n", "lxc.hook.version");
goto non_test_error;
}
fret = EXIT_SUCCESS;
non_test_error:
(void)unlink(tmpf);
(void)rmdir(dirname(c->configfile));
lxc_container_put(c);
exit(ret);
exit(fret);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment