From: Tycho Andersen Date: Fri, 30 Jan 2015 13:59:13 +0000 (+0100) Subject: set the monitor process title to something useful X-Git-Tag: lxc-1.1.1~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=807b8d68b64fa6194c45b0516651bd60d488138f;p=thirdparty%2Flxc.git set the monitor process title to something useful Instead of having a parent process that's called whatever the caller of the library is called, we instead set it to "[lxc monitor] " Closes #180 v2: check for null in tok for loop, only truncate environment when necessary Signed-off-by: Tycho Andersen Acked-by: Serge E. Hallyn --- diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 4da1627c3..e02ee93e9 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -598,6 +598,7 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv * while container is running... */ if (daemonize) { + char title[2048]; lxc_monitord_spawn(c->config_path); pid_t pid = fork(); @@ -612,6 +613,14 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv return wait_on_daemonized_start(c, pid); } + /* We don't really care if this doesn't print all the + * characters; all that it means is that the proctitle will be + * ugly. Similarly, we also don't care if setproctitle() + * fails. */ + snprintf(title, sizeof(title), "[lxc monitor] %s %s", c->config_path, c->name); + INFO("Attempting to set proc title to %s", title); + setproctitle(title); + /* second fork to be reparented by init */ pid = fork(); if (pid < 0) { diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 93de1c350..9acf7e672 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "utils.h" #include "log.h" @@ -1540,3 +1541,69 @@ char *get_template_path(const char *t) return tpath; } + +/* + * Sets the process title to the specified title. Note: + * 1. this function requires root to succeed + * 2. it clears /proc/self/environ + * 3. it may not succed (e.g. if title is longer than /proc/self/environ + + * the original title) + */ +int setproctitle(char *title) +{ + char buf[2048], *tmp; + FILE *f; + int i, len, ret = 0; + unsigned long arg_start, arg_end, env_start, env_end; + + f = fopen_cloexec("/proc/self/stat", "r"); + if (!f) { + return -1; + } + + tmp = fgets(buf, sizeof(buf), f); + fclose(f); + if (!tmp) { + return -1; + } + + /* Skip the first 47 fields, column 48-51 are ARG_START and + * ARG_END. */ + tmp = strchr(buf, ' '); + for (i = 0; i < 46; i++) { + if (!tmp) + return -1; + tmp = strchr(tmp+1, ' '); + } + + i = sscanf(tmp, "%lu %lu %lu %lu", &arg_start, &arg_end, &env_start, &env_end); + if (i != 4) { + return -1; + } + + /* We're truncating the environment, so we should use at most the + * length of the argument + environment for the title. */ + len = strlen(title); + if (len > env_end - arg_start) { + arg_end = env_end; + len = env_end - arg_start; + } else { + /* Only truncate the environment if we're actually going to + * overwrite part of it. */ + if (len >= arg_end - arg_start) { + env_start = env_end; + } + arg_end = arg_start + len; + } + + + /* memcpy instead of strcpy since this isn't null terminated */ + memcpy((void*)arg_start, title, len); + + ret |= prctl(PR_SET_MM, PR_SET_MM_ARG_START, (long)arg_start, 0, 0); + ret |= prctl(PR_SET_MM, PR_SET_MM_ARG_END, (long)arg_end, 0, 0); + ret |= prctl(PR_SET_MM, PR_SET_MM_ENV_START, (long)env_start, 0, 0); + ret |= prctl(PR_SET_MM, PR_SET_MM_ENV_END, (long)env_end, 0, 0); + + return ret; +} diff --git a/src/lxc/utils.h b/src/lxc/utils.h index b23cd8eea..cc1890604 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -286,3 +286,4 @@ int print_to_file(const char *file, const char *content); bool switch_to_ns(pid_t pid, const char *ns); int is_dir(const char *path); char *get_template_path(const char *t); +int setproctitle(char *title);