[CRIU] [PATCH 09/10] epoll: Ignore inaccessible targets
Kirill Tkhai
ktkhai at virtuozzo.com
Mon Mar 13 04:44:11 PDT 2017
On 28.02.2017 18:05, Cyrill Gorcunov wrote:
> 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))
Have you checked that this works correct, when nr_valid == 0 and tfd == NULL?
> + 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);
>
>
More information about the CRIU
mailing list