[lxc-devel] [PATCH] set the monitor process title to something useful
Serge Hallyn
serge.hallyn at ubuntu.com
Fri Jan 30 14:10:29 UTC 2015
Quoting Tycho Andersen (tycho.andersen at canonical.com):
> On Fri, Jan 30, 2015 at 01:38:59PM +0000, Serge Hallyn wrote:
> > Quoting Tycho Andersen (tycho.andersen at canonical.com):
> > > Instead of having a parent process that's called whatever the caller of the
> > > library is called, we instead set it to "[lxc monitor] <lxcpath> <container>"
> > >
> > > Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
> > > ---
> > > src/lxc/lxccontainer.c | 10 +++++++++
> > > src/lxc/utils.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++
> > > src/lxc/utils.h | 1 +
> > > 3 files changed, 72 insertions(+)
> > >
> > > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > > index 4da1627..1176a6f 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,15 @@ 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 93de1c3..f517ee6 100644
> > > --- a/src/lxc/utils.c
> > > +++ b/src/lxc/utils.c
> > > @@ -39,6 +39,7 @@
> > > #include <sys/types.h>
> > > #include <sys/wait.h>
> > > #include <assert.h>
> > > +#include <sys/prctl.h>
> > >
> > > #include "utils.h"
> > > #include "log.h"
> > > @@ -1540,3 +1541,63 @@ 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++)
> > > + tmp = strchr(tmp+1, ' ');
> >
> > Could you add a check here at each step for tmp != NULL? Or just
> >
> > for (i = 0; i < 46 && tmp; i++)
> > tmp = strchr(tmp+1, ' ');
> > if (!tmp)
> > return -1;
>
> Yep, here's a few other changes as well.
>
> Tycho
>
>
> From 6af924ded6e4ca9f0826a50c73cfcc8715159b18 Mon Sep 17 00:00:00 2001
> From: Tycho Andersen <tycho.andersen at canonical.com>
> Date: Fri, 30 Jan 2015 14:14:51 +0100
> Subject: [PATCH] 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] <lxcpath> <container>"
>
> Closes #180
>
> v2: check for null in tok for loop, only truncate environment when necessary
>
> Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
> ---
> src/lxc/lxccontainer.c | 9 +++++++
> src/lxc/utils.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++
> src/lxc/utils.h | 1 +
> 3 files changed, 77 insertions(+)
>
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 4da1627..e02ee93 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 93de1c3..9acf7e6 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -39,6 +39,7 @@
> #include <sys/types.h>
> #include <sys/wait.h>
> #include <assert.h>
> +#include <sys/prctl.h>
>
> #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 b23cd8e..cc18906 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);
> --
> 2.1.0
>
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
More information about the lxc-devel
mailing list