Commit a288f3f2 authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Pavel Emelyanov

files: Allow to receive further fds

For moving to a single transport socket scheme, we should be able
to receive a fd, which is not need at the moment, but it will
be used in the future. So, we receive a further fd, and then
continue to wait the fd, we really need now.

v3: Delete excess BUG_ON().
    Rename main patch funtion to keep_fd_for_future().
    Rename second funtion to task_fle(), and make it
    have "task" argument.

travis-ci: success for Rework file opening scheme to make it asynchronous (rev5)
Signed-off-by: 's avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 6bf2a433
......@@ -955,20 +955,51 @@ err:
return -1;
}
static bool task_fle(struct pstree_item *task, struct fdinfo_list_entry *fle)
{
struct fdinfo_list_entry *tmp;
list_for_each_entry(tmp, &rsti(task)->used, used_list)
if (fle == tmp)
return true;
return false;
}
static int keep_fd_for_future(struct fdinfo_list_entry *fle, int fd)
{
BUG_ON(fle->received);
fle->received = 1;
if (close(fle->fe->fd) < 0) {
pr_perror("Can't close transport fd\n");
return -1;
}
return reopen_fd_as(fle->fe->fd, fd);
}
int recv_fd_from_peer(struct fdinfo_list_entry *fle)
{
struct fdinfo_list_entry *tmp;
int fd, ret;
if (fle->received)
return fle->fe->fd;
again:
ret = recv_fds(fle->fe->fd, &fd, 1, (void *)&tmp, sizeof(struct fdinfo_list_entry *));
if (ret)
return -1;
if (tmp != fle) {
pr_err("Received wrong fle\n");
return -1;
pr_info("Further fle=%p, pid=%d\n", tmp, fle->pid);
if (!task_fle(current, fle)) {
pr_err("Unexpected fle %p, pid=%d\n", fle, current->pid->ns[0].virt);
return -1;
}
if (keep_fd_for_future(tmp, fd))
return -1;
goto again;
}
close(fle->fe->fd);
fle->received = 1;
return fd;
}
......@@ -1012,6 +1043,8 @@ static int send_fd_to_self(int fd, struct fdinfo_list_entry *fle)
return -1;
}
fle->received = 1;
return 0;
}
......
......@@ -72,6 +72,7 @@ struct fdinfo_list_entry {
int pid;
futex_t real_pid;
FdinfoEntry *fe;
u8 received:1;
};
static inline void fle_init(struct fdinfo_list_entry *fle, int pid, FdinfoEntry *fe)
......@@ -79,6 +80,7 @@ static inline void fle_init(struct fdinfo_list_entry *fle, int pid, FdinfoEntry
futex_init(&fle->real_pid);
fle->pid = pid;
fle->fe = fe;
fle->received = 0;
}
/* reports whether fd_a takes prio over fd_b */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment