diff --git a/pipes.c b/pipes.c index bd2a3650c..7bf1b5996 100644 --- a/pipes.c +++ b/pipes.c @@ -28,7 +28,8 @@ struct pipe_info { * This is pure circular list without head */ struct list_head list; /* list head for fdinfo_list_entry-s */ struct file_desc d; - int create; + unsigned int create : 1, + reopen : 1; }; static LIST_HEAD(pipes); @@ -117,6 +118,7 @@ void mark_pipe_master(void) while (1) { struct fdinfo_list_entry *fle; struct pipe_info *pi, *pic, *p; + struct pipe_info *pr = NULL, *pw = NULL; if (list_empty(&pipes)) break; @@ -129,6 +131,15 @@ void mark_pipe_master(void) fle = file_master(&pi->d); p = pi; + if (!(pi->pe->flags & O_LARGEFILE)) { + if (pi->pe->flags & O_WRONLY) { + if (pw == NULL) + pw = pi; + } else { + if (pr == NULL) + pr = pi; + } + } list_for_each_entry(pic, &pi->pipe_list, pipe_list) { struct fdinfo_list_entry *f; @@ -140,9 +151,23 @@ void mark_pipe_master(void) fle = f; } + if (!(pic->pe->flags & O_LARGEFILE)) { + if (pic->pe->flags & O_WRONLY) { + if (pw == NULL) + pw = pic; + } else { + if (pr == NULL) + pr = pic; + } + } + show_saved_pipe_fds(pic); } p->create = 1; + if (pr) + pr->reopen = 0; + if (pw) + pw->reopen = 0; pr_info(" by %#x\n", p->pe->id); } @@ -222,10 +247,22 @@ err: return ret; } +static int reopen_pipe(int fd, int flags, struct pipe_info *pi) +{ + int ret; + char path[32]; + + pr_err("%s %p %d\n", __func__, pi, fd); + snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); + ret = open(path, flags); + close(fd); + + return ret; +} + static int recv_pipe_fd(struct pipe_info *pi) { struct fdinfo_list_entry *fle; - char path[32]; int tmp, fd; fle = file_master(&pi->d); @@ -240,12 +277,12 @@ static int recv_pipe_fd(struct pipe_info *pi) } close(fd); - snprintf(path, sizeof(path), "/proc/self/fd/%d", tmp); - fd = open(path, pi->pe->flags); - close(tmp); - + if (pi->reopen) + fd = reopen_pipe(tmp, pi->pe->flags, pi); + else + fd = tmp; if (fd >= 0) { - if (restore_fown(fd, pi->pe->fown)) { + if (rst_file_params(fd, pi->pe->fown, pi->pe->flags)) { close(fd); return -1; } @@ -302,6 +339,9 @@ static int open_pipe(struct file_desc *d) close(pfd[!(pi->pe->flags & O_WRONLY)]); tmp = pfd[pi->pe->flags & O_WRONLY]; + if (pi->reopen) + tmp = reopen_pipe(tmp, pi->pe->flags, pi); + if (rst_file_params(tmp, pi->pe->fown, pi->pe->flags)) return -1; @@ -329,6 +369,7 @@ static int collect_one_pipe(void *o, ProtobufCMessage *base) pi->pe = pb_msg(base, PipeEntry); pi->create = 0; + pi->reopen = 1; pr_info("Collected pipe entry ID %#x PIPE ID %#x\n", pi->pe->id, pi->pe->pipe_id); diff --git a/test/zdtm/live/static/file_fown.c b/test/zdtm/live/static/file_fown.c index 4756fa946..0dfe47c50 100644 --- a/test/zdtm/live/static/file_fown.c +++ b/test/zdtm/live/static/file_fown.c @@ -40,16 +40,6 @@ static void fill_pipe_params(struct params *p, int *pipes) p->pipe_flags[0] = fcntl(pipes[0], F_GETFL); p->pipe_flags[1] = fcntl(pipes[1], F_GETFL); - /* - * The kernel's O_LARGEFILE set automatically - * on open() in x86-64, so unmask it explicitly - * we restore pipes via open call while the former - * pipes are created with pipe() and have no O_LARGEFILE - * set. - */ - p->pipe_flags[0] &= ~00100000; - p->pipe_flags[1] &= ~00100000; - test_msg("pipe_flags0 %08o\n", p->pipe_flags[0]); test_msg("pipe_flags1 %08o\n", p->pipe_flags[1]);