[CRIU] [PATCH v3 09/10] epoll: Add support for multiple duped fds
Cyrill Gorcunov
gorcunov at gmail.com
Fri Jun 29 18:44:44 MSK 2018
v3:
- use signed types to make clang happy and simplify cycle
Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
criu/eventpoll.c | 52 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 37 insertions(+), 15 deletions(-)
diff --git a/criu/eventpoll.c b/criu/eventpoll.c
index 90fac99488f4..b1436414321a 100644
--- a/criu/eventpoll.c
+++ b/criu/eventpoll.c
@@ -68,17 +68,18 @@ static int tfd_cmp(const void *a, const void *b)
* fds in fd_parms are sorted so we can use binary search
* for better performance.
*/
-static int find_tfd(pid_t pid, int efd, int fds[], size_t nr_fds, int tfd)
+static int find_tfd(pid_t pid, int efd, int fds[], size_t nr_fds, int tfd,
+ unsigned int toff)
{
kcmp_epoll_slot_t slot = {
.efd = efd,
.tfd = tfd,
- .toff = 0,
+ .toff = toff,
};
int *tfd_found;
size_t i;
- pr_debug("find_tfd: pid %d efd %d tfd %d\n", pid, efd, tfd);
+ pr_debug("find_tfd: pid %d efd %d tfd %d toff %u\n", pid, efd, tfd, toff);
/*
* Optimistic case: the target fd belongs to us
@@ -88,13 +89,13 @@ static int find_tfd(pid_t pid, int efd, int fds[], size_t nr_fds, int tfd)
if (tfd_found) {
if (kdat.has_kcmp_epoll_tfd) {
if (syscall(SYS_kcmp, pid, pid, KCMP_EPOLL_TFD, tfd, &slot) == 0) {
- pr_debug("find_tfd (kcmp-yes): bsearch match pid %d efd %d tfd %d\n",
- pid, efd, tfd);
+ pr_debug("find_tfd (kcmp-yes): bsearch match pid %d efd %d tfd %d toff %u\n",
+ pid, efd, tfd, toff);
return tfd;
}
} else {
- pr_debug("find_tfd (kcmp-no): bsearch match pid %d efd %d tfd %d\n",
- pid, efd, tfd);
+ pr_debug("find_tfd (kcmp-no): bsearch match pid %d efd %d tfd %d toff %u\n",
+ pid, efd, tfd, toff);
return tfd;
}
}
@@ -106,21 +107,21 @@ static int find_tfd(pid_t pid, int efd, int fds[], size_t nr_fds, int tfd)
*/
if (!kdat.has_kcmp_epoll_tfd) {
- pr_debug("find_tfd (kcmp-no): no match pid %d efd %d tfd %d\n",
- pid, efd, tfd);
+ pr_debug("find_tfd (kcmp-no): no match pid %d efd %d tfd %d toff %u\n",
+ pid, efd, tfd, toff);
return -1;
}
for (i = 0; i < nr_fds; i++) {
if (syscall(SYS_kcmp, pid, pid, KCMP_EPOLL_TFD, fds[i], &slot) == 0) {
- pr_debug("find_tfd (kcmp-yes): nsearch match pid %d efd %d tfd %d -> %d\n",
- pid, efd, tfd, fds[i]);
+ pr_debug("find_tfd (kcmp-yes): nsearch match pid %d efd %d tfd %d toff %u -> %d\n",
+ pid, efd, tfd, toff, fds[i]);
return fds[i];
}
}
- pr_debug("find_tfd (kcmp-yes): no match pid %d efd %d tfd %d\n",
- pid, efd, tfd);
+ pr_debug("find_tfd (kcmp-yes): no match pid %d efd %d tfd %d toff %u\n",
+ pid, efd, tfd, toff);
return -1;
}
@@ -129,7 +130,8 @@ static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
FileEntry fe = FILE_ENTRY__INIT;
EventpollFileEntry e = EVENTPOLL_FILE_ENTRY__INIT;
EventpollTfdEntry **tfd_cpy = NULL;
- size_t i, j, n_tfd_cpy;
+ ssize_t i, j, n_tfd_cpy;
+ uint32_t *toff = NULL;
int ret = -1;
e.id = id;
@@ -148,6 +150,25 @@ static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
if (!tfd_cpy)
goto out;
+ /*
+ * In regular case there is no so many dup'ed
+ * descriptors so instead of complex mappings
+ * lets rather walk over members with O(n^2)
+ */
+ if (p->dfds) {
+ toff = xzalloc(sizeof(*toff) * e.n_tfd);
+ if (!toff)
+ goto out;
+ for (i = e.n_tfd - 1; i >= 0; i--) {
+ for (j = i + 1; j < e.n_tfd; j++) {
+ if (e.tfd[i]->tfd == e.tfd[j]->tfd) {
+ toff[i] = toff[j] + 1;
+ break;
+ }
+ }
+ }
+ }
+
/*
* Handling dup'ed or transferred target
* files is tricky: we need to use kcmp
@@ -159,7 +180,7 @@ static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
if (p->dfds) {
for (i = j = 0; i < e.n_tfd; i++) {
int tfd = find_tfd(p->pid, p->fd, p->dfds->fds,
- p->dfds->nr_fds, e.tfd[i]->tfd);
+ p->dfds->nr_fds, e.tfd[i]->tfd, toff[i]);
if (tfd == -1) {
pr_warn("Escaped/closed fd descriptor %d on pid %d, ignoring\n",
e.tfd[i]->tfd, p->pid);
@@ -186,6 +207,7 @@ static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
eventpoll_tfd_entry__free_unpacked(e.tfd[i], NULL);
xfree(tfd_cpy);
xfree(e.tfd);
+ xfree(toff);
return ret;
}
--
2.14.4
More information about the CRIU
mailing list