diff --git a/cr-check.c b/cr-check.c index 875fe453c..df51484f6 100644 --- a/cr-check.c +++ b/cr-check.c @@ -27,6 +27,7 @@ #include "tty.h" #include "ptrace.h" #include "kerndat.h" +#include "timerfd.h" #include "tun.h" #include "namespaces.h" #include "pstree.h" @@ -596,6 +597,7 @@ int cr_check(void) ret |= check_mem_dirty_track(); ret |= check_posix_timers(); ret |= check_tun(); + ret |= check_timerfd(); ret |= check_mnt_id(); if (!ret) diff --git a/include/timerfd.h b/include/timerfd.h index 8e88f9f3d..41c683fea 100644 --- a/include/timerfd.h +++ b/include/timerfd.h @@ -26,6 +26,7 @@ static inline unsigned long rst_timerfd_len(void) return sizeof(*rst_timerfd) * rst_timerfd_nr; } +extern int check_timerfd(void); extern int is_timerfd_link(char *link); #ifndef TFD_TIMER_ABSTIME diff --git a/timerfd.c b/timerfd.c index 9075e9761..0fd9f1b91 100644 --- a/timerfd.c +++ b/timerfd.c @@ -10,6 +10,7 @@ #include "proc_parse.h" #include "rst-malloc.h" +#include "cr_options.h" #include "restorer.h" #include "timerfd.h" #include "pstree.h" @@ -35,6 +36,33 @@ struct timerfd_info { struct restore_timerfd *rst_timerfd; unsigned int rst_timerfd_nr; +int check_timerfd(void) +{ + int fd, ret = -1; + + if (opts.check_ms_kernel) { + pr_warn("Skipping timerfd support check\n"); + return 0; + } + + fd = timerfd_create(CLOCK_MONOTONIC, 0); + if (fd < 0) { + pr_perror("timerfd_create failed"); + return -1; + } else { + ret = ioctl(fd, TFD_IOC_SET_TICKS, NULL); + if (ret < 0) { + if (errno != EFAULT) + pr_perror("No timerfd support for c/r"); + else + ret = 0; + } + } + + close(fd); + return ret; +} + int is_timerfd_link(char *link) { return is_anon_link_type(link, "[timerfd]");