Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@virtuozzo.com>2017-02-28 10:26:00 +0300
committerPavel Emelyanov <xemul@virtuozzo.com>2017-03-06 11:44:05 +0300
commitebb7087aea8e76387155629b63c4f745db8bb325 (patch)
tree682e0b3f0c468c39caabe6f846b1cf7bda744c8e
parent1de7fdff4ae79049c6e940fc9fb9530f676330a5 (diff)
pipe: reopen pipes via usernsd
If a pipe is inherited (external), it may be impossible to reopen it from a restored user namespace due to lack of permession, so in this case we have to reopen it via usernsd. https://github.com/opencontainers/runc/issues/1333 Signed-off-by: Andrei Vagin <avagin@virtuozzo.com> Acked-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
-rw-r--r--criu/pipes.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/criu/pipes.c b/criu/pipes.c
index d665a5946..4d15d739e 100644
--- a/criu/pipes.c
+++ b/criu/pipes.c
@@ -17,6 +17,7 @@
#include "images/pipe.pb-c.h"
#include "images/pipe-data.pb-c.h"
#include "fcntl.h"
+#include "namespaces.h"
static LIST_HEAD(pipes);
@@ -213,10 +214,10 @@ err:
return ret;
}
-static int reopen_pipe(int fd, int flags)
+static int userns_reopen(void *_arg, int fd, pid_t pid)
{
- int ret;
char path[PSFDS];
+ int ret, flags = *(int*)_arg;
sprintf(path, "/proc/self/fd/%d", fd);
ret = open(path, flags);
@@ -227,6 +228,26 @@ static int reopen_pipe(int fd, int flags)
return ret;
}
+static int reopen_pipe(int fd, int flags)
+{
+ int ret;
+ char path[PSFDS];
+
+ sprintf(path, "/proc/self/fd/%d", fd);
+ ret = open(path, flags);
+ if (ret < 0) {
+ if (errno == EACCES) {
+ /* It may be an external pipe from an another userns */
+ ret = userns_call(userns_reopen, UNS_FDOUT,
+ &flags, sizeof(flags), fd);
+ } else
+ pr_perror("Unable to reopen the pipe %s", path);
+ }
+ close(fd);
+
+ return ret;
+}
+
static int recv_pipe_fd(struct pipe_info *pi, int *new_fd)
{
int tmp, fd, ret;