iopoll-leak.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. if (errno == EINVAL || errno == EPERM || errno == EACCES)
  28. return T_EXIT_SKIP;
  29. perror("open");
  30. return T_EXIT_SKIP;
  31. }
  32. iov = t_create_buffers(1, 4096);
  33. t_create_ring(2, &ring, IORING_SETUP_IOPOLL);
  34. sqe = io_uring_get_sqe(&ring);
  35. io_uring_prep_read(sqe, fd, iov->iov_base, iov->iov_len, 0);
  36. io_uring_submit(&ring);
  37. close(fd);
  38. free(iov->iov_base);
  39. free(iov);
  40. return T_EXIT_PASS;
  41. }
  42. static int test(const char *fname)
  43. {
  44. if (fork()) {
  45. int stat;
  46. wait(&stat);
  47. return WEXITSTATUS(stat);
  48. } else {
  49. int ret;
  50. ret = do_iopoll(fname);
  51. exit(ret);
  52. }
  53. }
  54. int main(int argc, char *argv[])
  55. {
  56. char buf[256];
  57. char *fname;
  58. int i, ret;
  59. if (argc > 1) {
  60. fname = argv[1];
  61. } else {
  62. srand((unsigned)time(NULL));
  63. snprintf(buf, sizeof(buf), ".iopoll-leak-%u-%u",
  64. (unsigned)rand(), (unsigned)getpid());
  65. fname = buf;
  66. t_create_file(fname, FILE_SIZE);
  67. }
  68. for (i = 0; i < 16; i++) {
  69. ret = test(fname);
  70. if (ret == T_EXIT_SKIP || ret == T_EXIT_FAIL)
  71. break;
  72. }
  73. if (fname != argv[1])
  74. unlink(fname);
  75. return ret;
  76. }