From patchwork Wed Jul 4 15:51:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v5,05/19] epoll: kdat -- Check if we have KCMP_EPOLL_TFD support From: Cyrill Gorcunov X-Patchwork-Id: 8812 Message-Id: <20180704155147.29114-6-gorcunov@gmail.com> To: crml Cc: Andrey Vagin Date: Wed, 4 Jul 2018 18:51:33 +0300 We will need it to make sure the target files in epolls are present in current process. Signed-off-by: Cyrill Gorcunov --- criu/include/kerndat.h | 1 + criu/kerndat.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index 28a84fb0d583..af6b5c5c3a38 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -77,6 +77,7 @@ struct kerndat_s { bool has_pid_for_children_ns; bool x86_has_ptrace_fpu_xsave_bug; bool has_inotify_setnextwd; + bool has_kcmp_epoll_tfd; }; extern struct kerndat_s kdat; diff --git a/criu/kerndat.c b/criu/kerndat.c index 9b93487cc5ef..f26187f7bfbe 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -40,6 +40,7 @@ #include "prctl.h" #include "uffd.h" #include "vdso.h" +#include "kcmp.h" struct kerndat_s kdat = { }; @@ -819,6 +820,51 @@ int kerndat_has_inotify_setnextwd(void) return ret; } +int has_kcmp_epoll_tfd(void) +{ + kcmp_epoll_slot_t slot = { }; + int ret = -1, efd, tfd; + pid_t pid = getpid(); + struct epoll_event ev; + int pipefd[2]; + + efd = epoll_create(1); + if (efd < 0) { + pr_perror("Can't create epoll"); + return -1; + } + + memset(&ev, 0xff, sizeof(ev)); + ev.events = EPOLLIN | EPOLLOUT; + + if (pipe(pipefd)) { + pr_perror("Can't create pipe"); + close(efd); + return -1; + } + + tfd = pipefd[0]; + if (epoll_ctl(efd, EPOLL_CTL_ADD, tfd, &ev)) { + pr_perror("Can't add event"); + goto out; + } + + slot.efd = efd; + slot.tfd = tfd; + + if (syscall(SYS_kcmp, pid, pid, KCMP_EPOLL_TFD, tfd, &slot) == 0) + kdat.has_kcmp_epoll_tfd = true; + else + kdat.has_kcmp_epoll_tfd = false; + ret = 0; + +out: + close(pipefd[0]); + close(pipefd[1]); + close(efd); + return ret; +} + int __attribute__((weak)) kdat_x86_has_ptrace_fpu_xsave_bug(void) { return 0; @@ -1120,6 +1166,8 @@ int kerndat_init(void) ret = kerndat_x86_has_ptrace_fpu_xsave_bug(); if (!ret) ret = kerndat_has_inotify_setnextwd(); + if (!ret) + ret = has_kcmp_epoll_tfd(); kerndat_lsm(); kerndat_mmap_min_addr();