[lxc-devel] [lxc/master] use execveat syscall to exec lxc-init if supported
tych0 on Github
lxc-bot at linuxcontainers.org
Tue May 22 23:35:25 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 498 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180522/a9a6664d/attachment.bin>
-------------- next part --------------
From fcc7bf2940b912dee51c1062e66893a2d7726f10 Mon Sep 17 00:00:00 2001
From: Tycho Andersen <tycho at tycho.ws>
Date: Tue, 22 May 2018 23:33:17 +0000
Subject: [PATCH] use execveat syscall to exec lxc-init if supported
the execveat allows us to exec stuff via a fd so we don't have to bind
mount stuff in. see the comment about why we're using the syscall directly.
Signed-off-by: Tycho Andersen <tycho at tycho.ws>
---
src/lxc/conf.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
src/lxc/execute.c | 19 ++++++++++++-------
src/lxc/start.h | 1 +
3 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 77c134e82..c87465c77 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3259,6 +3259,7 @@ static int lxc_execute_bind_init(struct lxc_handler *handler)
INFO("Bind mounted lxc.init.static into container at \"%s\"", path);
out:
+ ((struct execute_args *)handler->data)->init_fd = -1;
((struct execute_args *)handler->data)->init_path = p;
return 0;
}
@@ -3333,6 +3334,24 @@ static bool verify_start_hooks(struct lxc_conf *conf)
return true;
}
+static bool execveat_supported(void)
+{
+#ifdef __NR_execveat
+ /*
+ * We use the syscall here, because it was introduced in kernel 3.19,
+ * while glibc got support for using the syscall much later, in 2.27.
+ * We don't want to use glibc because it falls back to /proc, and the
+ * container may not have /proc mounted depending on its configuration.
+ */
+ syscall(__NR_execveat, -1, "", NULL, NULL, AT_EMPTY_PATH);
+ if (errno == ENOSYS)
+ return false;
+ return true;
+#else
+ return false;
+#endif
+}
+
int lxc_setup(struct lxc_handler *handler)
{
int ret;
@@ -3393,10 +3412,30 @@ int lxc_setup(struct lxc_handler *handler)
return -1;
if (lxc_conf->is_execute) {
- ret = lxc_execute_bind_init(handler);
- if (ret < 0) {
- ERROR("Failed to bind-mount the lxc init system");
- return -1;
+ if (execveat_supported()) {
+ int fd;
+ char path[PATH_MAX];
+
+ ret = snprintf(path, PATH_MAX, SBINDIR "/init.lxc.static");
+ if (ret < 0 || ret >= PATH_MAX) {
+ ERROR("Path to init.lxc.static too long");
+ return -1;
+ }
+
+ fd = open(path, O_PATH | O_CLOEXEC);
+ if (fd < 0) {
+ SYSERROR("Unable to open lxc.init.static");
+ return -1;
+ }
+
+ ((struct execute_args *)handler->data)->init_fd = fd;
+ ((struct execute_args *)handler->data)->init_path = NULL;
+ } else {
+ ret = lxc_execute_bind_init(handler);
+ if (ret < 0) {
+ ERROR("Failed to bind-mount the lxc init system");
+ return -1;
+ }
}
}
diff --git a/src/lxc/execute.c b/src/lxc/execute.c
index b436b6a3f..fdd639a2d 100644
--- a/src/lxc/execute.c
+++ b/src/lxc/execute.c
@@ -66,12 +66,10 @@ static int execute_start(struct lxc_handler *handler, void* data)
goto out1;
}
- if (!my_args->init_path) {
- ERROR("Init path missing");
- goto out2;
- }
-
- argv[i++] = my_args->init_path;
+ if (my_args->init_path)
+ argv[i++] = my_args->init_path;
+ else
+ argv[i++] = "lxc-init";
argv[i++] = "-n";
argv[i++] = (char *)handler->name;
@@ -117,7 +115,14 @@ static int execute_start(struct lxc_handler *handler, void* data)
NOTICE("Exec'ing \"%s\"", my_args->argv[0]);
- execvp(argv[0], argv);
+ if (my_args->init_fd >= 0)
+#ifdef __NR_execveat
+ syscall(__NR_execveat, my_args->init_fd, "", argv, environ, AT_EMPTY_PATH);
+#else
+ ERROR("Set up execveat without syscall nr?");
+#endif
+ else
+ execvp(argv[0], argv);
SYSERROR("Failed to exec %s", argv[0]);
out3:
diff --git a/src/lxc/start.h b/src/lxc/start.h
index 466dbf5f3..aaa731077 100644
--- a/src/lxc/start.h
+++ b/src/lxc/start.h
@@ -138,6 +138,7 @@ struct lxc_handler {
struct execute_args {
char *init_path;
+ int init_fd;
char *const *argv;
int quiet;
};
More information about the lxc-devel
mailing list