xref: /xnu-10002.1.13/tests/vfs/freeable_vnodes.c (revision 1031c584a5e37aff177559b9f69dbd3c8c3fd30a)
1*1031c584SApple OSS Distributions /* xcrun -sdk iphoneos.internal clang -ldarwintest -o freeable_vnodes freeable_vnodes.c -g -Weverything */
2*1031c584SApple OSS Distributions 
3*1031c584SApple OSS Distributions #include <darwintest.h>
4*1031c584SApple OSS Distributions #include <darwintest_utils.h>
5*1031c584SApple OSS Distributions 
6*1031c584SApple OSS Distributions #include <unistd.h>
7*1031c584SApple OSS Distributions #include <stdlib.h>
8*1031c584SApple OSS Distributions #include <stdio.h>
9*1031c584SApple OSS Distributions #include <signal.h>
10*1031c584SApple OSS Distributions #include <fcntl.h>
11*1031c584SApple OSS Distributions #include <string.h>
12*1031c584SApple OSS Distributions #include <sys/sysctl.h>
13*1031c584SApple OSS Distributions #include <sys/mman.h>
14*1031c584SApple OSS Distributions #include <sys/stat.h>
15*1031c584SApple OSS Distributions #include <sys/socket.h>
16*1031c584SApple OSS Distributions #include <TargetConditionals.h>
17*1031c584SApple OSS Distributions 
18*1031c584SApple OSS Distributions static pid_t vnoder_pid = -1;
19*1031c584SApple OSS Distributions static uint32_t maxvnodes = 0;
20*1031c584SApple OSS Distributions T_GLOBAL_META(T_META_NAMESPACE("xnu.vfs"));
21*1031c584SApple OSS Distributions 
22*1031c584SApple OSS Distributions #if TARGET_OS_IOS
23*1031c584SApple OSS Distributions 
24*1031c584SApple OSS Distributions static char *dlpaths[] = {
25*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/HomeAutomationFlowDelegatePlugin.bundle/HomeAutomationFlowDelegatePlugin",
26*1031c584SApple OSS Distributions 	"/System/Library/NanoPreferenceBundles/Applications/NanoPassbookBridgeSettings.bundle/NanoPassbookBridgeSettings",
27*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/MessagesFlowDelegatePlugin.bundle/MessagesFlowDelegatePlugin",
28*1031c584SApple OSS Distributions 	"/System/Library/NanoPreferenceBundles/Discover/HealthAndFitnessPlugin.bundle/HealthAndFitnessPlugin",
29*1031c584SApple OSS Distributions 	"/System/Library/NanoPreferenceBundles/SetupBundles/DepthCompanionSetup.bundle/DepthCompanionSetup",
30*1031c584SApple OSS Distributions 	"/System/Library/PreferenceBundles/DigitalSeparationSettings.bundle/DigitalSeparationSettings",
31*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/NotebookFlowPlugin.bundle/NotebookFlowPlugin",
32*1031c584SApple OSS Distributions 	"/System/Library/NanoPreferenceBundles/Discover/UserGuidePlugin.bundle/UserGuidePlugin",
33*1031c584SApple OSS Distributions 	"/System/Library/PreferenceBundles/NotificationsSettings.bundle/NotificationsSettings",
34*1031c584SApple OSS Distributions 	"/System/Library/PreferenceBundles/AssistantSettings.bundle/AssistantSettings",
35*1031c584SApple OSS Distributions 	"/System/Library/PreferenceBundles/SettingsCellular.bundle/SettingsCellular",
36*1031c584SApple OSS Distributions 	"/System/Library/PreferenceBundles/FocusSettings.bundle/FocusSettings",
37*1031c584SApple OSS Distributions 	"/private/preboot/Cryptexes/App/System/Library/PreferenceBundles/MobileSafariSettings.bundle/MobileSafariSettings",
38*1031c584SApple OSS Distributions 	NULL
39*1031c584SApple OSS Distributions };
40*1031c584SApple OSS Distributions 
41*1031c584SApple OSS Distributions #elif TARGET_OS_WATCH
42*1031c584SApple OSS Distributions 
43*1031c584SApple OSS Distributions static char *dlpaths[] = {
44*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/HomeAutomationFlowDelegatePlugin.bundle/HomeAutomationFlowDelegatePlugin",
45*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/MessagesFlowDelegatePlugin.bundle/MessagesFlowDelegatePlugin",
46*1031c584SApple OSS Distributions 	"/System/Library/PreferenceBundles/NanoAccessibilitySettings.bundle/NanoAccessibilitySettings",
47*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/NotebookFlowPlugin.bundle/NotebookFlowPlugin",
48*1031c584SApple OSS Distributions 	NULL
49*1031c584SApple OSS Distributions };
50*1031c584SApple OSS Distributions 
51*1031c584SApple OSS Distributions #elif TARGET_OS_OSX
52*1031c584SApple OSS Distributions 
53*1031c584SApple OSS Distributions static char *dlpaths[] = {
54*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/HomeAutomationFlowDelegatePlugin.bundle/Contents/MacOS/HomeAutomationFlowDelegatePlugin",
55*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/MessagesFlowDelegatePlugin.bundle/Contents/MacOS/MessagesFlowDelegatePlugin",
56*1031c584SApple OSS Distributions 	"/System/Library/Assistant/FlowDelegatePlugins/NotebookFlowPlugin.bundle/Contents/MacOS/NotebookFlowPlugin",
57*1031c584SApple OSS Distributions 	NULL
58*1031c584SApple OSS Distributions };
59*1031c584SApple OSS Distributions 
60*1031c584SApple OSS Distributions #else
61*1031c584SApple OSS Distributions 
62*1031c584SApple OSS Distributions static char *dlpaths[] = {
63*1031c584SApple OSS Distributions 	NULL
64*1031c584SApple OSS Distributions };
65*1031c584SApple OSS Distributions 
66*1031c584SApple OSS Distributions #endif
67*1031c584SApple OSS Distributions 
68*1031c584SApple OSS Distributions static uint32_t
get_sysctl_int(char * sysctl_name)69*1031c584SApple OSS Distributions get_sysctl_int(char *sysctl_name)
70*1031c584SApple OSS Distributions {
71*1031c584SApple OSS Distributions 	uint32_t max_vnodes = 0;
72*1031c584SApple OSS Distributions 	size_t length = sizeof(max_vnodes);
73*1031c584SApple OSS Distributions 	int return_code = 0;
74*1031c584SApple OSS Distributions 
75*1031c584SApple OSS Distributions 	return_code = sysctlbyname(sysctl_name, &max_vnodes, &length, NULL, 0);
76*1031c584SApple OSS Distributions 	T_QUIET;
77*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(return_code, "sysctl call should return 0");
78*1031c584SApple OSS Distributions 	return max_vnodes;
79*1031c584SApple OSS Distributions }
80*1031c584SApple OSS Distributions 
81*1031c584SApple OSS Distributions #define MINVNODES_FOR_TEST 200
82*1031c584SApple OSS Distributions #define MAXVNODES_FOR_TEST 18000
83*1031c584SApple OSS Distributions 
84*1031c584SApple OSS Distributions static void
run_vnoder(void)85*1031c584SApple OSS Distributions run_vnoder(void)
86*1031c584SApple OSS Distributions {
87*1031c584SApple OSS Distributions 	void *buffer;
88*1031c584SApple OSS Distributions 	uint32_t i = 0;
89*1031c584SApple OSS Distributions 	uint32_t current_num = 0;
90*1031c584SApple OSS Distributions 	uint32_t num_files =  maxvnodes - MINVNODES_FOR_TEST;
91*1031c584SApple OSS Distributions 	int fd = -1;
92*1031c584SApple OSS Distributions 	int dir_fd = -1;
93*1031c584SApple OSS Distributions 	char dirpath[PATH_MAX];
94*1031c584SApple OSS Distributions 	char filepath[NAME_MAX];
95*1031c584SApple OSS Distributions 
96*1031c584SApple OSS Distributions 	T_WITH_ERRNO;
97*1031c584SApple OSS Distributions 
98*1031c584SApple OSS Distributions 	/* Create a temporary working directory */
99*1031c584SApple OSS Distributions 	sprintf(dirpath, "%s/tmp-mmap-bomb-dir.%d", dt_tmpdir(), getpid());
100*1031c584SApple OSS Distributions 	T_QUIET;
101*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(mkdir(dirpath, S_IRWXU | S_IRWXG ), NULL);
102*1031c584SApple OSS Distributions 
103*1031c584SApple OSS Distributions 	T_LOG("Created test dir %s\n", dirpath);
104*1031c584SApple OSS Distributions 
105*1031c584SApple OSS Distributions 	T_QUIET;
106*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(dir_fd = open(dirpath, O_RDONLY), NULL);
107*1031c584SApple OSS Distributions 
108*1031c584SApple OSS Distributions 	/* use mmap to exhaust vnode pool */
109*1031c584SApple OSS Distributions 	uint32_t log_interval = (num_files / 4);
110*1031c584SApple OSS Distributions 	uint32_t next_test_log_number = log_interval;
111*1031c584SApple OSS Distributions 	T_LOG("trying to map %u files, progress every %u files\n", num_files, log_interval);
112*1031c584SApple OSS Distributions 	/*
113*1031c584SApple OSS Distributions 	 * This loop can take an ideterminate amount of time on different devices since the
114*1031c584SApple OSS Distributions 	 * it is based on file creation (which is rate limited by the SEP) and the number we
115*1031c584SApple OSS Distributions 	 * will attempt to create. At some point it should be replaced by walking a large hierarchy
116*1031c584SApple OSS Distributions 	 * (like /System) and mapping those files instead of creating files.
117*1031c584SApple OSS Distributions 	 */
118*1031c584SApple OSS Distributions 	for (i = 0; i < num_files; ++i) {
119*1031c584SApple OSS Distributions 		if (i == next_test_log_number) {
120*1031c584SApple OSS Distributions 			T_LOG("created and mapped %u files so far\n", next_test_log_number);
121*1031c584SApple OSS Distributions 			next_test_log_number += log_interval;
122*1031c584SApple OSS Distributions 			current_num = get_sysctl_int("vfs.vnstats.num_vnodes");
123*1031c584SApple OSS Distributions 			if (current_num >= (maxvnodes + 5000)) {
124*1031c584SApple OSS Distributions 				T_LOG("numvnodes is >= maxvnodes + 5000 (%u), done with creation and mmap loop\n",
125*1031c584SApple OSS Distributions 				    current_num);
126*1031c584SApple OSS Distributions 				break;
127*1031c584SApple OSS Distributions 			}
128*1031c584SApple OSS Distributions 		}
129*1031c584SApple OSS Distributions 
130*1031c584SApple OSS Distributions 		sprintf(filepath, "file-%d", i);
131*1031c584SApple OSS Distributions 
132*1031c584SApple OSS Distributions 		T_QUIET;
133*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(fd = openat(dir_fd, filepath, O_CREAT | O_RDWR, 0666), NULL);
134*1031c584SApple OSS Distributions 
135*1031c584SApple OSS Distributions 		T_QUIET;
136*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(ftruncate(fd, (off_t)PAGE_SIZE), NULL);
137*1031c584SApple OSS Distributions 
138*1031c584SApple OSS Distributions 		T_QUIET;
139*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(unlinkat(dir_fd, filepath, 0), NULL);
140*1031c584SApple OSS Distributions 
141*1031c584SApple OSS Distributions 		T_QUIET;
142*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(buffer = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_FILE | MAP_NOCACHE | MAP_PRIVATE, fd, 0), NULL);
143*1031c584SApple OSS Distributions 
144*1031c584SApple OSS Distributions 		T_QUIET;
145*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(close(fd), NULL);
146*1031c584SApple OSS Distributions 	}
147*1031c584SApple OSS Distributions 	T_LOG("created and mapped %u files\n", i);
148*1031c584SApple OSS Distributions 
149*1031c584SApple OSS Distributions 	T_QUIET;
150*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(dir_fd), NULL);
151*1031c584SApple OSS Distributions 
152*1031c584SApple OSS Distributions 	T_QUIET;
153*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(rmdir(dirpath), NULL);
154*1031c584SApple OSS Distributions }
155*1031c584SApple OSS Distributions 
156*1031c584SApple OSS Distributions static void
cleanup(void)157*1031c584SApple OSS Distributions cleanup(void)
158*1031c584SApple OSS Distributions {
159*1031c584SApple OSS Distributions 	if (vnoder_pid > 0) {
160*1031c584SApple OSS Distributions 		T_LOG("Killing vnoder pid in cleanup: %d", vnoder_pid);
161*1031c584SApple OSS Distributions 		kill(vnoder_pid, SIGKILL);
162*1031c584SApple OSS Distributions 	}
163*1031c584SApple OSS Distributions }
164*1031c584SApple OSS Distributions 
165*1031c584SApple OSS Distributions 
166*1031c584SApple OSS Distributions T_DECL(vnode_max_increase,
167*1031c584SApple OSS Distributions     "Consume vnodes to cause the max vnodes available to increase",
168*1031c584SApple OSS Distributions     T_META_REQUIRES_SYSCTL_EQ("vfs.vnstats.vn_dealloc_level", 1),
169*1031c584SApple OSS Distributions     T_META_RADAR_COMPONENT_NAME("xnu"),
170*1031c584SApple OSS Distributions     T_META_RADAR_COMPONENT_VERSION("VFS"))
171*1031c584SApple OSS Distributions {
172*1031c584SApple OSS Distributions 	int sock_fd[2];
173*1031c584SApple OSS Distributions 	char buf[10];
174*1031c584SApple OSS Distributions 	uint32_t initial_num = 0, current_num = 0;
175*1031c584SApple OSS Distributions 	uint32_t deallocateable_vnodes = 0;
176*1031c584SApple OSS Distributions 	uint32_t deallocateable_busy_vnodes = 0;
177*1031c584SApple OSS Distributions 	uint32_t vnode_delta = 100;
178*1031c584SApple OSS Distributions 	uint32_t timeout = 10;
179*1031c584SApple OSS Distributions 	uint32_t i = 0;
180*1031c584SApple OSS Distributions 
181*1031c584SApple OSS Distributions 	T_ATEND(cleanup);
182*1031c584SApple OSS Distributions 	T_WITH_ERRNO;
183*1031c584SApple OSS Distributions 
184*1031c584SApple OSS Distributions 	T_SETUPBEGIN;
185*1031c584SApple OSS Distributions 	/*
186*1031c584SApple OSS Distributions 	 * We use this to handshake certain actions between this process and its
187*1031c584SApple OSS Distributions 	 * child.
188*1031c584SApple OSS Distributions 	 */
189*1031c584SApple OSS Distributions 	T_QUIET;
190*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fd),
191*1031c584SApple OSS Distributions 	    NULL);
192*1031c584SApple OSS Distributions 
193*1031c584SApple OSS Distributions 	maxvnodes = get_sysctl_int("kern.maxvnodes");
194*1031c584SApple OSS Distributions 	T_LOG("max vnodes: %d", maxvnodes);
195*1031c584SApple OSS Distributions 	if (maxvnodes > MAXVNODES_FOR_TEST) {
196*1031c584SApple OSS Distributions 		T_SKIP("maxvnodes can't be more than %d for test", MAXVNODES_FOR_TEST);
197*1031c584SApple OSS Distributions 	} else if (maxvnodes <= MINVNODES_FOR_TEST) {
198*1031c584SApple OSS Distributions 		T_SKIP("maxvnodes can't be less than %d for test", MINVNODES_FOR_TEST);
199*1031c584SApple OSS Distributions 	}
200*1031c584SApple OSS Distributions 
201*1031c584SApple OSS Distributions 	initial_num = get_sysctl_int("vfs.vnstats.num_vnodes");
202*1031c584SApple OSS Distributions 	T_LOG("Initial num vnodes: %d", initial_num);
203*1031c584SApple OSS Distributions 
204*1031c584SApple OSS Distributions 	T_SETUPEND;
205*1031c584SApple OSS Distributions 
206*1031c584SApple OSS Distributions 	T_QUIET;
207*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(vnoder_pid = fork(), NULL);
208*1031c584SApple OSS Distributions 
209*1031c584SApple OSS Distributions 	if (vnoder_pid == 0) { /* child */
210*1031c584SApple OSS Distributions 		T_QUIET;
211*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(close(sock_fd[0]), NULL);
212*1031c584SApple OSS Distributions 
213*1031c584SApple OSS Distributions 		run_vnoder();
214*1031c584SApple OSS Distributions 
215*1031c584SApple OSS Distributions 		/* now let parent know we're done with creating all the vnodes */
216*1031c584SApple OSS Distributions 		T_QUIET;
217*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(write(sock_fd[1], "done", sizeof("done")), NULL);
218*1031c584SApple OSS Distributions 
219*1031c584SApple OSS Distributions 		/* wait for parent to set us to send us a signal */
220*1031c584SApple OSS Distributions 		T_QUIET;
221*1031c584SApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(read(sock_fd[1], buf, sizeof(buf)), NULL);
222*1031c584SApple OSS Distributions 
223*1031c584SApple OSS Distributions 		pause();
224*1031c584SApple OSS Distributions 
225*1031c584SApple OSS Distributions 		exit(0);
226*1031c584SApple OSS Distributions 	}
227*1031c584SApple OSS Distributions 
228*1031c584SApple OSS Distributions 	T_QUIET;
229*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(close(sock_fd[1]), NULL);
230*1031c584SApple OSS Distributions 
231*1031c584SApple OSS Distributions 	/* wait for child to run and run up the vnodes */
232*1031c584SApple OSS Distributions 	T_QUIET;
233*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(read(sock_fd[0], buf, sizeof(buf)), NULL);
234*1031c584SApple OSS Distributions 
235*1031c584SApple OSS Distributions 	int num_getpaths = 0;
236*1031c584SApple OSS Distributions 	for (i = 0; i < 5 && dlpaths[0] != NULL; i++) {
237*1031c584SApple OSS Distributions 		for (int j = 0; dlpaths[j] != NULL; j++) {
238*1031c584SApple OSS Distributions 			int dlpath_fd;
239*1031c584SApple OSS Distributions 			char path[256] = {0};
240*1031c584SApple OSS Distributions 			struct stat sb;
241*1031c584SApple OSS Distributions 
242*1031c584SApple OSS Distributions 			if (stat(dlpaths[j], &sb) != -1) {
243*1031c584SApple OSS Distributions 				T_QUIET;
244*1031c584SApple OSS Distributions 				T_ASSERT_POSIX_SUCCESS(dlpath_fd = open(dlpaths[j], O_RDONLY), NULL);
245*1031c584SApple OSS Distributions 				T_QUIET;
246*1031c584SApple OSS Distributions 				T_ASSERT_POSIX_SUCCESS(fcntl(dlpath_fd, F_GETPATH, &path), "path is %s, iteration number is %d and path number is %d", dlpaths[j], i + 1, j + 1);
247*1031c584SApple OSS Distributions 				T_QUIET;
248*1031c584SApple OSS Distributions 				T_ASSERT_POSIX_SUCCESS(close(dlpath_fd), NULL);
249*1031c584SApple OSS Distributions 				num_getpaths++;
250*1031c584SApple OSS Distributions 			}
251*1031c584SApple OSS Distributions 		}
252*1031c584SApple OSS Distributions 	}
253*1031c584SApple OSS Distributions 	T_LOG("Num getpaths done = %d", num_getpaths);
254*1031c584SApple OSS Distributions 
255*1031c584SApple OSS Distributions 	current_num = get_sysctl_int("vfs.vnstats.num_vnodes");
256*1031c584SApple OSS Distributions 	T_LOG("num vnodes after vnoder: %d", current_num);
257*1031c584SApple OSS Distributions 
258*1031c584SApple OSS Distributions 	T_QUIET;
259*1031c584SApple OSS Distributions 	T_ASSERT_GT(current_num, maxvnodes,
260*1031c584SApple OSS Distributions 	    "vnode maximum should increase under vnode presssure");
261*1031c584SApple OSS Distributions 
262*1031c584SApple OSS Distributions 	T_LOG("Killing vnoder (pid %d) to free up held vnodes", vnoder_pid);
263*1031c584SApple OSS Distributions 	T_QUIET;
264*1031c584SApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(write(sock_fd[0], "done", sizeof("done")), NULL);
265*1031c584SApple OSS Distributions 	kill(vnoder_pid, SIGKILL);
266*1031c584SApple OSS Distributions 	vnoder_pid = -1;
267*1031c584SApple OSS Distributions 
268*1031c584SApple OSS Distributions 	T_LOG("Waiting up to %ds for vnodes to be deallocated", timeout);
269*1031c584SApple OSS Distributions 	for (i = 0; i < timeout; i++) {
270*1031c584SApple OSS Distributions 		sleep(1);
271*1031c584SApple OSS Distributions 		deallocateable_vnodes = get_sysctl_int(
272*1031c584SApple OSS Distributions 			"vfs.vnstats.num_deallocable_vnodes");
273*1031c584SApple OSS Distributions 		deallocateable_busy_vnodes = get_sysctl_int(
274*1031c584SApple OSS Distributions 			"vfs.vnstats.num_deallocable_busy_vnodes");
275*1031c584SApple OSS Distributions 
276*1031c584SApple OSS Distributions 		T_LOG("deallocateable_vnodes after %d second%s : %d",
277*1031c584SApple OSS Distributions 		    i + 1, (i == 0) ? "" : "s", deallocateable_vnodes);
278*1031c584SApple OSS Distributions 		T_LOG("deallocateable_busy_vnodes after %d second%s : %d",
279*1031c584SApple OSS Distributions 		    i + 1, (i == 0) ? "" : "s", deallocateable_busy_vnodes);
280*1031c584SApple OSS Distributions 
281*1031c584SApple OSS Distributions 		if (deallocateable_vnodes < vnode_delta) {
282*1031c584SApple OSS Distributions 			break;
283*1031c584SApple OSS Distributions 		}
284*1031c584SApple OSS Distributions 		/* This can happen because we don't fetch atomically */
285*1031c584SApple OSS Distributions 		if (deallocateable_busy_vnodes > deallocateable_vnodes) {
286*1031c584SApple OSS Distributions 			deallocateable_busy_vnodes = deallocateable_vnodes;
287*1031c584SApple OSS Distributions 		}
288*1031c584SApple OSS Distributions 
289*1031c584SApple OSS Distributions 		if ((i == (timeout - 1)) &&
290*1031c584SApple OSS Distributions 		    ((deallocateable_vnodes - deallocateable_busy_vnodes) < vnode_delta)) {
291*1031c584SApple OSS Distributions 			break;
292*1031c584SApple OSS Distributions 		}
293*1031c584SApple OSS Distributions 	}
294*1031c584SApple OSS Distributions 
295*1031c584SApple OSS Distributions 	T_QUIET;
296*1031c584SApple OSS Distributions 	T_ASSERT_NE(i, timeout, "Deallocateable vnodes should drop in under %ds",
297*1031c584SApple OSS Distributions 	    timeout);
298*1031c584SApple OSS Distributions 
299*1031c584SApple OSS Distributions 	current_num = get_sysctl_int("vfs.vnstats.num_vnodes");
300*1031c584SApple OSS Distributions 	T_LOG("num vnodes after killing vnoder: %d", current_num);
301*1031c584SApple OSS Distributions 
302*1031c584SApple OSS Distributions 	T_QUIET;
303*1031c584SApple OSS Distributions 	T_ASSERT_LE(current_num, maxvnodes + deallocateable_busy_vnodes + vnode_delta,
304*1031c584SApple OSS Distributions 	    "vnode maximum should be within %d of the initial maximum",
305*1031c584SApple OSS Distributions 	    vnode_delta);
306*1031c584SApple OSS Distributions }
307