[lxc-devel] [lxc/master] tree-wide: use _exit() in child

brauner on Github lxc-bot at linuxcontainers.org
Sat Dec 16 12:10:22 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 549 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171216/67f677c8/attachment.bin>
-------------- next part --------------
From d5a523eb709b11c2f9074328acd89ebca63aa87c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Sat, 16 Dec 2017 12:10:14 +0100
Subject: [PATCH] tree-wide: use _exit() in child

- When fork()ing we shouldn't run any exit() handlers as they can mess with the
  parent state.
- exit() is not thread-safe so replace it with _exit() inside library
  codepaths.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgmanager.c     |  42 +++++++--------
 src/lxc/criu.c                  |  20 +++----
 src/lxc/lxccontainer.c          | 117 ++++++++++++++++++++--------------------
 src/lxc/lxclock.c               |   4 +-
 src/lxc/monitor.c               |   8 +--
 src/lxc/network.c               |  18 +++----
 src/lxc/storage/nbd.c           |  12 ++---
 src/lxc/storage/storage_utils.c |  20 +++----
 src/lxc/tools/lxc_checkpoint.c  |   2 +-
 src/lxc/tools/lxc_create.c      |   2 +-
 src/lxc/tools/lxc_device.c      |  16 +++---
 src/lxc/tools/lxc_unshare.c     |   6 +--
 src/lxc/tools/lxc_usernsexec.c  |   6 +--
 src/lxc/utils.c                 |  16 +++---
 14 files changed, 144 insertions(+), 145 deletions(-)

diff --git a/src/lxc/cgroups/cgmanager.c b/src/lxc/cgroups/cgmanager.c
index e8ef8c66c..54a623a32 100644
--- a/src/lxc/cgroups/cgmanager.c
+++ b/src/lxc/cgroups/cgmanager.c
@@ -79,7 +79,7 @@ static void lock_mutex(pthread_mutex_t *l)
 
 	if ((ret = pthread_mutex_lock(l)) != 0) {
 		fprintf(stderr, "pthread_mutex_lock returned:%d %s\n", ret, strerror(ret));
-		exit(1);
+		_exit(1);
 	}
 }
 
@@ -90,7 +90,7 @@ static void unlock_mutex(pthread_mutex_t *l)
 	if ((ret = pthread_mutex_unlock(l)) != 0) {
 		fprintf(stderr, "%s: pthread_mutex_unlock returned:%d %s\n",
 				__FILE__, ret, strerror(ret));
-		exit(1);
+		_exit(1);
 	}
 }
 
