[lxc-devel] [lxc/master] init: rework dumb init

brauner on Github lxc-bot at linuxcontainers.org
Tue Oct 10 16:06:54 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 460 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171010/d46be712/attachment.bin>
-------------- next part --------------
From f6d9b7d50ea6919631cf061014600bab357e9488 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 10 Oct 2017 15:53:11 +0200
Subject: [PATCH 1/2] init: become session leader

Before exec()ing we need to become session leader otherwise some shells will
not be able to correctly initialize job control.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/tools/lxc_init.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/lxc/tools/lxc_init.c b/src/lxc/tools/lxc_init.c
index cac1e8c02..3aab2397e 100644
--- a/src/lxc/tools/lxc_init.c
+++ b/src/lxc/tools/lxc_init.c
@@ -77,7 +77,7 @@ static void usage(void) {
 
 int main(int argc, char *argv[])
 {
-	pid_t pid;
+	pid_t pid, sid;
 	int err;
 	char **aargv;
 	sigset_t mask, omask;
@@ -189,6 +189,10 @@ int main(int argc, char *argv[])
 			exit(EXIT_FAILURE);
 		}
 
+		sid = setsid();
+		if (sid < 0)
+			DEBUG("Failed to make child session leader");
+
 		NOTICE("About to exec '%s'", aargv[0]);
 
 		ret = execvp(aargv[0], aargv);

From a6f151a7ce1c67f75663e9f23a1ae6e691443d15 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 10 Oct 2017 16:53:25 +0200
Subject: [PATCH 2/2] init: rework dumb init

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/Makefile.am      |   3 +-
 src/lxc/execute.c        |  27 ++---
 src/lxc/initutils.c      | 106 ++++++++++++++++++
 src/lxc/initutils.h      |  43 ++++++--
 src/lxc/lxccontainer.c   |   1 +
 src/lxc/tools/lxc_init.c | 273 +++++++++++++++++++++++++----------------------
 src/lxc/utils.c          | 129 ----------------------
 src/lxc/utils.h          |   1 -
 8 files changed, 306 insertions(+), 277 deletions(-)

diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
index 9a429b8cf..b71992d75 100644
--- a/src/lxc/Makefile.am
+++ b/src/lxc/Makefile.am
@@ -298,7 +298,8 @@ endif
 if HAVE_STATIC_LIBCAP
 sbin_PROGRAMS += init.lxc.static
 
-init_lxc_static_SOURCES = tools/lxc_init.c error.c log.c initutils.c caps.c
+init_lxc_static_SOURCES = tools/lxc_init.c error.c log.c initutils.c caps.c \
+			  arguments.c
 
 if !HAVE_GETLINE
 if HAVE_FGETLN
diff --git a/src/lxc/execute.c b/src/lxc/execute.c
index ddfd9fadb..2f7f13747 100644
--- a/src/lxc/execute.c
+++ b/src/lxc/execute.c
@@ -64,33 +64,36 @@ static int execute_start(struct lxc_handler *handler, void* data)
 
 	initpath = choose_init(NULL);
 	if (!initpath) {
-		ERROR("Failed to find an lxc-init or init.lxc");
+		ERROR("Failed to find an init.lxc or init.lxc.static");
 		goto out2;
 	}
 	argv[i++] = initpath;
+
+	argv[i++] = "-n";
+	argv[i++] = (char *)handler->name;
+
+	if (lxc_log_has_valid_level()) {
+		argv[i++] = "-l";
+		argv[i++] = (char *)lxc_log_priority_to_string(lxc_log_get_level());
+	}
+
 	if (my_args->quiet)
 		argv[i++] = "--quiet";
+
 	if (!handler->conf->rootfs.path) {
-		argv[i++] = "--name";
-		argv[i++] = (char *)handler->name;
-		argv[i++] = "--lxcpath";
+		argv[i++] = "-P";
 		argv[i++] = (char *)handler->lxcpath;
-
-		if (lxc_log_has_valid_level()) {
-			argv[i++] = "--logpriority";
-			argv[i++] = (char *)
-				lxc_log_priority_to_string(lxc_log_get_level());
-		}
 	}
+
 	argv[i++] = "--";
 	for (j = 0; j < argc; j++)
 		argv[i++] = my_args->argv[j];
 	argv[i++] = NULL;
 
-	NOTICE("exec'ing '%s'", my_args->argv[0]);
+	NOTICE("Exec'ing \"%s\"", my_args->argv[0]);
 
 	execvp(argv[0], argv);
-	SYSERROR("failed to exec %s", argv[0]);
+	SYSERROR("Failed to exec %s", argv[0]);
 	free(initpath);
 out2:
 	free(argv);
diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c
index c190d6d50..12c33630b 100644
--- a/src/lxc/initutils.c
+++ b/src/lxc/initutils.c
@@ -21,6 +21,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <sys/prctl.h>
+
 #include "initutils.h"
 #include "log.h"
 
@@ -296,3 +298,107 @@ FILE *fopen_cloexec(const char *path, const char *mode)
 	errno = saved_errno;
 	return ret;
 }
