[lxc-devel] [lxc/master] rexec: try sendfile() fallback to fd_to_fd()

brauner on Github lxc-bot at linuxcontainers.org
Mon Feb 18 22:02:33 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190218/5bc4f292/attachment.bin>
-------------- next part --------------
From 4b7469be3da72df7371d05084875a153ce8eb934 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 18 Feb 2019 23:01:43 +0100
Subject: [PATCH] rexec: try sendfile() fallback to fd_to_fd()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/rexec.c | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/lxc/rexec.c b/src/lxc/rexec.c
index 58f3ff486..3840231f8 100644
--- a/src/lxc/rexec.c
+++ b/src/lxc/rexec.c
@@ -107,6 +107,8 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
 {
 	__do_close_prot_errno int fd = -EBADF, memfd = -EBADF, tmpfd = -EBADF;
 	int ret;
+	ssize_t bytes_sent = 0;
+	struct stat st = {0};
 
 	memfd = memfd_create(memfd_name, MFD_ALLOW_SEALING | MFD_CLOEXEC);
 	if (memfd < 0) {
@@ -131,24 +133,26 @@ static void lxc_rexec_as_memfd(char **argv, char **envp, const char *memfd_name)
 		return;
 
 	/* sendfile() handles up to 2GB. */
-	if (memfd >= 0) {
-		ssize_t bytes_sent = 0;
-		struct stat st = {0};
+	ret = fstat(fd, &st);
+	if (ret)
+		return;
 
-		ret = fstat(fd, &st);
-		if (ret)
-			return;
+	while (bytes_sent < st.st_size) {
+		ssize_t sent;
 
-		while (bytes_sent < st.st_size) {
-			ssize_t sent;
-			sent = lxc_sendfile_nointr(memfd, fd, NULL,
-						   st.st_size - bytes_sent);
-			if (sent < 0)
-				return;
-			bytes_sent += sent;
+		sent = lxc_sendfile_nointr(memfd >= 0 ? memfd : tmpfd, fd, NULL,
+					   st.st_size - bytes_sent);
+		if (sent < 0) {
+			/* Fallback to shoveling data between kernel- and
+			 * userspace.
+			 */
+			lseek(fd, 0, SEEK_SET);
+			if (fd_to_fd(fd, memfd >= 0 ? memfd : tmpfd))
+				break;
+
+			return;
 		}
-	} else if (fd_to_fd(fd, tmpfd)) {
-		return;
+		bytes_sent += sent;
 	}
 
 	close_prot_errno_disarm(fd);


More information about the lxc-devel mailing list