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