+
+/*
+ * Sets the process title to the specified title. Note that this may fail if
+ * the kernel doesn't support PR_SET_MM_MAP (kernels <3.18).
+ */
+int setproctitle(char *title)
+{
+	static char *proctitle = NULL;
+	char buf[2048], *tmp;
+	FILE *f;
+	int i, len, ret = 0;
+
+	/* We don't really need to know all of this stuff, but unfortunately
+	 * PR_SET_MM_MAP requires us to set it all at once, so we have to
+	 * figure it out anyway.
+	 */
+	unsigned long start_data, end_data, start_brk, start_code, end_code,
+			start_stack, arg_start, arg_end, env_start, env_end,
+			brk_val;
+	struct prctl_mm_map prctl_map;
+
+	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 25 fields, column 26-28 are start_code, end_code,
+	 * and start_stack */
+	tmp = strchr(buf, ' ');
+	for (i = 0; i < 24; i++) {
+		if (!tmp)
+			return -1;
+		tmp = strchr(tmp+1, ' ');
+	}
+	if (!tmp)
+		return -1;
+
+	i = sscanf(tmp, "%lu %lu %lu", &start_code, &end_code, &start_stack);
+	if (i != 3)
+		return -1;
+
+	/* Skip the next 19 fields, column 45-51 are start_data to arg_end */
+	for (i = 0; i < 19; i++) {
+		if (!tmp)
+			return -1;
+		tmp = strchr(tmp+1, ' ');
+	}
+
+	if (!tmp)
+		return -1;
+
+	i = sscanf(tmp, "%lu %lu %lu %*u %*u %lu %lu",
+		&start_data,
+		&end_data,
+		&start_brk,
+		&env_start,
+		&env_end);
+	if (i != 5)
+		return -1;
+
+	/* Include the null byte here, because in the calculations below we
+	 * want to have room for it. */
+	len = strlen(title) + 1;
+
+	proctitle = realloc(proctitle, len);
+	if (!proctitle)
+		return -1;
+
+	arg_start = (unsigned long) proctitle;
+	arg_end = arg_start + len;
+
+	brk_val = syscall(__NR_brk, 0);
+
+	prctl_map = (struct prctl_mm_map) {
+		.start_code = start_code,
+		.end_code = end_code,
+		.start_stack = start_stack,
+		.start_data = start_data,
+		.end_data = end_data,
+		.start_brk = start_brk,
+		.brk = brk_val,
+		.arg_start = arg_start,
+		.arg_end = arg_end,
+		.env_start = env_start,
+		.env_end = env_end,
+		.auxv = NULL,
+		.auxv_size = 0,
+		.exe_fd = -1,
+	};
+
+	ret = prctl(PR_SET_MM, PR_SET_MM_MAP, (long) &prctl_map, sizeof(prctl_map), 0);
+	if (ret == 0)
+		strcpy((char*)arg_start, title);
+	else
+		INFO("setting cmdline failed - %s", strerror(errno));
+
+	return ret;
+}
diff --git a/src/lxc/initutils.h b/src/lxc/initutils.h
index c021fd617..ec44554e3 100644
--- a/src/lxc/initutils.h
+++ b/src/lxc/initutils.h
@@ -25,17 +25,16 @@
 #define __LXC_INITUTILS_H
 
 #include <errno.h>
