1*f23ed011SPatrick Mooney /*
2*f23ed011SPatrick Mooney  * This file and its contents are supplied under the terms of the
3*f23ed011SPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
4*f23ed011SPatrick Mooney  * You may only use this file in accordance with the terms of version
5*f23ed011SPatrick Mooney  * 1.0 of the CDDL.
6*f23ed011SPatrick Mooney  *
7*f23ed011SPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
8*f23ed011SPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
9*f23ed011SPatrick Mooney  * http://www.illumos.org/license/CDDL.
10*f23ed011SPatrick Mooney  */
11*f23ed011SPatrick Mooney 
12*f23ed011SPatrick Mooney /*
13*f23ed011SPatrick Mooney  * Copyright 2022 Oxide Computer Company
14*f23ed011SPatrick Mooney  */
15*f23ed011SPatrick Mooney 
16*f23ed011SPatrick Mooney #include <stdio.h>
17*f23ed011SPatrick Mooney #include <unistd.h>
18*f23ed011SPatrick Mooney #include <stdlib.h>
19*f23ed011SPatrick Mooney #include <fcntl.h>
20*f23ed011SPatrick Mooney #include <dirent.h>
21*f23ed011SPatrick Mooney #include <port.h>
22*f23ed011SPatrick Mooney #include <err.h>
23*f23ed011SPatrick Mooney #include <assert.h>
24*f23ed011SPatrick Mooney 
25*f23ed011SPatrick Mooney #include <sys/types.h>
26*f23ed011SPatrick Mooney #include <sys/stat.h>
27*f23ed011SPatrick Mooney #include <sys/param.h>
28*f23ed011SPatrick Mooney #include <sys/poll.h>
29*f23ed011SPatrick Mooney 
30*f23ed011SPatrick Mooney /*
31*f23ed011SPatrick Mooney  * Attempt to trigger the #15036 regression.  This depends on a subsequent
32*f23ed011SPatrick Mooney  * allocation in the same slab setting a bit at a specific offset, so reliable
33*f23ed011SPatrick Mooney  * detection of the issue is a challenge.  This test uses brute force in its
34*f23ed011SPatrick Mooney  * attempt, but cannot guarantee to trigger the behavior on a system affected by
35*f23ed011SPatrick Mooney  * the issue.
36*f23ed011SPatrick Mooney  */
37*f23ed011SPatrick Mooney 
38*f23ed011SPatrick Mooney /*
39*f23ed011SPatrick Mooney  * We need regular files on a regular filesystem for fs_poll to be called.
40*f23ed011SPatrick Mooney  * Assume that we can find some in our own tests dir.
41*f23ed011SPatrick Mooney  *
42*f23ed011SPatrick Mooney  * As for repetitions, this is not especially consistent, so really hammer
43*f23ed011SPatrick Mooney  * things out of brute force.
44*f23ed011SPatrick Mooney  */
45*f23ed011SPatrick Mooney #define	FILE_SRC	"/opt/os-tests/tests"
46*f23ed011SPatrick Mooney #define	FILE_COUNT	10
47*f23ed011SPatrick Mooney #define	TEST_REPEAT	10000
48*f23ed011SPatrick Mooney 
49*f23ed011SPatrick Mooney static uint_t
find_test_files(const char * dir,uint_t count,int * result_fds)50*f23ed011SPatrick Mooney find_test_files(const char *dir, uint_t count, int *result_fds)
51*f23ed011SPatrick Mooney {
52*f23ed011SPatrick Mooney 	assert(count > 0);
53*f23ed011SPatrick Mooney 
54*f23ed011SPatrick Mooney 	DIR *dirp;
55*f23ed011SPatrick Mooney 
56*f23ed011SPatrick Mooney 	dirp = opendir(dir);
57*f23ed011SPatrick Mooney 	if (dirp == NULL) {
58*f23ed011SPatrick Mooney 		return (0);
59*f23ed011SPatrick Mooney 	}
60*f23ed011SPatrick Mooney 
61*f23ed011SPatrick Mooney 	dirent_t *de;
62*f23ed011SPatrick Mooney 	uint_t nvalid = 0;
63*f23ed011SPatrick Mooney 	while ((de = readdir(dirp)) != NULL) {
64*f23ed011SPatrick Mooney 		char path[MAXPATHLEN];
65*f23ed011SPatrick Mooney 		struct stat st;
66*f23ed011SPatrick Mooney 
67*f23ed011SPatrick Mooney 		(void) snprintf(path, sizeof (path), "%s/%s", dir, de->d_name);
68*f23ed011SPatrick Mooney 		if (lstat(path, &st) != 0 || (st.st_mode & S_IFREG) == 0) {
69*f23ed011SPatrick Mooney 			continue;
70*f23ed011SPatrick Mooney 		}
71*f23ed011SPatrick Mooney 		result_fds[nvalid] = open(path, O_RDONLY, 0);
72*f23ed011SPatrick Mooney 		if (result_fds[nvalid] < 0) {
73*f23ed011SPatrick Mooney 			continue;
74*f23ed011SPatrick Mooney 		}
75*f23ed011SPatrick Mooney 
76*f23ed011SPatrick Mooney 		nvalid++;
77*f23ed011SPatrick Mooney 		if (nvalid == count) {
78*f23ed011SPatrick Mooney 			break;
79*f23ed011SPatrick Mooney 		}
80*f23ed011SPatrick Mooney 	}
81*f23ed011SPatrick Mooney 
82*f23ed011SPatrick Mooney 	(void) closedir(dirp);
83*f23ed011SPatrick Mooney 	return (nvalid);
84*f23ed011SPatrick Mooney }
85*f23ed011SPatrick Mooney 
86*f23ed011SPatrick Mooney int
main(int argc,char * argv[])87*f23ed011SPatrick Mooney main(int argc, char *argv[])
88*f23ed011SPatrick Mooney {
89*f23ed011SPatrick Mooney 	int poll_fds[FILE_COUNT];
90*f23ed011SPatrick Mooney 
91*f23ed011SPatrick Mooney 	if (find_test_files(FILE_SRC, FILE_COUNT, poll_fds) != FILE_COUNT) {
92*f23ed011SPatrick Mooney 		errx(EXIT_FAILURE, "FAIL - count not open test files to poll");
93*f23ed011SPatrick Mooney 	}
94*f23ed011SPatrick Mooney 
95*f23ed011SPatrick Mooney 	for (uint_t i = 0; i < TEST_REPEAT; i++) {
96*f23ed011SPatrick Mooney 		int port_fds[FILE_COUNT];
97*f23ed011SPatrick Mooney 
98*f23ed011SPatrick Mooney 		for (uint_t j = 0; j < FILE_COUNT; j++) {
99*f23ed011SPatrick Mooney 			port_fds[j] = port_create();
100*f23ed011SPatrick Mooney 			if (port_fds[j] < 0) {
101*f23ed011SPatrick Mooney 				err(EXIT_FAILURE, "FAIL - port_create()");
102*f23ed011SPatrick Mooney 			}
103*f23ed011SPatrick Mooney 
104*f23ed011SPatrick Mooney 			int res = port_associate(port_fds[j], PORT_SOURCE_FD,
105*f23ed011SPatrick Mooney 			    (uintptr_t)poll_fds[j], POLLIN, NULL);
106*f23ed011SPatrick Mooney 			if (res != 0) {
107*f23ed011SPatrick Mooney 				err(EXIT_FAILURE, "FAIL - port_associate()");
108*f23ed011SPatrick Mooney 			}
109*f23ed011SPatrick Mooney 		}
110*f23ed011SPatrick Mooney 
111*f23ed011SPatrick Mooney 		for (uint_t j = 0; j < FILE_COUNT; j++) {
112*f23ed011SPatrick Mooney 			int res = port_dissociate(port_fds[j], PORT_SOURCE_FD,
113*f23ed011SPatrick Mooney 			    (uintptr_t)poll_fds[j]);
114*f23ed011SPatrick Mooney 			if (res != 0) {
115*f23ed011SPatrick Mooney 				err(EXIT_FAILURE, "FAIL - port_dissociate()");
116*f23ed011SPatrick Mooney 			}
117*f23ed011SPatrick Mooney 			(void) close(port_fds[j]);
118*f23ed011SPatrick Mooney 		}
119*f23ed011SPatrick Mooney 	}
120*f23ed011SPatrick Mooney 
121*f23ed011SPatrick Mooney 	(void) printf("PASS\n");
122*f23ed011SPatrick Mooney 	return (EXIT_SUCCESS);
123*f23ed011SPatrick Mooney }
124