@@ -869,7 +869,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &len, sizeof(len));
 		if (ret != sizeof(len))
 			WARN("Failed to warn cgm_get of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	*key = '\0';
 
@@ -878,7 +878,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &len, sizeof(len));
 		if (ret != sizeof(len))
 			WARN("Failed to warn cgm_get of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	cgroup = try_get_abs_cgroup(name, lxcpath, controller);
 	if (!cgroup) {
@@ -886,7 +886,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &len, sizeof(len));
 		if (ret != sizeof(len))
 			WARN("Failed to warn cgm_get of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	cglast = strrchr(cgroup, '/');
 	if (!cglast) {
@@ -895,7 +895,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &len, sizeof(len));
 		if (ret != sizeof(len))
 			WARN("Failed to warn cgm_get of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	*cglast = '\0';
 	if (!lxc_cgmanager_enter(getpid(), controller, cgroup, abs_cgroup_supported())) {
@@ -905,7 +905,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
 			WARN("Failed to warn cgm_get of error; parent may hang");
 		cgm_dbus_disconnect();
 		free_abs_cgroup(cgroup);
-		exit(1);
+		_exit(1);
 	}
 	if (cgmanager_get_value_sync(NULL, cgroup_manager, controller, cglast+1, filename, &result) != 0) {
 		NihError *nerr;
@@ -916,7 +916,7 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &len, sizeof(len));
 		if (ret != sizeof(len))
 			WARN("Failed to warn cgm_get of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	free_abs_cgroup(cgroup);
 	cgm_dbus_disconnect();
@@ -924,15 +924,15 @@ static void do_cgm_get(const char *name, const char *lxcpath, const char *filena
 	ret = write(outp, &len, sizeof(len));
 	if (ret != sizeof(len)) {
 		WARN("Failed to send length to parent");
-		exit(1);
+		_exit(1);
 	}
 	if (!len || !sendvalue) {
-		exit(0);
+		_exit(0);
 	}
 	ret = write(outp, result, len);
 	if (ret < 0)
-		exit(1);
-	exit(0);
+		_exit(1);
+	_exit(0);
 }
 
 /* cgm_get is called to get container cgroup settings, not during startup */
@@ -1009,7 +1009,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &retval, sizeof(retval));
 		if (ret != sizeof(retval))
 			WARN("Failed to warn cgm_set of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	*key = '\0';
 
@@ -1018,7 +1018,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &retval, sizeof(retval));
 		if (ret != sizeof(retval))
 			WARN("Failed to warn cgm_set of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	cgroup = try_get_abs_cgroup(name, lxcpath, controller);
 	if (!cgroup) {
@@ -1026,7 +1026,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &retval, sizeof(retval));
 		if (ret != sizeof(retval))
 			WARN("Failed to warn cgm_set of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	cglast = strrchr(cgroup, '/');
 	if (!cglast) {
@@ -1035,7 +1035,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &retval, sizeof(retval));
 		if (ret != sizeof(retval))
 			WARN("Failed to warn cgm_set of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	*cglast = '\0';
 	if (!lxc_cgmanager_enter(getpid(), controller, cgroup, abs_cgroup_supported())) {
@@ -1045,7 +1045,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
 			WARN("Failed to warn cgm_set of error; parent may hang");
 		cgm_dbus_disconnect();
 		free_abs_cgroup(cgroup);
-		exit(1);
+		_exit(1);
 	}
 	if (cgmanager_set_value_sync(NULL, cgroup_manager, controller, cglast+1, filename, value) != 0) {
 		NihError *nerr;
@@ -1058,7 +1058,7 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
 		ret = write(outp, &retval, sizeof(retval));
 		if (ret != sizeof(retval))
 			WARN("Failed to warn cgm_set of error; parent may hang");
-		exit(1);
+		_exit(1);
 	}
 	free_abs_cgroup(cgroup);
 	cgm_dbus_disconnect();
@@ -1066,9 +1066,9 @@ static void do_cgm_set(const char *name, const char *lxcpath, const char *filena
 	retval = 1;
 	ret = write(outp, &retval, sizeof(retval));
 	if (ret != sizeof(retval)) {
-		exit(1);
+		_exit(1);
 	}
-	exit(0);
+	_exit(0);
 }
 
 /* cgm_set is called to change cgroup settings, not during startup */
@@ -1216,7 +1216,7 @@ static void drop_subsystem(int which)
 
 	if (which < 0 || which >= nr_subsystems) {
 		ERROR("code error: dropping invalid subsystem index\n");
-		exit(1);
+		_exit(1);
 	}
 
 	free(subsystems[which]);
diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index a76834f9f..dc0db161b 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -717,13 +717,13 @@ bool __criu_check_feature(uint64_t *features_to_check)
 				 * LXC checking only for 'uffd' makes not much sense. */
 				args[3] = "uffd-noncoop";
 			else
-				exit(1);
+				_exit(1);
 
 			null_stdfds();
 
 			execvp("criu", args);
 			SYSERROR("Failed to exec \"criu\"");
-			exit(1);
+			_exit(1);
 		}
 
 		ret = wait_for_pid(pid);
@@ -785,14 +785,14 @@ static bool criu_version_ok(char **version)
 
 		close(STDERR_FILENO);
 		if (dup2(pipes[1], STDOUT_FILENO) < 0)
-			exit(1);
+			_exit(1);
 
 		path = on_path("criu", NULL);
 		if (!path)
-			exit(1);
+			_exit(1);
 
 		execv(path, args);
-		exit(1);
+		_exit(1);
 	} else {
 		FILE *f;
 		char *tmp;
@@ -1140,7 +1140,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
 		if (ret)
 			lxc_abort(c->name, handler);
 		lxc_fini(c->name, handler);
-		exit(ret);
+		_exit(ret);
 	}
 
 out_fini_handler:
@@ -1165,7 +1165,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
 		close(status_pipe);
 	}
 
-	exit(1);
+	_exit(1);
 }
 
 static int save_tty_major_minor(char *directory, struct lxc_container *c, char *tty_id, int len)
@@ -1256,7 +1256,7 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
 		h.name = c->name;
 		if (!cgroup_init(&h)) {
 			ERROR("failed to cgroup_init()");
-			exit(1);
+			_exit(1);
 		}
 
 		os.pipefd = criuout[1];
@@ -1269,13 +1269,13 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
 		ret = save_tty_major_minor(opts->directory, c, os.tty_id, sizeof(os.tty_id));
 		if (ret < 0) {
 			free(criu_version);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* exec_criu() returning is an error */
 		exec_criu(&os);
 		free(criu_version);
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	} else {
 		int status;
 		ssize_t n;
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 7182b81fe..8917a32c5 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -904,14 +904,14 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		pid = fork();
 		if (pid < 0) {
 			SYSERROR("Failed to fork first child process");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* second parent */
 		if (pid != 0) {
 			free_init_cmd(init_cmd);
 			lxc_free_handler(handler);
-			exit(EXIT_SUCCESS);
+			_exit(EXIT_SUCCESS);
 		}
 
 		/* second child */
@@ -920,7 +920,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		ret = chdir("/");
 		if (ret < 0) {
 			SYSERROR("Failed to change to \"/\" directory");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		keepfds[0] = handler->conf->maincmd_fd;
@@ -929,13 +929,13 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 		ret = lxc_check_inherited(conf, true, keepfds,
 					  sizeof(keepfds) / sizeof(keepfds[0]));
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		/* redirect std{in,out,err} to /dev/null */
 		ret = null_stdfds();
 		if (ret < 0) {
 			ERROR("Failed to redirect std{in,out,err} to /dev/null");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* become session leader */
@@ -962,7 +962,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 			free_init_cmd(init_cmd);
 			lxc_free_handler(handler);
 			if (daemonize)
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			return false;
 		}
 
@@ -973,7 +973,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 			free_init_cmd(init_cmd);
 			lxc_free_handler(handler);
 			if (daemonize)
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			return false;
 		}
 
@@ -1044,9 +1044,9 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a
 	free_init_cmd(init_cmd);
 
 	if (daemonize && ret != 0)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	else if (daemonize)
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 
 	if (ret != 0)
 		return false;
@@ -1249,20 +1249,19 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		char **newargv;
 		struct lxc_conf *conf = c->lxc_conf;
 
-		if (need_null_stdfds && null_stdfds() < 0) {
-			exit(1);
-		}
+		if (need_null_stdfds && null_stdfds() < 0)
+			_exit(1);
 
 		bdev = storage_init(c->lxc_conf);
 		if (!bdev) {
 			ERROR("Error opening rootfs");
-			exit(1);
+			_exit(1);
 		}
 
 		if (geteuid() == 0) {
 			if (unshare(CLONE_NEWNS) < 0) {
 				ERROR("error unsharing mounts");
-				exit(1);
+				_exit(1);
 			}
 			if (detect_shared_rootfs()) {
 				if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL)) {
@@ -1274,7 +1273,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		if (strcmp(bdev->type, "dir") && strcmp(bdev->type, "btrfs")) {
 			if (geteuid() != 0) {
 				ERROR("non-root users can only create btrfs and directory-backed containers");
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			}
 
 			if (!strcmp(bdev->type, "overlay") || !strcmp(bdev->type, "overlayfs")) {
@@ -1300,7 +1299,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 				src = ovl_get_rootfs(bdev->src, &(size_t){0});
 				if (!src) {
 					ERROR("Failed to get rootfs");
-					exit(EXIT_FAILURE);
+					_exit(EXIT_FAILURE);
 				}
 
 				ret = mount(src, bdev->dest, "bind", MS_BIND | MS_REC, NULL);
@@ -1311,7 +1310,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			} else {
 				if (bdev->ops->mount(bdev) < 0) {
 					ERROR("Failed to mount rootfs");
-					exit(EXIT_FAILURE);
+					_exit(EXIT_FAILURE);
 				}
 			}
 		} else { /* TODO come up with a better way here! */
@@ -1331,33 +1330,33 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 
 		newargv = malloc(nargs * sizeof(*newargv));
 		if (!newargv)
-			exit(1);
+			_exit(1);
 		newargv[0] = lxcbasename(tpath);
 
 		len = strlen(c->config_path) + strlen(c->name) + strlen("--path=") + 2;
 		patharg = malloc(len);
 		if (!patharg)
-			exit(1);
+			_exit(1);
 		ret = snprintf(patharg, len, "--path=%s/%s", c->config_path, c->name);
 		if (ret < 0 || ret >= len)
-			exit(1);
+			_exit(1);
 		newargv[1] = patharg;
 		len = strlen("--name=") + strlen(c->name) + 1;
 		namearg = malloc(len);
 		if (!namearg)
-			exit(1);
+			_exit(1);
 		ret = snprintf(namearg, len, "--name=%s", c->name);
 		if (ret < 0 || ret >= len)
-			exit(1);
+			_exit(1);
 		newargv[2] = namearg;
 
 		len = strlen("--rootfs=") + 1 + strlen(bdev->dest);
 		rootfsarg = malloc(len);
 		if (!rootfsarg)
-			exit(1);
+			_exit(1);
 		ret = snprintf(rootfsarg, len, "--rootfs=%s", bdev->dest);
 		if (ret < 0 || ret >= len)
-			exit(1);
+			_exit(1);
 		newargv[3] = rootfsarg;
 
 		/* add passed-in args */
@@ -1369,7 +1368,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		nargs++;
 		newargv = realloc(newargv, nargs * sizeof(*newargv));
 		if (!newargv)
-			exit(1);
+			_exit(1);
 		newargv[nargs - 1] = NULL;
 
 		/*
@@ -1389,7 +1388,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 
 			if (!n2) {
 				SYSERROR("out of memory");
-				exit(1);
+				_exit(1);
 			}
 			newargv[0] = tpath;
 			tpath = "lxc-usernsexec";
@@ -1399,63 +1398,63 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 				n2args += 2;
 				n2 = realloc(n2, n2args * sizeof(char *));
 				if (!n2)
-					exit(1);
+					_exit(1);
 				n2[n2args-2] = "-m";
 				n2[n2args-1] = malloc(200);
 				if (!n2[n2args-1])
-					exit(1);
+					_exit(1);
 				ret = snprintf(n2[n2args-1], 200, "%c:%lu:%lu:%lu",
 					map->idtype == ID_TYPE_UID ? 'u' : 'g',
 					map->nsid, map->hostid, map->range);
 				if (ret < 0 || ret >= 200)
-					exit(1);
+					_exit(1);
 			}
 			int hostid_mapped = mapped_hostid(geteuid(), conf, ID_TYPE_UID);
 			int extraargs = hostid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
-				exit(1);
+				_exit(1);
 			if (hostid_mapped < 0) {
 				hostid_mapped = find_unmapped_nsid(conf, ID_TYPE_UID);
 				n2[n2args++] = "-m";
 				if (hostid_mapped < 0) {
 					ERROR("Could not find free uid to map");
-					exit(1);
+					_exit(1);
 				}
 				n2[n2args++] = malloc(200);
 				if (!n2[n2args-1]) {
 					SYSERROR("out of memory");
-					exit(1);
+					_exit(1);
 				}
 				ret = snprintf(n2[n2args-1], 200, "u:%d:%d:1",
 					hostid_mapped, geteuid());
 				if (ret < 0 || ret >= 200) {
 					ERROR("string too long");
-					exit(1);
+					_exit(1);
 				}
 			}
 			int hostgid_mapped = mapped_hostid(getegid(), conf, ID_TYPE_GID);
 			extraargs = hostgid_mapped >= 0 ? 1 : 3;
 			n2 = realloc(n2, (nargs + n2args + extraargs) * sizeof(char *));
 			if (!n2)
-				exit(1);
+				_exit(1);
 			if (hostgid_mapped < 0) {
 				hostgid_mapped = find_unmapped_nsid(conf, ID_TYPE_GID);
 				n2[n2args++] = "-m";
 				if (hostgid_mapped < 0) {
 					ERROR("Could not find free uid to map");
-					exit(1);
+					_exit(1);
 				}
 				n2[n2args++] = malloc(200);
 				if (!n2[n2args-1]) {
 					SYSERROR("out of memory");
-					exit(1);
+					_exit(1);
 				}
 				ret = snprintf(n2[n2args-1], 200, "g:%d:%d:1",
 					hostgid_mapped, getegid());
 				if (ret < 0 || ret >= 200) {
 					ERROR("string too long");
-					exit(1);
+					_exit(1);
 				}
 			}
 			n2[n2args++] = "--";
@@ -1469,7 +1468,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 			n2 = realloc(n2, n2args * sizeof(char *));
 			if (!n2) {
 				SYSERROR("out of memory");
-				exit(1);
+				_exit(1);
 			}
 			/* note n2[n2args-1] is NULL */
 			n2[n2args-5] = "--mapped-uid";
@@ -1485,7 +1484,7 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool need_
 		/* execute */
 		execvp(tpath, newargv);
 		SYSERROR("Failed to execute template %s", tpath);
-		exit(1);
+		_exit(1);
 	}
 
 	if (wait_for_pid(pid) != 0) {
@@ -1715,7 +1714,7 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
 		if (!bdev) {
 			ERROR("Failed to create %s storage for %s",
 			      bdevtype ? bdevtype : "(none)", c->name);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* Save config file again to store the new rootfs location. */
@@ -1726,9 +1725,9 @@ static bool do_lxcapi_create(struct lxc_container *c, const char *t,
 			 */
 			bdev->ops->umount(bdev);
 			bdev->ops->destroy(bdev);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 	}
 	if (wait_for_pid(pid) != 0)
 		goto out_unlock;
@@ -2167,7 +2166,7 @@ static char ** do_lxcapi_get_interfaces(struct lxc_container *c)
 
 		/* close the write-end of the pipe, thus sending EOF to the reader */
 		close(pipefd[1]);
-		exit(ret);
+		_exit(ret);
 	}
 
 	/* close the write-end of the pipe */
@@ -2292,7 +2291,7 @@ static char** do_lxcapi_get_ips(struct lxc_container *c, const char* interface,
 
 		/* close the write-end of the pipe, thus sending EOF to the reader */
 		close(pipefd[1]);
-		exit(ret);
+		_exit(ret);
 	}
 
 	/* close the write-end of the pipe */
@@ -3706,10 +3705,10 @@ static struct lxc_container *do_lxcapi_clone(struct lxc_container *c, const char
 	else
 		ret = clone_update_rootfs(&data);
 	if (ret < 0)
-		exit(1);
+		_exit(1);
 
 	container_mem_unlock(c);
-	exit(0);
+	_exit(0);
 
 out:
 	container_mem_unlock(c);
@@ -4279,11 +4278,11 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
 
 	ret = chroot(chrootpath);
 	if (ret < 0)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 
 	ret = chdir("/");
 	if (ret < 0)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 
 	/* remove path if it exists */
 	ret = faccessat(AT_FDCWD, path, F_OK, AT_SYMLINK_NOFOLLOW);
@@ -4291,24 +4290,24 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
 		ret = unlink(path);
 		if (ret < 0) {
 			ERROR("%s - Failed to remove \"%s\"", strerror(errno), path);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 	}
 
 	if (!add)
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 
 	/* create any missing directories */
 	tmp = strdup(path);
 	if (!tmp)
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 
 	directory_path = dirname(tmp);
 	ret = mkdir_p(directory_path, 0755);
 	if (ret < 0 && errno != EEXIST) {
 		ERROR("%s - Failed to create path \"%s\"", strerror(errno), directory_path);
 		free(tmp);
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	/* create the device node */
@@ -4316,10 +4315,10 @@ static bool do_add_remove_node(pid_t init_pid, const char *path, bool add,
 	free(tmp);
 	if (ret < 0) {
 		ERROR("%s - Failed to create device node at \"%s\"", strerror(errno), path);
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
-	exit(EXIT_SUCCESS);
+	_exit(EXIT_SUCCESS);
 }
 
 static bool add_remove_device_node(struct lxc_container *c, const char *src_path, const char *dest_path, bool add)
@@ -4464,13 +4463,13 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
 		init_pid = do_lxcapi_init_pid(c);
 		if (!switch_to_ns(init_pid, "net")) {
 			ERROR("Failed to enter network namespace");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		ret = lxc_netdev_isup(ifname);
 		if (ret < 0) {
 			ERROR("Failed to determine whether network device \"%s\" is up", ifname);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* netdev of ifname is up. */
@@ -4478,7 +4477,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
 			ret = lxc_netdev_down(ifname);
 			if (ret) {
 				ERROR("Failed to set network device \"%s\" down", ifname);
-				exit(EXIT_FAILURE);
+				_exit(EXIT_FAILURE);
 			}
 		}
 
@@ -4489,10 +4488,10 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
 				ERROR("Network device \"%s\" not found", ifname);
 			else
 				ERROR("Failed to remove network device \"%s\"", ifname);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
-		exit(EXIT_SUCCESS);
+		_exit(EXIT_SUCCESS);
 	}
 
 	ret = wait_for_pid(pid);
diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
index dee5aa5f0..ed9062f49 100644
--- a/src/lxc/lxclock.c
+++ b/src/lxc/lxclock.c
@@ -75,7 +75,7 @@ static void lock_mutex(pthread_mutex_t *l)
 	if ((ret = pthread_mutex_lock(l)) != 0) {
 		fprintf(stderr, "pthread_mutex_lock returned:%d %s\n", ret, strerror(ret));
 		dump_stacktrace();
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 }
 
@@ -87,7 +87,7 @@ static void unlock_mutex(pthread_mutex_t *l)
 		fprintf(stderr, "%s: pthread_mutex_unlock returned:%d %s\n",
 				__FILE__, ret, strerror(ret));
 		dump_stacktrace();
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 }
 
diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
index a16238992..3b1ce59b4 100644
--- a/src/lxc/monitor.c
+++ b/src/lxc/monitor.c
@@ -366,13 +366,13 @@ int lxc_monitord_spawn(const char *lxcpath)
 
 	if (setsid() < 0) {
 		SYSERROR("Failed to setsid().");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	lxc_check_inherited(NULL, true, &pipefd[1], 1);
 	if (null_stdfds() < 0) {
 		SYSERROR("Failed to dup2() standard file descriptors to /dev/null.");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	close(pipefd[0]);
@@ -380,7 +380,7 @@ int lxc_monitord_spawn(const char *lxcpath)
 	ret = snprintf(pipefd_str, LXC_NUMSTRLEN64, "%d", pipefd[1]);
 	if (ret < 0 || ret >= LXC_NUMSTRLEN64) {
 		ERROR("Failed to create pid argument to pass to monitord.");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	DEBUG("Using pipe file descriptor %d for monitord.", pipefd[1]);
@@ -388,5 +388,5 @@ int lxc_monitord_spawn(const char *lxcpath)
 	execvp(args[0], args);
 	SYSERROR("failed to exec lxc-monitord");
 
-	exit(EXIT_FAILURE);
+	_exit(EXIT_FAILURE);
 }
diff --git a/src/lxc/network.c b/src/lxc/network.c
index 734cfe4e0..d3b1b7315 100644
--- a/src/lxc/network.c
+++ b/src/lxc/network.c
@@ -635,7 +635,7 @@ static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old,
 	if (!switch_to_ns(pid, "net"))
 		return -1;
 
-	exit(lxc_netdev_rename_by_name(old, new));
+	_exit(lxc_netdev_rename_by_name(old, new));
 }
 
 static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
@@ -663,7 +663,7 @@ static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
 		sprintf(pidstr, "%d", pid);
 		execlp("iw", "iw", "phy", physname, "set", "netns", pidstr,
 		       (char *)NULL);
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	if (wait_for_pid(fpid))
@@ -2152,7 +2152,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
 		close(pipefd[1]);
 		if (ret < 0) {
 			SYSERROR("Failed to duplicate std{err,out} file descriptor");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		if (netdev->link[0] != '\0')
@@ -2162,7 +2162,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
 
 		ret = snprintf(pidstr, LXC_NUMSTRLEN64, "%d", pid);
 		if (ret < 0 || ret >= LXC_NUMSTRLEN64)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		pidstr[LXC_NUMSTRLEN64 - 1] = '\0';
 
 		INFO("Execing lxc-user-nic create %s %s %s veth %s %s", lxcpath,
@@ -2177,7 +2177,7 @@ static int lxc_create_network_unpriv_exec(const char *lxcpath, const char *lxcna
 			       lxcpath, lxcname, pidstr, "veth", netdev_link,
 			       (char *)NULL);
 		SYSERROR("Failed to execute lxc-user-nic");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	/* close the write-end of the pipe */
@@ -2295,7 +2295,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
 		close(pipefd[1]);
 		if (ret < 0) {
 			SYSERROR("Failed to duplicate std{err,out} file descriptor");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		if (netdev->priv.veth_attr.pair[0] != '\0')
@@ -2304,13 +2304,13 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
 			hostveth = netdev->priv.veth_attr.veth1;
 		if (hostveth[0] == '\0') {
 			SYSERROR("Host side veth device name is missing");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		if (netdev->link[0] == '\0') {
 			SYSERROR("Network link for network device \"%s\" is "
 				 "missing", netdev->priv.veth_attr.veth1);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		INFO("Execing lxc-user-nic delete %s %s %s veth %s %s", lxcpath,
@@ -2319,7 +2319,7 @@ static int lxc_delete_network_unpriv_exec(const char *lxcpath, const char *lxcna
 		       lxcname, netns_path, "veth", netdev->link, hostveth,
 		       (char *)NULL);
 		SYSERROR("Failed to exec lxc-user-nic.");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	close(pipefd[1]);
diff --git a/src/lxc/storage/nbd.c b/src/lxc/storage/nbd.c
index 5262e4e1f..1249476ce 100644
--- a/src/lxc/storage/nbd.c
+++ b/src/lxc/storage/nbd.c
@@ -192,13 +192,13 @@ static int do_attach_nbd(void *d)
 
 	if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
 		SYSERROR("Error blocking signals for nbd watcher");
-		exit(1);
+		_exit(1);
 	}
 
 	sfd = signalfd(-1, &mask, 0);
 	if (sfd == -1) {
 		SYSERROR("Error opening signalfd for nbd task");
-		exit(1);
+		_exit(1);
 	}
 
 	if (prctl(PR_SET_PDEATHSIG, SIGHUP, 0, 0, 0) < 0)
@@ -214,7 +214,7 @@ static int do_attach_nbd(void *d)
 			if (fdsi.ssi_signo == SIGHUP) {
 				/* container has exited */
 				nbd_detach(nbd);
-				exit(0);
+				_exit(0);
 			} else if (fdsi.ssi_signo == SIGCHLD) {
 				int status;
 				/* If qemu-nbd fails, or is killed by a signal,
@@ -223,7 +223,7 @@ static int do_attach_nbd(void *d)
 					if ((WIFEXITED(status) && WEXITSTATUS(status) != 0) ||
 							WIFSIGNALED(status)) {
 						nbd_detach(nbd);
-						exit(1);
+						_exit(1);
 					}
 				}
 			}
@@ -236,7 +236,7 @@ static int do_attach_nbd(void *d)
 
 	execlp("qemu-nbd", "qemu-nbd", "-c", nbd, path, (char *)NULL);
 	SYSERROR("Error executing qemu-nbd");
-	exit(1);
+	_exit(1);
 }
 
 static bool clone_attach_nbd(const char *nbd, const char *path)
@@ -281,7 +281,7 @@ static void nbd_detach(const char *path)
 	}
 	execlp("qemu-nbd", "qemu-nbd", "-d", path, (char *)NULL);
 	SYSERROR("Error executing qemu-nbd");
-	exit(1);
+	_exit(1);
 }
 
 /*
diff --git a/src/lxc/storage/storage_utils.c b/src/lxc/storage/storage_utils.c
index 3cae81a59..e7d7b719f 100644
--- a/src/lxc/storage/storage_utils.c
+++ b/src/lxc/storage/storage_utils.c
@@ -206,7 +206,7 @@ int detect_fs(struct lxc_storage *bdev, char *type, int len)
 	}
 
 	if (unshare(CLONE_NEWNS) < 0)
-		exit(1);
+		_exit(1);
 
 	if (detect_shared_rootfs()) {
 		if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL)) {
@@ -219,39 +219,39 @@ int detect_fs(struct lxc_storage *bdev, char *type, int len)
 	if (ret < 0) {
 		ERROR("failed mounting %s onto %s to detect fstype", srcdev,
 		      bdev->dest);
-		exit(1);
+		_exit(1);
 	}
 
 	l = linkderef(srcdev, devpath);
 	if (!l)
-		exit(1);
+		_exit(1);
 	f = fopen("/proc/self/mounts", "r");
 	if (!f)
-		exit(1);
+		_exit(1);
 
 	while (getline(&line, &linelen, f) != -1) {
 		sp1 = strchr(line, ' ');
 		if (!sp1)
-			exit(1);
+			_exit(1);
 		*sp1 = '\0';
 		if (strcmp(line, l))
 			continue;
 		sp2 = strchr(sp1 + 1, ' ');
 		if (!sp2)
-			exit(1);
+			_exit(1);
 		*sp2 = '\0';
 		sp3 = strchr(sp2 + 1, ' ');
 		if (!sp3)
-			exit(1);
+			_exit(1);
 		*sp3 = '\0';
 		sp2++;
 		if (write(p[1], sp2, strlen(sp2)) != strlen(sp2))
-			exit(1);
+			_exit(1);
 
-		exit(0);
+		_exit(0);
 	}
 
-	exit(1);
+	_exit(1);
 }
 
 int do_mkfs_exec_wrapper(void *args)
diff --git a/src/lxc/tools/lxc_checkpoint.c b/src/lxc/tools/lxc_checkpoint.c
index 8f93934b3..cbc7afe63 100644
--- a/src/lxc/tools/lxc_checkpoint.c
+++ b/src/lxc/tools/lxc_checkpoint.c
@@ -214,7 +214,7 @@ static bool restore(struct lxc_container *c)
 			close(0);
 			close(1);
 
-			exit(!restore_finalize(c));
+			_exit(!restore_finalize(c));
 		} else {
 			return wait_for_pid(pid) == 0;
 		}
diff --git a/src/lxc/tools/lxc_create.c b/src/lxc/tools/lxc_create.c
index f702c2ba7..3acae89b8 100644
--- a/src/lxc/tools/lxc_create.c
+++ b/src/lxc/tools/lxc_create.c
@@ -123,7 +123,7 @@ static void create_helpfn(const struct lxc_arguments *args)
 
 	execv(path, argv);
 	fprintf(stderr, "Error executing %s -h\n", path);
-	exit(EXIT_FAILURE);
+	_exit(EXIT_FAILURE);
 }
 
 static struct lxc_arguments my_args = {
diff --git a/src/lxc/tools/lxc_device.c b/src/lxc/tools/lxc_device.c
index f73e8c2cb..b7b49645e 100644
--- a/src/lxc/tools/lxc_device.c
+++ b/src/lxc/tools/lxc_device.c
@@ -72,22 +72,22 @@ static bool is_interface(const char* dev_name, pid_t pid)
 
 		if (!switch_to_ns(pid, "net")) {
 			fprintf(stderr, "failed to enter netns of container.\n");
-			exit(-1);
+			_exit(-1);
 		}
 
 		/* Grab the list of interfaces */
 		if (getifaddrs(&interfaceArray)) {
 			fprintf(stderr, "failed to get interfaces list\n");
-			exit(-1);
+			_exit(-1);
 		}
 
 		/* Iterate through the interfaces */
-		for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next) {
-			if (strcmp(tempIfAddr->ifa_name, dev_name) == 0) {
-				exit(EXIT_SUCCESS);
-			}
-		}
-		exit(EXIT_FAILURE);
+		for (tempIfAddr = interfaceArray; tempIfAddr != NULL;
+		     tempIfAddr = tempIfAddr->ifa_next)
+			if (strcmp(tempIfAddr->ifa_name, dev_name) == 0)
+				_exit(EXIT_SUCCESS);
+
+		_exit(EXIT_FAILURE);
 	}
 
 	if (wait_for_pid(p) == 0) {
diff --git a/src/lxc/tools/lxc_unshare.c b/src/lxc/tools/lxc_unshare.c
index 9e062a0ca..63f00e5a3 100644
--- a/src/lxc/tools/lxc_unshare.c
+++ b/src/lxc/tools/lxc_unshare.c
@@ -122,7 +122,7 @@ static int do_start(void *arg)
 		if (ret == -1) {
 			close(wait_fd);
 			fprintf(stderr, "read eventfd failed\n");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 	}
 
@@ -132,13 +132,13 @@ static int do_start(void *arg)
 	if ((flags & CLONE_NEWUTS) && want_hostname)
 		if (sethostname(want_hostname, strlen(want_hostname)) < 0) {
 			fprintf(stderr, "failed to set hostname %s: %s\n", want_hostname, strerror(errno));
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 	/* Setuid is useful even without a new user id space. */
 	if (start_arg->setuid && setuid(uid)) {
 		fprintf(stderr, "failed to set uid %d: %s\n", uid, strerror(errno));
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	execvp(args[0], args);
diff --git a/src/lxc/tools/lxc_usernsexec.c b/src/lxc/tools/lxc_usernsexec.c
index 72d4a005b..32eac4be1 100644
--- a/src/lxc/tools/lxc_usernsexec.c
+++ b/src/lxc/tools/lxc_usernsexec.c
@@ -340,15 +340,15 @@ int main(int argc, char *argv[])
 		buf[0] = '1';
 		if (write(pipe1[1], buf, 1) < 1) {
 			perror("write pipe");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 		if (read(pipe2[0], buf, 1) < 1) {
 			perror("read pipe");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 		if (buf[0] != '1') {
 			fprintf(stderr, "parent had an error, child exiting\n");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		close(pipe1[1]);
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index 79e47732c..c721019c4 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -461,7 +461,7 @@ struct lxc_popen_FILE *lxc_popen(const char *command)
 	if (child_pid < 0)
 		goto on_error;
 
-	if (!child_pid) {
+	if (child_pid == 0) {
 		sigset_t mask;
 
 		close(pipe_fds[0]);
@@ -473,7 +473,7 @@ struct lxc_popen_FILE *lxc_popen(const char *command)
 			ret = fcntl(pipe_fds[1], F_SETFD, 0);
 		if (ret < 0) {
 			close(pipe_fds[1]);
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* duplicate stderr */
@@ -483,19 +483,19 @@ struct lxc_popen_FILE *lxc_popen(const char *command)
 			ret = fcntl(pipe_fds[1], F_SETFD, 0);
 		close(pipe_fds[1]);
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		/* unblock all signals */
 		ret = sigfillset(&mask);
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
 		if (ret < 0)
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 
 		execl("/bin/sh", "sh", "-c", command, (char *)NULL);
-		exit(127);
+		_exit(127);
 	}
 
 	close(pipe_fds[1]);
@@ -2254,13 +2254,13 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
 
 		if (ret < 0) {
 			SYSERROR("failed to duplicate std{err,out} file descriptor");
-			exit(EXIT_FAILURE);
+			_exit(EXIT_FAILURE);
 		}
 
 		/* Does not return. */
 		child_fn(args);
 		ERROR("failed to exec command");
-		exit(EXIT_FAILURE);
+		_exit(EXIT_FAILURE);
 	}
 
 	/* close the write-end of the pipe */


More information about the lxc-devel mailing list