-#include <stdio.h>
+#include <fcntl.h>
+#include <inttypes.h>
 #include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mount.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-
 
 #include "config.h"
 
@@ -44,11 +43,37 @@
 #define DEFAULT_ZFSROOT "lxc"
 #define DEFAULT_RBDPOOL "lxc"
 
+#ifndef PR_SET_MM
+#define PR_SET_MM 35
+#endif
+
+#ifndef PR_SET_MM_MAP
+#define PR_SET_MM_MAP 14
+
+struct prctl_mm_map {
+	uint64_t start_code;
+	uint64_t end_code;
+	uint64_t start_data;
+	uint64_t end_data;
+	uint64_t start_brk;
+	uint64_t brk;
+	uint64_t start_stack;
+	uint64_t arg_start;
+	uint64_t arg_end;
+	uint64_t env_start;
+	uint64_t env_end;
+	uint64_t *auxv;
+	uint32_t auxv_size;
+	uint32_t exe_fd;
+};
+#endif
+
 extern void lxc_setup_fs(void);
 extern const char *lxc_global_config_value(const char *option_name);
 
 /* open a file with O_CLOEXEC */
 extern void remove_trailing_slashes(char *p);
-FILE *fopen_cloexec(const char *path, const char *mode);
+extern FILE *fopen_cloexec(const char *path, const char *mode);
+extern int setproctitle(char *title);
 
 #endif /* __LXC_INITUTILS_H */
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 5e8ad00f9..fa144c55b 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -50,6 +50,7 @@
 #include "confile_utils.h"
 #include "console.h"
 #include "criu.h"
+#include "initutils.h"
 #include "log.h"
 #include "lxc.h"
 #include "lxccontainer.h"
diff --git a/src/lxc/tools/lxc_init.c b/src/lxc/tools/lxc_init.c
index 3aab2397e..56cc7e084 100644
--- a/src/lxc/tools/lxc_init.c
+++ b/src/lxc/tools/lxc_init.c
@@ -22,35 +22,27 @@
  */
 
 #define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
 #include <errno.h>
-#include <signal.h>
+#include <getopt.h>
 #include <libgen.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
-#include <getopt.h>
 
 #include <lxc/lxccontainer.h>
 
-#include "log.h"
+#include "arguments.h"
 #include "error.h"
 #include "initutils.h"
+#include "log.h"
 
 lxc_log_define(lxc_init, lxc);
 
-static int quiet;
-
-static const struct option options[] = {
-	{ "name",        required_argument, NULL, 'n' },
-	{ "logpriority", required_argument, NULL, 'l' },
-	{ "quiet",       no_argument,       NULL, 'q' },
-	{ "lxcpath",     required_argument, NULL, 'P' },
-	{ 0, 0, 0, 0 },
-};
-
 static sig_atomic_t was_interrupted = 0;
 
 static void interrupt_handler(int sig)
@@ -59,114 +51,124 @@ static void interrupt_handler(int sig)
 		was_interrupted = sig;
 }
 
