iopoll-leak.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #include "../config-host.h"
  2. /* SPDX-License-Identifier: MIT */
  3. /*
  4. * Description: test a mem leak with IOPOLL
  5. */
  6. #include <errno.h>
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <fcntl.h>
  12. #include <sys/types.h>
  13. #include <sys/wait.h>
  14. #include "helpers.h"
  15. #include "liburing.h"
  16. #define FILE_SIZE (128 * 1024)
  17. #define BS 4096
  18. #define BUFFERS (FILE_SIZE / BS)
  19. static int do_iopoll(const char *fname)
  20. {
  21. struct io_uring_sqe *sqe;
  22. struct io_uring ring;
  23. struct iovec *iov;
  24. int fd;
  25. fd = open(fname, O_RDONLY | O_DIRECT);
  26. if (fd < 0) {
  27. perror("open");
  28. return T_EXIT_SKIP;
  29. }
  30. iov = t_create_buffers(1, 4096);
  31. t_create_ring(2, &ring, IORING_SETUP_IOPOLL);
  32. sqe = io_uring_get_sqe(&ring);
  33. io_uring_prep_read(sqe, fd, iov->iov_base, iov->iov_len, 0);
  34. io_uring_submit(&ring);
  35. close(fd);
  36. return T_EXIT_PASS;
  37. }
  38. static int test(const char *fname)
  39. {
  40. if (fork()) {
  41. int stat;
  42. wait(&stat);
  43. return WEXITSTATUS(stat);
  44. } else {
  45. int ret;
  46. ret = do_iopoll(fname);
  47. exit(ret);
  48. }
  49. }
  50. int main(int argc, char *argv[])
  51. {
  52. char buf[256];
  53. char *fname;
  54. int i, ret;
  55. if (argc > 1) {
  56. fname = argv[1];
  57. } else {
  58. srand((unsigned)time(NULL));
  59. snprintf(buf, sizeof(buf), ".iopoll-leak-%u-%u",
  60. (unsigned)rand(), (unsigned)getpid());
  61. fname = buf;
  62. t_create_file(fname, FILE_SIZE);
  63. }
  64. for (i = 0; i < 16; i++) {
  65. ret = test(fname);
  66. if (ret == T_EXIT_SKIP || ret == T_EXIT_FAIL)
  67. break;
  68. }
  69. if (fname != argv[1])
  70. unlink(fname);
  71. return ret;
  72. }