[PATCH v6 6/7] namespace utils: code shrink
Bartosz Golaszewski
bartekgola at gmail.com
Thu Mar 17 14:52:28 UTC 2016
Both unshare and nsenter use similar code to fork and have the parent
wait for child's completion. Move it to a common library function.
function old new delta
continue_as_child - 105 +105
unshare_main 1066 1004 -62
nsenter_main 850 753 -97
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 0/2 up/down: 105/-159) Total: -54 bytes
text data bss dec hex filename
829552 4486 9120 843158 cdd96 busybox_old
829498 4486 9120 843104 cdd60 busybox_unstripped
Signed-off-by: Bartosz Golaszewski <bartekgola at gmail.com>
---
util-linux/namespace.c | 34 ++++++++++++++++++++++++++++++++++
util-linux/namespace.h | 7 +++++++
util-linux/nsenter.c | 20 ++------------------
util-linux/unshare.c | 19 ++-----------------
4 files changed, 45 insertions(+), 35 deletions(-)
create mode 100644 util-linux/namespace.c
diff --git a/util-linux/namespace.c b/util-linux/namespace.c
new file mode 100644
index 0000000..1cfa1ae
--- /dev/null
+++ b/util-linux/namespace.c
@@ -0,0 +1,34 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Common namespace code.
+ *
+ * Copyright (C) 2016 by Bartosz Golaszewski <bartekgola at gmail.com>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+//kbuild:lib-$(CONFIG_UNSHARE) += namespace.o
+//kbuild:lib-$(CONFIG_NSENTER) += namespace.o
+
+#include "libbb.h"
+#include "namespace.h"
+
+void continue_as_child(void)
+{
+ int exit_status, rv;
+ pid_t pid;
+
+ pid = xfork();
+ if (pid > 0) {
+ rv = safe_waitpid(pid, &exit_status, WUNTRACED);
+ if (rv < 0)
+ bb_perror_msg_and_die("waitpid");
+
+ if (WIFEXITED(exit_status))
+ exit(WEXITSTATUS(exit_status));
+ else if (WIFSIGNALED(exit_status))
+ kill(getpid(), WTERMSIG(exit_status));
+
+ bb_error_msg_and_die("child exit failed");
+ } /* Child continues. */
+}
diff --git a/util-linux/namespace.h b/util-linux/namespace.h
index 331bfe6..8a203d5 100644
--- a/util-linux/namespace.h
+++ b/util-linux/namespace.h
@@ -17,4 +17,11 @@
*/
#define NS_PROC_PATH_MAX (sizeof("/proc//ns/user") + INT_BUF_MAX(pid_t))
+/*
+ * Fork and wait for the child process to finish. Exit with the child process'
+ * exit status or deliver the signal which killed the child to the parent.
+ * Exit if fork() or waitpid() fails.
+ */
+void continue_as_child(void);
+
#endif /* BB_NAMESPACE_H */
diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c
index 79a28c6..28c6972 100644
--- a/util-linux/nsenter.c
+++ b/util-linux/nsenter.c
@@ -312,24 +312,8 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv)
* Entering the pid namespace implies forking unless it's been
* explicitly requested by the user not to.
*/
- if (!(opts & OPT_nofork) && (opts & OPT_pid)) {
- int exit_status;
- pid_t pid;
-
- pid = xfork();
- if (pid > 0) {
- status = safe_waitpid(pid, &exit_status, 0);
- if (status < 0)
- bb_perror_msg_and_die("waitpid");
-
- if (WIFEXITED(exit_status))
- return WEXITSTATUS(exit_status);
- else if (WIFSIGNALED(exit_status))
- kill(getpid(), WTERMSIG(exit_status));
-
- bb_error_msg_and_die("child exit failed");
- } /* Child continues. */
- }
+ if (!(opts & OPT_nofork) && (opts & OPT_pid))
+ continue_as_child();
if (opts & OPT_setgid) {
status = setgroups(0, NULL);
diff --git a/util-linux/unshare.c b/util-linux/unshare.c
index c1811be..6cefd81 100644
--- a/util-linux/unshare.c
+++ b/util-linux/unshare.c
@@ -397,23 +397,8 @@ int unshare_main(int argc UNUSED_PARAM, char **argv)
* child. The user may want to use this option to spawn a new process
* that'll become PID 1 in this new namespace.
*/
- if (opts & OPT_fork) {
- int exit_status;
-
- pid = xfork();
- if (pid > 0) {
- status = safe_waitpid(pid, &exit_status, 0);
- if (status < 0)
- bb_perror_msg_and_die("waitpid");
-
- if (WIFEXITED(exit_status))
- return WEXITSTATUS(exit_status);
- else if (WIFSIGNALED(exit_status))
- kill(getpid(), WTERMSIG(exit_status));
-
- bb_error_msg_and_die("child exit failed");
- } /* Child continues. */
- }
+ if (opts & OPT_fork)
+ continue_as_child();
if (opts & OPT_map_root) {
char uidmap_buf[sizeof(unsigned int) * 3 + sizeof(" 0 1")];
--
2.1.4
More information about the busybox
mailing list