From af2600c52f6ec959036accadf2c1d47252b72d20 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Mon, 2 Nov 2020 17:50:54 +0000 Subject: [PATCH] rbd-nbd: use pidfd_open syscall if available If it is not fallback to just periodically polling the process still exists. Signed-off-by: Mykola Golub --- src/tools/rbd_nbd/rbd-nbd.cc | 48 +++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index 17592f01594..01be6ce0be7 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include "nbd-netlink.h" #include @@ -1431,24 +1432,53 @@ static void run_server(Preforker& forker, NBDServer *server, bool netlink_used) shutdown_async_signal_handler(); } -// Eventually it should be replaced with glibc' pidfd_open -// when it is widely available. -static int -pidfd_open(pid_t pid, unsigned int) +// Eventually it should be removed when pidfd_open is widely supported. + +static int wait_for_terminate_legacy(int pid, int timeout) { - std::string path = "/proc/" + stringify(pid); - int fd = open(path.c_str(), O_RDONLY); - if (fd == -1 && errno == ENOENT) { - errno = ESRCH; + for (int i = 0; ; i++) { + if (kill(pid, 0) == -1) { + if (errno == ESRCH) { + return 0; + } + int r = -errno; + cerr << "rbd-nbd: kill(" << pid << ", 0) failed: " + << cpp_strerror(r) << std::endl; + return r; + } + if (i >= timeout * 2) { + break; + } + usleep(500000); } - return fd; + cerr << "rbd-nbd: waiting for process exit timed out" << std::endl; + return -ETIMEDOUT; } +// Eventually it should be replaced with glibc' pidfd_open +// when it is widely available. + +#ifdef __NR_pidfd_open +static int pidfd_open(pid_t pid, unsigned int flags) +{ + return syscall(__NR_pidfd_open, pid, flags); +} +#else +static int pidfd_open(pid_t pid, unsigned int flags) +{ + errno = ENOSYS; + return -1; +} +#endif + static int wait_for_terminate(int pid, int timeout) { int fd = pidfd_open(pid, 0); if (fd == -1) { + if (errno == ENOSYS) { + return wait_for_terminate_legacy(pid, timeout); + } if (errno == -ESRCH) { return 0; } -- 2.39.5