From 02d9bd1093c33c507aa0ee47aeccf150e304550e Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Mon, 27 Oct 2014 13:19:00 +0400 Subject: [PATCH] zdtm: check that process w/o file descriptors can be dumped and restored In addition it checks that criu closes all its descriptors Signed-off-by: Andrey Vagin Signed-off-by: Pavel Emelyanov --- test/zdtm/live/static/Makefile | 1 + test/zdtm/live/static/fd.c | 109 +++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 test/zdtm/live/static/fd.c diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile index 986a9182b..32e4be226 100644 --- a/test/zdtm/live/static/Makefile +++ b/test/zdtm/live/static/Makefile @@ -115,6 +115,7 @@ TST_NOFILE = \ dumpable01 \ dumpable02 \ remap_dead_pid \ + fd \ # jobctl00 \ TST_FILE = \ diff --git a/test/zdtm/live/static/fd.c b/test/zdtm/live/static/fd.c new file mode 100644 index 000000000..12bda5ff7 --- /dev/null +++ b/test/zdtm/live/static/fd.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zdtmtst.h" +#include "lock.h" + +const char *test_doc = "Check that criu closes up all its descriptors"; +const char *test_author = "Andrew Vagin "; + +int main(int argc, char **argv) +{ + struct dirent *de; + char pfd[PATH_MAX]; + mutex_t *lock; + int status; + pid_t pid; + DIR *d; + + test_init(argc, argv); + + lock = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (lock == MAP_FAILED) + return 1; + + mutex_init(lock); + mutex_lock(lock); + + pid = fork(); + if (pid < 0) { + err("fork()"); + return 1; + } + + if (pid == 0) { + + d = opendir("/proc/self/fd"); + if (d == NULL) + return 1; + + while ((de = readdir(d))) { + int fd; + + if (de->d_name[0] == '.') + continue; + + fd = atoi(de->d_name); + if (dirfd(d) == fd) + continue; + close(fd); + } + + closedir(d); + mutex_unlock(lock); + + test_waitsig(); + + return 0; + } + + mutex_lock(lock); + + test_daemon(); + test_waitsig(); + + snprintf(pfd, sizeof(pfd), "/proc/%d/fd", pid); + d = opendir(pfd); + if (d == NULL) + return 2; + + while ((de = readdir(d))) { + int ret; + + if (de->d_name[0] == '.') + continue; + + ret = readlinkat(dirfd(d), de->d_name, pfd, sizeof(pfd) - 1); + if (ret < 0) { + err("readlink"); + ret = 0; + } + pfd[ret] = '\0'; + fail("Unexpected fd: %s -> %s\n", de->d_name, pfd); + return 1; + } + + closedir(d); + kill(pid, SIGTERM); + + if (waitpid(pid, &status, 0) != pid) { + err("waitpid()"); + return 1; + } + + if (status != 0) { + fail("%d:%d:%d:%d", WIFEXITED(status), WEXITSTATUS(status), + WIFSIGNALED(status), WTERMSIG(status)); + return 1; + } + + pass(); + + return 0; +}