Add a test with file ref dependency, which is actually checks that the files are removed and put. Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> --- test/ring-leak.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/test/ring-leak.c b/test/ring-leak.c index f8f043c..5b739ad 100644 --- a/test/ring-leak.c +++ b/test/ring-leak.c @@ -131,12 +131,84 @@ static int test_iowq_request_cancel(void) ret = read(fds[0], buffer, 10); if (ret < 0) perror("read"); + close(fds[0]); + return 0; +} + +static int test_scm_cycles(bool update) +{ + char buffer[128]; + struct io_uring ring; + int i, ret; + int sp[2], fds[2], reg_fds[4]; + + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) { + perror("Failed to create Unix-domain socket pair\n"); + return 1; + } + ret = io_uring_queue_init(8, &ring, 0); + if (ret < 0) { + fprintf(stderr, "failed to init io_uring: %s\n", strerror(-ret)); + return ret; + } + if (pipe(fds)) { + perror("pipe"); + return -1; + } + send_fd(sp[0], ring.ring_fd); + + /* register an empty set for updates */ + if (update) { + for (i = 0; i < 4; i++) + reg_fds[i] = -1; + ret = io_uring_register_files(&ring, reg_fds, 4); + if (ret) { + fprintf(stderr, "file_register: %d\n", ret); + return ret; + } + } + + reg_fds[0] = fds[0]; + reg_fds[1] = fds[1]; + reg_fds[2] = sp[0]; + reg_fds[3] = sp[1]; + if (update) { + ret = io_uring_register_files_update(&ring, 0, reg_fds, 4); + if (ret != 4) { + fprintf(stderr, "file_register: %d\n", ret); + return ret; + } + } else { + ret = io_uring_register_files(&ring, reg_fds, 4); + if (ret) { + fprintf(stderr, "file_register: %d\n", ret); + return ret; + } + } + + close(fds[1]); + close(sp[0]); + close(sp[1]); + + /* should unregister files and close the write fd */ + io_uring_queue_exit(&ring); + + /* + * We're trying to wait for the ring to "really" exit, that will be + * done async. For that rely on the registered write end to be closed + * after ring quiesce, so failing read from the other pipe end. + */ + ret = read(fds[0], buffer, 10); + if (ret < 0) + perror("read"); + close(fds[0]); return 0; } int main(int argc, char *argv[]) { int sp[2], pid, ring_fd, ret; + int i; if (argc > 1) return 0; @@ -147,6 +219,18 @@ int main(int argc, char *argv[]) return 1; } + for (i = 0; i < 2; i++) { + bool update = !!(i & 1); + + ret = test_scm_cycles(update); + if (ret) { + fprintf(stderr, "test_scm_cycles() failed %i\n", + update); + return 1; + } + break; + } + if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) { perror("Failed to create Unix-domain socket pair\n"); return 1; -- 2.35.2