From: Christian Brauner Date: Sun, 10 Dec 2017 11:54:00 +0000 (+0100) Subject: conf: execute hooks based on lxc.hooks.version X-Git-Tag: lxc-3.0.0.beta1~111^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f60c2f749277b0dd08e850ac3dc3b38c7790e26;p=thirdparty%2Flxc.git conf: execute hooks based on lxc.hooks.version Unblocks #2013. Unblocks #2015. Closes #1766. Signed-off-by: Christian Brauner --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 0da760933..8e31275f6 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -308,84 +308,114 @@ 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) +static int run_script_argv(const char *name, unsigned int hook_version, + const char *section, const char *script, + const char *hookname, const char *lxcpath, + char **argsin) { - int ret, i; + int buf_pos, i, ret; char *buffer; - size_t size = 0; + size_t size = 0, size_legacy_args = 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++; + + size_legacy_args += strlen(section); + size_legacy_args++; + + size_legacy_args += strlen(name); + size_legacy_args++; + + size_legacy_args += strlen(hookname); + size_legacy_args++; 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 += size_legacy_args; + + 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); } 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); @@ -3261,41 +3291,45 @@ int lxc_setup(struct lxc_handler *handler) return 0; } -int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf, +int run_lxc_hooks(const char *name, char *hookname, struct lxc_conf *conf, const char *lxcpath, 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, lxcpath, argv); + if (ret < 0) + return -1; } + return 0; }