[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