[CRIU] [PATCH 09/10] epoll: Ignore inaccessible targets
Cyrill Gorcunov
gorcunov at openvz.org
Tue Feb 28 07:05:48 PST 2017
Not all targets can be restored by now,
so simply ignore them on dump this should
not be a common case.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
criu/eventpoll.c | 57 +++++++++++++++++++++++++++++++++++++++++----------
criu/include/fdinfo.h | 1 +
criu/proc_parse.c | 1 +
3 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/criu/eventpoll.c b/criu/eventpoll.c
index 0515b736603a..670cb06f95bd 100644
--- a/criu/eventpoll.c
+++ b/criu/eventpoll.c
@@ -151,6 +151,7 @@ int dump_eventpoll(void)
struct kid_elem *kid;
list_for_each_entry(dinfo, &eventpoll_fds, list) {
+ unsigned long nr_valid = 0;
kcmp_epoll_slot_t slot = {
.efd = dinfo->fd,
.toff = 0,
@@ -167,22 +168,56 @@ int dump_eventpoll(void)
kid = fd_kid_epoll_lookup(dinfo->pid,
te->epl.gen_id,
&slot);
- if (!kid || kid->pid != dinfo->pid) {
- pr_err("Target %d not found for pid %d "
- "(or pid mismatsh %d)\n",
- te->epl.e.tfd, dinfo->pid,
- kid ? kid->pid : -1);
- goto out;
+ if (!kid || kid->pid != dinfo->pid ||
+ kid->idx != te->epl.e.tfd) {
+ pr_warn("Target %d not found for pid %d "
+ "(or pid mismatsh %d), ignoring\n",
+ te->epl.e.tfd, dinfo->pid,
+ kid ? kid->pid : -1);
+ te->epl.valid = 0;
+ } else {
+ pr_debug("Target %d for pid %d matched fd %d\n",
+ te->epl.e.tfd, dinfo->pid, kid->idx);
+ nr_valid++;
+ }
+ } else {
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path), "/proc/%d/fd/%d",
+ dinfo->pid, slot.tfd);
+ if (access(path, F_OK)) {
+ pr_warn("Target %d not found for pid %d, ignoring\n",
+ te->epl.e.tfd, dinfo->pid);
+ te->epl.valid = 0;
+ } else {
+ pr_debug("Target %d for pid %d is accessible\n",
+ te->epl.e.tfd, dinfo->pid);
+ nr_valid++;
}
-
- pr_debug("Target %d for pid %d matched fd %d\n",
- te->epl.e.tfd, dinfo->pid, kid->idx);
}
+ }
+
+ if (nr_valid != dinfo->efe.n_tfd) {
+ size_t i = 0;
- if (pb_write_one(img_from_set(glob_imgset, CR_FD_EVENTPOLL_FILE),
- &dinfo->efe, PB_EVENTPOLL_FILE))
+ EventpollTfdEntry **tfd = xmalloc(sizeof(struct EventpollTfdEntry *) * nr_valid);
+ if (!tfd)
goto out;
+
+ list_for_each_entry(te, &dinfo->ep_list, epl.node) {
+ if (te->epl.valid)
+ tfd[i++] = &te->epl.e;
+ }
+
+ xfree(dinfo->efe.tfd);
+ dinfo->efe.tfd = tfd;
+ dinfo->efe.n_tfd = nr_valid;
}
+
+ pr_info_eventpoll("Dumping ", &dinfo->efe);
+ if (pb_write_one(img_from_set(glob_imgset, CR_FD_EVENTPOLL_FILE),
+ &dinfo->efe, PB_EVENTPOLL_FILE))
+ goto out;
}
ret = 0;
diff --git a/criu/include/fdinfo.h b/criu/include/fdinfo.h
index be516efce5d6..c9af47eeadc5 100644
--- a/criu/include/fdinfo.h
+++ b/criu/include/fdinfo.h
@@ -30,6 +30,7 @@ struct eventpoll_tfd_entry {
struct list_head node;
unsigned int gen_id;
int use_kcmp;
+ int valid;
};
union fdinfo_entries {
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index a96123679aa2..f2255d42e6f7 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -1744,6 +1744,7 @@ static int parse_fdinfo_pid_s(int pid, int fd, int type,
e = xmalloc(sizeof(union fdinfo_entries));
if (!e)
goto out;
+ e->epl.valid = 1;
eventpoll_tfd_entry__init(&e->epl.e);
--
2.7.4
More information about the CRIU
mailing list