-static void usage(void) {
-	fprintf(stderr, "Usage: lxc-init [OPTION]...\n\n"
-		"Common options :\n"
-		"  -n, --name=NAME          NAME of the container\n"
-		"  -l, --logpriority=LEVEL  Set log priority to LEVEL\n"
-		"  -q, --quiet              Don't produce any output\n"
-		"  -P, --lxcpath=PATH       Use specified container path\n"
-		"  -?, --help               Give this help list\n"
-		"\n"
-		"Mandatory or optional arguments to long options are also mandatory or optional\n"
-		"for any corresponding short options.\n"
-		"\n"
-		"NOTE: lxc-init is intended for use by lxc internally\n"
-		"      and does not need to be run by hand\n\n");
+static const struct option my_longopts[] = {
+	LXC_COMMON_OPTIONS
+};
+
+static int my_parser(struct lxc_arguments *args, int c, char *arg)
+{
+	return 0;
 }
 
+static struct lxc_arguments my_args = {
+	.progname = "lxc-init",
+	.help     = "\
+--name=NAME -- COMMAND\n\
+\n\
+lxc-init start a COMMAND as PID 2 inside a container\n\
+\n\
+Options :\n\
+  -n, --name=NAME        NAME of the container\n\
+",
+	.options   = my_longopts,
+	.parser    = my_parser,
+};
+
 int main(int argc, char *argv[])
 {
+	int i, ret;
 	pid_t pid, sid;
-	int err;
-	char **aargv;
-	sigset_t mask, omask;
 	struct sigaction act;
-	int i, have_status = 0, shutdown = 0;
-	int opt;
-	char *lxcpath = NULL, *name = NULL, *logpriority = NULL;
 	struct lxc_log log;
+	sigset_t mask, omask;
+	int have_status = 0, shutdown = 0;
 
-	while ((opt = getopt_long(argc, argv, "n:l:qP:", options, NULL)) != -1) {
-		switch(opt) {
-		case 'n':
-			name = optarg;
-			break;
-		case 'l':
-			logpriority = optarg;
-			break;
-		case 'q':
-			quiet = 1;
-			break;
-		case 'P':
-			lxcpath = optarg;
-			break;
-		default: /* '?' */
-			usage();
-			exit(EXIT_FAILURE);
-		}
-	}
+	if (lxc_arguments_parse(&my_args, argc, argv))
+		exit(EXIT_FAILURE);
 
-	log.name = name;
-	log.file = name ? NULL : "none";
-	log.level = logpriority;
-	log.prefix = basename(argv[0]);
-	log.quiet = quiet;
-	log.lxcpath = lxcpath;
+	log.name = my_args.name;
+	log.file = my_args.log_file;
+	log.level = my_args.log_priority;
+	log.prefix = my_args.progname;
+	log.quiet = my_args.quiet;
+	log.lxcpath = my_args.lxcpath[0];
 
-	err = lxc_log_init(&log);
-	if (err < 0)
+	ret = lxc_log_init(&log);
+	if (ret < 0)
 		exit(EXIT_FAILURE);
 	lxc_log_options_no_override();
 
-	if (!argv[optind]) {
-		ERROR("Missing command to launch");
+	if (!my_args.argc) {
+		ERROR("Please specify a command to execute");
 		exit(EXIT_FAILURE);
 	}
 
-	aargv = &argv[optind];
-
-	/*
-	 * mask all the signals so we are safe to install a
-	 * signal handler and to fork
+	/* Mask all the signals so we are safe to install a signal handler and
+	 * to fork.
 	 */
-	if (sigfillset(&mask) ||
-	    sigdelset(&mask, SIGILL) ||
-	    sigdelset(&mask, SIGSEGV) ||
-	    sigdelset(&mask, SIGBUS) ||
-	    sigprocmask(SIG_SETMASK, &mask, &omask)) {
-		SYSERROR("Failed to set signal mask");
+	ret = sigfillset(&mask);
+	if (ret < 0)
 		exit(EXIT_FAILURE);
-	}
 
-	if (sigfillset(&act.sa_mask) ||
-	    sigdelset(&act.sa_mask, SIGILL) ||
-	    sigdelset(&act.sa_mask, SIGSEGV) ||
-	    sigdelset(&act.sa_mask, SIGBUS) ||
-	    sigdelset(&act.sa_mask, SIGSTOP) ||
-	    sigdelset(&act.sa_mask, SIGKILL)) {
-		ERROR("Failed to set signal");
+	ret = sigdelset(&mask, SIGILL);
+	if (ret < 0)
 		exit(EXIT_FAILURE);
-	}
+
+	ret = sigdelset(&mask, SIGSEGV);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigdelset(&mask, SIGBUS);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigprocmask(SIG_SETMASK, &mask, &omask);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigfillset(&act.sa_mask);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigdelset(&act.sa_mask, SIGILL);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigdelset(&act.sa_mask, SIGSEGV);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigdelset(&act.sa_mask, SIGBUS);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigdelset(&act.sa_mask, SIGSTOP);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigdelset(&act.sa_mask, SIGKILL);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
 	act.sa_flags = 0;
 	act.sa_handler = interrupt_handler;
 
 	for (i = 1; i < NSIG; i++) {
-		/* Exclude some signals: ILL, SEGV and BUS are likely to
-		 * reveal a bug and we want a core. STOP and KILL cannot be
-		 * handled anyway: they're here for documentation. 32 and 33
-		 * are not defined.
+		/* Exclude some signals: ILL, SEGV and BUS are likely to reveal
+		 * a bug and we want a core. STOP and KILL cannot be handled
+		 * anyway: they're here for documentation. 32 and 33 are not
+		 * defined.
 		 */
-		if (i == SIGILL ||
-		    i == SIGSEGV ||
-		    i == SIGBUS ||
-		    i == SIGSTOP ||
-		    i == SIGKILL ||
-		    i == 32 || i == 33)
+		if (i == SIGILL || i == SIGSEGV || i == SIGBUS ||
+		    i == SIGSTOP || i == SIGKILL || i == 32 || i == 33)
 			continue;
 
-		if (sigaction(i, &act, NULL) && errno != EINVAL) {
-			SYSERROR("Failed to sigaction");
+		ret = sigaction(i, &act, NULL);
+		if (ret < 0) {
+			if (errno == EINVAL)
+				continue;
+
+			SYSERROR("Failed to change signal action");
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -178,13 +180,19 @@ int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 
 	if (!pid) {
-		int ret;
-
 		/* restore default signal handlers */
-		for (i = 1; i < NSIG; i++)
-			signal(i, SIG_DFL);
+		for (i = 1; i < NSIG; i++) {
+			sighandler_t sigerr;
+			sigerr = signal(i, SIG_DFL);
+			if (sigerr == SIG_ERR) {
+				DEBUG("%s - Failed to reset to default action "
+				      "for signal \"%d\": %d", strerror(errno),
+				      i, pid);
+			}
+		}
 
-		if (sigprocmask(SIG_SETMASK, &omask, NULL)) {
+		ret = sigprocmask(SIG_SETMASK, &omask, NULL);
+		if (ret < 0) {
 			SYSERROR("Failed to set signal mask");
 			exit(EXIT_FAILURE);
 		}
@@ -193,25 +201,31 @@ int main(int argc, char *argv[])
 		if (sid < 0)
 			DEBUG("Failed to make child session leader");
 
-		NOTICE("About to exec '%s'", aargv[0]);
+		NOTICE("Exec'ing \"%s\"", my_args.argv[0]);
 
-		ret = execvp(aargv[0], aargv);
-		ERROR("Failed to exec: '%s' : %s", aargv[0], strerror(errno));
+		ret = execvp(my_args.argv[0], my_args.argv);
+		ERROR("%s - Failed to exec \"%s\"", strerror(errno), my_args.argv[0]);
 		exit(ret);
 	}
 
-	/* let's process the signals now */
-	if (sigdelset(&omask, SIGALRM) ||
-	    sigprocmask(SIG_SETMASK, &omask, NULL)) {
+	INFO("Attempting to set proc title to \"init\"");
+	setproctitle("init");
+
+	/* Let's process the signals now. */
+	ret = sigdelset(&omask, SIGALRM);
+	if (ret < 0)
+		exit(EXIT_FAILURE);
+
+	ret = sigprocmask(SIG_SETMASK, &omask, NULL);
+	if (ret < 0) {
 		SYSERROR("Failed to set signal mask");
 		exit(EXIT_FAILURE);
 	}
 
-	/* no need of other inherited fds but stderr */
-	close(fileno(stdin));
-	close(fileno(stdout));
+	/* No need of other inherited fds but stderr. */
+	close(STDIN_FILENO);
+	close(STDOUT_FILENO);
 
-	err = EXIT_SUCCESS;
 	for (;;) {
 		int status;
 		pid_t waited_pid;
@@ -223,47 +237,56 @@ int main(int argc, char *argv[])
 		case SIGTERM:
 			if (!shutdown) {
 				shutdown = 1;
-				kill(-1, SIGTERM);
+				ret = kill(-1, SIGTERM);
+				if (ret < 0)
+					DEBUG("%s - Failed to send SIGTERM to "
+					      "all children", strerror(errno));
 				alarm(1);
 			}
 			break;
 		case SIGALRM:
-			kill(-1, SIGKILL);
+			ret = kill(-1, SIGKILL);
+			if (ret < 0)
+				DEBUG("%s - Failed to send SIGKILL to all "
+				      "children", strerror(errno));
 			break;
 		default:
-			kill(pid, was_interrupted);
+			ret = kill(pid, was_interrupted);
+			if (ret < 0)
+				DEBUG("%s - Failed to send signal \"%d\" to "
+				      "%d", strerror(errno), was_interrupted, pid);
 			break;
 		}
+		ret = EXIT_SUCCESS;
 
 		was_interrupted = 0;
 		waited_pid = wait(&status);
 		if (waited_pid < 0) {
 			if (errno == ECHILD)
 				goto out;
+
 			if (errno == EINTR)
 				continue;
 
-			ERROR("Failed to wait child : %s",
-			      strerror(errno));
+			ERROR("%s - Failed to wait on child %d",
+			      strerror(errno), pid);
 			goto out;
 		}
 
-		/* reset timer each time a process exited */
+		/* Reset timer each time a process exited. */
 		if (shutdown)
 			alarm(1);
 
-		/*
-		 * keep the exit code of started application
-		 * (not wrapped pid) and continue to wait for
-		 * the end of the orphan group.
+		/* Keep the exit code of the started application (not wrapped
+		 * pid) and continue to wait for the end of the orphan group.
 		 */
 		if (waited_pid == pid && !have_status) {
-			err = lxc_error_set_and_log(waited_pid, status);
+			ret = lxc_error_set_and_log(waited_pid, status);
 			have_status = 1;
 		}
 	}
 out:
-	if (err < 0)
+	if (ret < 0)
 		exit(EXIT_FAILURE);
-	exit(err);
+	exit(ret);
 }
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index c9a60979a..4c886cadd 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -49,31 +49,6 @@
 #include "namespace.h"
 #include "utils.h"
 
-#ifndef PR_SET_MM
-#define PR_SET_MM 35
-#endif
-
-#ifndef PR_SET_MM_MAP
-#define PR_SET_MM_MAP 14
-
-struct prctl_mm_map {
-        uint64_t   start_code;
-        uint64_t   end_code;
-        uint64_t   start_data;
-        uint64_t   end_data;
-        uint64_t   start_brk;
-        uint64_t   brk;
-        uint64_t   start_stack;
-        uint64_t   arg_start;
-        uint64_t   arg_end;
-        uint64_t   env_start;
-        uint64_t   env_end;
-        uint64_t   *auxv;
-        uint32_t   auxv_size;
-        uint32_t   exe_fd;
-};
-#endif
-
 #ifndef O_PATH
 #define O_PATH      010000000
 #endif
@@ -1439,110 +1414,6 @@ char *get_template_path(const char *t)
 }
 
 /*
- * Sets the process title to the specified title. Note that this may fail if
- * the kernel doesn't support PR_SET_MM_MAP (kernels <3.18).
- */
-int setproctitle(char *title)
-{
-	static char *proctitle = NULL;
-	char buf[2048], *tmp;
-	FILE *f;
-	int i, len, ret = 0;
-
-	/* We don't really need to know all of this stuff, but unfortunately
-	 * PR_SET_MM_MAP requires us to set it all at once, so we have to
-	 * figure it out anyway.
-	 */
-	unsigned long start_data, end_data, start_brk, start_code, end_code,
-			start_stack, arg_start, arg_end, env_start, env_end,
-			brk_val;
-	struct prctl_mm_map prctl_map;
-
-	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 25 fields, column 26-28 are start_code, end_code,
-	 * and start_stack */
-	tmp = strchr(buf, ' ');
-	for (i = 0; i < 24; i++) {
-		if (!tmp)
-			return -1;
-		tmp = strchr(tmp+1, ' ');
-	}
-	if (!tmp)
-		return -1;
-
-	i = sscanf(tmp, "%lu %lu %lu", &start_code, &end_code, &start_stack);
-	if (i != 3)
-		return -1;
-
-	/* Skip the next 19 fields, column 45-51 are start_data to arg_end */
-	for (i = 0; i < 19; i++) {
-		if (!tmp)
-			return -1;
-		tmp = strchr(tmp+1, ' ');
-	}
-
-	if (!tmp)
-		return -1;
-
-	i = sscanf(tmp, "%lu %lu %lu %*u %*u %lu %lu",
-		&start_data,
-		&end_data,
-		&start_brk,
-		&env_start,
-		&env_end);
-	if (i != 5)
-		return -1;
-
-	/* Include the null byte here, because in the calculations below we
-	 * want to have room for it. */
-	len = strlen(title) + 1;
-
-	proctitle = realloc(proctitle, len);
-	if (!proctitle)
-		return -1;
-
-	arg_start = (unsigned long) proctitle;
-	arg_end = arg_start + len;
-
-	brk_val = syscall(__NR_brk, 0);
-
-	prctl_map = (struct prctl_mm_map) {
-		.start_code = start_code,
-		.end_code = end_code,
-		.start_stack = start_stack,
-		.start_data = start_data,
-		.end_data = end_data,
-		.start_brk = start_brk,
-		.brk = brk_val,
-		.arg_start = arg_start,
-		.arg_end = arg_end,
-		.env_start = env_start,
-		.env_end = env_end,
-		.auxv = NULL,
-		.auxv_size = 0,
-		.exe_fd = -1,
-	};
-
-	ret = prctl(PR_SET_MM, PR_SET_MM_MAP, (long) &prctl_map, sizeof(prctl_map), 0);
-	if (ret == 0)
-		strcpy((char*)arg_start, title);
-	else
-		INFO("setting cmdline failed - %s", strerror(errno));
-
-	return ret;
-}
-
-/*
  * @path:    a pathname where / replaced with '\0'.
  * @offsetp: pointer to int showing which path segment was last seen.
  *           Updated on return to reflect the next segment.
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 833ec4416..41c43827a 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -340,7 +340,6 @@ extern int print_to_file(const char *file, const char *content);
 extern bool switch_to_ns(pid_t pid, const char *ns);
 extern int is_dir(const char *path);
 extern char *get_template_path(const char *t);
-extern int setproctitle(char *title);
 extern int safe_mount(const char *src, const char *dest, const char *fstype,
 		      unsigned long flags, const void *data,
 		      const char *rootfs);


More information about the lxc-devel mailing list