[CRIU] [PATCH] pipes: Restore pipe size via userns call

Cyrill Gorcunov gorcunov at openvz.org
Fri Feb 3 10:28:23 PST 2017


From: Cyrill Gorcunov <gorcunov at virtuozzo.com>

In vanilla kernels starting from v4.4-6172-g759c011
pipes allocation is limited per user-namespace, and
what is more interesting is that if hard limit is
zero but softlimit is not, then it is possible to
create new pipes with one buffer but setting its
size if not allowed until we're having CAP_SYS_RESOURCE
and CAP_SYS_ADMIN caps granted.

So to be able to restore this resource we need
to use userns daemon.

Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
---
 criu/pipes.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/criu/pipes.c b/criu/pipes.c
index 7be1d5f047a1..26aa2b4c359f 100644
--- a/criu/pipes.c
+++ b/criu/pipes.c
@@ -11,6 +11,7 @@
 #include "pipes.h"
 #include "util-pie.h"
 #include "autofs.h"
+#include "namespaces.h"
 
 #include "protobuf.h"
 #include "util.h"
@@ -142,6 +143,25 @@ static int mark_pipe_master(void *unused)
 
 static struct pipe_data_rst *pd_hash_pipes[PIPE_DATA_HASH_SIZE];
 
+typedef struct {
+	unsigned int	pipe_id;
+	size_t		size;
+} pipe_set_size_arg_t;
+
+static int pipe_set_size(void *arg, int fd, int pid)
+{
+	pipe_set_size_arg_t *p = arg;
+
+	pr_info("Restoring size %#zx for %#x\n", p->size, p->pipe_id);
+
+	if (fcntl(fd, F_SETPIPE_SZ, p->size) < 0) {
+		pr_perror("Can't restore pipe size");
+		return -1;
+	}
+
+	return 0;
+}
+
 int restore_pipe_data(int img_type, int pfd, u32 id, struct pipe_data_rst **hash)
 {
 	int ret;
@@ -201,13 +221,11 @@ int restore_pipe_data(int img_type, int pfd, u32 id, struct pipe_data_rst **hash
 out:
 	ret = 0;
 	if (pd->pde->has_size) {
-		pr_info("Restoring size %#x for %#x\n",
-				pd->pde->size, pd->pde->pipe_id);
-		ret = fcntl(pfd, F_SETPIPE_SZ, pd->pde->size);
-		if (ret < 0)
-			pr_perror("Can't restore pipe size");
-		else
-			ret = 0;
+		pipe_set_size_arg_t args = {
+			.pipe_id	= pd->pde->pipe_id,
+			.size		= (size_t)pd->pde->size,
+		};
+		ret = userns_call(pipe_set_size, UNS_ASYNC, &args, sizeof(args), pfd);
 	}
 err:
 	return ret;
-- 
2.7.4



More information about the CRIU mailing list