1*ea7b7d8aSRobert Mustacchi /*
2*ea7b7d8aSRobert Mustacchi * This file and its contents are supplied under the terms of the
3*ea7b7d8aSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
4*ea7b7d8aSRobert Mustacchi * You may only use this file in accordance with the terms of version
5*ea7b7d8aSRobert Mustacchi * 1.0 of the CDDL.
6*ea7b7d8aSRobert Mustacchi *
7*ea7b7d8aSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
8*ea7b7d8aSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
9*ea7b7d8aSRobert Mustacchi * http://www.illumos.org/license/CDDL.
10*ea7b7d8aSRobert Mustacchi */
11*ea7b7d8aSRobert Mustacchi
12*ea7b7d8aSRobert Mustacchi /*
13*ea7b7d8aSRobert Mustacchi * Copyright 2024 Oxide Computer Company
14*ea7b7d8aSRobert Mustacchi */
15*ea7b7d8aSRobert Mustacchi
16*ea7b7d8aSRobert Mustacchi /*
17*ea7b7d8aSRobert Mustacchi * Basic tests for statvfs and fstatvfs. In particular we want to verify the
18*ea7b7d8aSRobert Mustacchi * following:
19*ea7b7d8aSRobert Mustacchi *
20*ea7b7d8aSRobert Mustacchi * - We can generate basic statvfs(2) errors like ENOENT, ENOTDIR, and EFAULT.
21*ea7b7d8aSRobert Mustacchi * - We can generate basic fstatvfs(2) errors like EBADF and EFAULT.
22*ea7b7d8aSRobert Mustacchi * - statvfs and fstatvfs work on basic file systems like /, ctfs, bootfs,
23*ea7b7d8aSRobert Mustacchi * objfs, procfs, tmpfs, etc. Additional paths will be allowed on the command
24*ea7b7d8aSRobert Mustacchi * line for this.
25*ea7b7d8aSRobert Mustacchi * - fstatvfs works on sockets and devices, but not pipes
26*ea7b7d8aSRobert Mustacchi */
27*ea7b7d8aSRobert Mustacchi
28*ea7b7d8aSRobert Mustacchi #include <stdlib.h>
29*ea7b7d8aSRobert Mustacchi #include <sys/types.h>
30*ea7b7d8aSRobert Mustacchi #include <sys/statvfs.h>
31*ea7b7d8aSRobert Mustacchi #include <stdbool.h>
32*ea7b7d8aSRobert Mustacchi #include <err.h>
33*ea7b7d8aSRobert Mustacchi #include <string.h>
34*ea7b7d8aSRobert Mustacchi #include <errno.h>
35*ea7b7d8aSRobert Mustacchi #include <unistd.h>
36*ea7b7d8aSRobert Mustacchi #include <sys/mman.h>
37*ea7b7d8aSRobert Mustacchi #include <sys/debug.h>
38*ea7b7d8aSRobert Mustacchi #include <sys/sysmacros.h>
39*ea7b7d8aSRobert Mustacchi #include <fcntl.h>
40*ea7b7d8aSRobert Mustacchi #include <sys/socket.h>
41*ea7b7d8aSRobert Mustacchi #include <port.h>
42*ea7b7d8aSRobert Mustacchi #include <door.h>
43*ea7b7d8aSRobert Mustacchi
44*ea7b7d8aSRobert Mustacchi static bool
statvfs_fail(const char * path,int exp,struct statvfs * svp)45*ea7b7d8aSRobert Mustacchi statvfs_fail(const char *path, int exp, struct statvfs *svp)
46*ea7b7d8aSRobert Mustacchi {
47*ea7b7d8aSRobert Mustacchi struct statvfs st;
48*ea7b7d8aSRobert Mustacchi
49*ea7b7d8aSRobert Mustacchi if (svp == NULL) {
50*ea7b7d8aSRobert Mustacchi svp = &st;
51*ea7b7d8aSRobert Mustacchi }
52*ea7b7d8aSRobert Mustacchi
53*ea7b7d8aSRobert Mustacchi if (statvfs(path, svp) == 0) {
54*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: statvfs on %s passed, but expected %s",
55*ea7b7d8aSRobert Mustacchi path, strerrorname_np(exp));
56*ea7b7d8aSRobert Mustacchi return (false);
57*ea7b7d8aSRobert Mustacchi }
58*ea7b7d8aSRobert Mustacchi
59*ea7b7d8aSRobert Mustacchi if (errno != exp) {
60*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: statvfs on %s returned wrong errno: "
61*ea7b7d8aSRobert Mustacchi "expected %s, found %s", path, strerrorname_np(exp),
62*ea7b7d8aSRobert Mustacchi strerrorname_np(errno));
63*ea7b7d8aSRobert Mustacchi return (false);
64*ea7b7d8aSRobert Mustacchi }
65*ea7b7d8aSRobert Mustacchi
66*ea7b7d8aSRobert Mustacchi (void) printf("TEST PASSED: statvfs on %s correctly returned %s\n",
67*ea7b7d8aSRobert Mustacchi path, strerrorname_np(exp));
68*ea7b7d8aSRobert Mustacchi return (true);
69*ea7b7d8aSRobert Mustacchi }
70*ea7b7d8aSRobert Mustacchi
71*ea7b7d8aSRobert Mustacchi static bool
statvfs_pass(const char * path,const char * fs)72*ea7b7d8aSRobert Mustacchi statvfs_pass(const char *path, const char *fs)
73*ea7b7d8aSRobert Mustacchi {
74*ea7b7d8aSRobert Mustacchi struct statvfs sv;
75*ea7b7d8aSRobert Mustacchi
76*ea7b7d8aSRobert Mustacchi if (statvfs(path, &sv) != 0) {
77*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: statvfs on %s failed with %s, but "
78*ea7b7d8aSRobert Mustacchi "expected success", path, strerrorname_np(errno));
79*ea7b7d8aSRobert Mustacchi return (false);
80*ea7b7d8aSRobert Mustacchi }
81*ea7b7d8aSRobert Mustacchi
82*ea7b7d8aSRobert Mustacchi (void) printf("TEST PASSED: statvfs on %s worked\n", path);
83*ea7b7d8aSRobert Mustacchi if (fs == NULL) {
84*ea7b7d8aSRobert Mustacchi return (true);
85*ea7b7d8aSRobert Mustacchi }
86*ea7b7d8aSRobert Mustacchi
87*ea7b7d8aSRobert Mustacchi if (strcmp(sv.f_basetype, fs) != 0) {
88*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: statvfs on %s has wrong fs: expected %s, "
89*ea7b7d8aSRobert Mustacchi "found %s", path, fs, sv.f_basetype);
90*ea7b7d8aSRobert Mustacchi return (false);
91*ea7b7d8aSRobert Mustacchi }
92*ea7b7d8aSRobert Mustacchi
93*ea7b7d8aSRobert Mustacchi (void) printf("TEST PASSED: statvfs on %s correctly indicated fs %s\n",
94*ea7b7d8aSRobert Mustacchi path, fs);
95*ea7b7d8aSRobert Mustacchi return (true);
96*ea7b7d8aSRobert Mustacchi }
97*ea7b7d8aSRobert Mustacchi
98*ea7b7d8aSRobert Mustacchi typedef struct {
99*ea7b7d8aSRobert Mustacchi const char *sp_path;
100*ea7b7d8aSRobert Mustacchi const char *sp_fs;
101*ea7b7d8aSRobert Mustacchi int sp_ret;
102*ea7b7d8aSRobert Mustacchi } statvfs_pass_t;
103*ea7b7d8aSRobert Mustacchi
104*ea7b7d8aSRobert Mustacchi static const statvfs_pass_t statvfs_passes[] = {
105*ea7b7d8aSRobert Mustacchi { "/", NULL },
106*ea7b7d8aSRobert Mustacchi { "/usr/lib/libc.so.1", NULL },
107*ea7b7d8aSRobert Mustacchi { "/var/run", "tmpfs" },
108*ea7b7d8aSRobert Mustacchi { "/etc/svc/volatile", "tmpfs" },
109*ea7b7d8aSRobert Mustacchi { "/system/boot", "bootfs" },
110*ea7b7d8aSRobert Mustacchi { "/system/contract", "ctfs" },
111*ea7b7d8aSRobert Mustacchi { "/system/object", "objfs" },
112*ea7b7d8aSRobert Mustacchi { "/dev/fd", "fd" },
113*ea7b7d8aSRobert Mustacchi { "/etc/mnttab", "mntfs" },
114*ea7b7d8aSRobert Mustacchi { "/dev/net", "dev" },
115*ea7b7d8aSRobert Mustacchi /* This is a symlink in the GZ to /devices */
116*ea7b7d8aSRobert Mustacchi { "/dev/zero", "devfs" },
117*ea7b7d8aSRobert Mustacchi { "/devices/pseudo", "devfs" },
118*ea7b7d8aSRobert Mustacchi { "/etc/dfs/sharetab", "sharefs" },
119*ea7b7d8aSRobert Mustacchi { "/proc/self/psinfo", "proc" },
120*ea7b7d8aSRobert Mustacchi { "/var/run/name_service_door", "namefs" }
121*ea7b7d8aSRobert Mustacchi };
122*ea7b7d8aSRobert Mustacchi
123*ea7b7d8aSRobert Mustacchi typedef struct fstatvfs_test {
124*ea7b7d8aSRobert Mustacchi int (*ft_open)(const struct fstatvfs_test *);
125*ea7b7d8aSRobert Mustacchi const char *ft_path;
126*ea7b7d8aSRobert Mustacchi const char *ft_fs;
127*ea7b7d8aSRobert Mustacchi int ft_ret;
128*ea7b7d8aSRobert Mustacchi } fstatvfs_test_t;
129*ea7b7d8aSRobert Mustacchi
130*ea7b7d8aSRobert Mustacchi static int
statvfs_open_file(const fstatvfs_test_t * test)131*ea7b7d8aSRobert Mustacchi statvfs_open_file(const fstatvfs_test_t *test)
132*ea7b7d8aSRobert Mustacchi {
133*ea7b7d8aSRobert Mustacchi int fd = open(test->ft_path, O_RDONLY);
134*ea7b7d8aSRobert Mustacchi if (fd < 0) {
135*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "TEST FAILED: failed to open file %s",
136*ea7b7d8aSRobert Mustacchi test->ft_path);
137*ea7b7d8aSRobert Mustacchi }
138*ea7b7d8aSRobert Mustacchi
139*ea7b7d8aSRobert Mustacchi return (fd);
140*ea7b7d8aSRobert Mustacchi }
141*ea7b7d8aSRobert Mustacchi
142*ea7b7d8aSRobert Mustacchi static int
statvfs_open_socket(const fstatvfs_test_t * test)143*ea7b7d8aSRobert Mustacchi statvfs_open_socket(const fstatvfs_test_t *test)
144*ea7b7d8aSRobert Mustacchi {
145*ea7b7d8aSRobert Mustacchi struct sockaddr_in in;
146*ea7b7d8aSRobert Mustacchi int fd = socket(PF_INET, SOCK_STREAM, 0);
147*ea7b7d8aSRobert Mustacchi if (fd < 0) {
148*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "TEST FAILED: failed to create basic "
149*ea7b7d8aSRobert Mustacchi "socket");
150*ea7b7d8aSRobert Mustacchi }
151*ea7b7d8aSRobert Mustacchi
152*ea7b7d8aSRobert Mustacchi (void) memset(&in, 0, sizeof (in));
153*ea7b7d8aSRobert Mustacchi if (bind(fd, (struct sockaddr *)&in, sizeof (in)) != 0) {
154*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "TEST FAILED: failed to bind socket");
155*ea7b7d8aSRobert Mustacchi }
156*ea7b7d8aSRobert Mustacchi
157*ea7b7d8aSRobert Mustacchi return (fd);
158*ea7b7d8aSRobert Mustacchi }
159*ea7b7d8aSRobert Mustacchi
160*ea7b7d8aSRobert Mustacchi static int
statvfs_open_uds(const fstatvfs_test_t * test)161*ea7b7d8aSRobert Mustacchi statvfs_open_uds(const fstatvfs_test_t *test)
162*ea7b7d8aSRobert Mustacchi {
163*ea7b7d8aSRobert Mustacchi int fd = socket(PF_UNIX, SOCK_STREAM, 0);
164*ea7b7d8aSRobert Mustacchi if (fd < 0) {
165*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "TEST FAILED: failed to create UDS");
166*ea7b7d8aSRobert Mustacchi }
167*ea7b7d8aSRobert Mustacchi
168*ea7b7d8aSRobert Mustacchi return (fd);
169*ea7b7d8aSRobert Mustacchi }
170*ea7b7d8aSRobert Mustacchi
171*ea7b7d8aSRobert Mustacchi static int
statvfs_open_pipe(const fstatvfs_test_t * test)172*ea7b7d8aSRobert Mustacchi statvfs_open_pipe(const fstatvfs_test_t *test)
173*ea7b7d8aSRobert Mustacchi {
174*ea7b7d8aSRobert Mustacchi int fds[2];
175*ea7b7d8aSRobert Mustacchi
176*ea7b7d8aSRobert Mustacchi if (pipe(fds) != 0) {
177*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "TEST FAILED: failed to create pipe");
178*ea7b7d8aSRobert Mustacchi }
179*ea7b7d8aSRobert Mustacchi
180*ea7b7d8aSRobert Mustacchi VERIFY0(close(fds[1]));
181*ea7b7d8aSRobert Mustacchi return (fds[0]);
182*ea7b7d8aSRobert Mustacchi }
183*ea7b7d8aSRobert Mustacchi
184*ea7b7d8aSRobert Mustacchi static int
statvfs_open_negfd(const fstatvfs_test_t * test)185*ea7b7d8aSRobert Mustacchi statvfs_open_negfd(const fstatvfs_test_t *test)
186*ea7b7d8aSRobert Mustacchi {
187*ea7b7d8aSRobert Mustacchi return (-1);
188*ea7b7d8aSRobert Mustacchi }
189*ea7b7d8aSRobert Mustacchi
190*ea7b7d8aSRobert Mustacchi static int
statvfs_open_bigfd(const fstatvfs_test_t * test)191*ea7b7d8aSRobert Mustacchi statvfs_open_bigfd(const fstatvfs_test_t *test)
192*ea7b7d8aSRobert Mustacchi {
193*ea7b7d8aSRobert Mustacchi return (0x7777);
194*ea7b7d8aSRobert Mustacchi }
195*ea7b7d8aSRobert Mustacchi
196*ea7b7d8aSRobert Mustacchi static int
statvfs_open_portfs(const fstatvfs_test_t * test)197*ea7b7d8aSRobert Mustacchi statvfs_open_portfs(const fstatvfs_test_t *test)
198*ea7b7d8aSRobert Mustacchi {
199*ea7b7d8aSRobert Mustacchi int fd = port_create();
200*ea7b7d8aSRobert Mustacchi if (fd < 0) {
201*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "TEST FAILED: failed to create event port");
202*ea7b7d8aSRobert Mustacchi }
203*ea7b7d8aSRobert Mustacchi
204*ea7b7d8aSRobert Mustacchi return (fd);
205*ea7b7d8aSRobert Mustacchi }
206*ea7b7d8aSRobert Mustacchi
207*ea7b7d8aSRobert Mustacchi static void
statvfs_close_door(void * cookie,char * arg,size_t size,door_desc_t * dp,uint_t ndesc)208*ea7b7d8aSRobert Mustacchi statvfs_close_door(void *cookie, char *arg, size_t size, door_desc_t *dp,
209*ea7b7d8aSRobert Mustacchi uint_t ndesc)
210*ea7b7d8aSRobert Mustacchi {
211*ea7b7d8aSRobert Mustacchi (void) door_return(NULL, 0, NULL, 0);
212*ea7b7d8aSRobert Mustacchi }
213*ea7b7d8aSRobert Mustacchi
214*ea7b7d8aSRobert Mustacchi static int
statvfs_open_door(const fstatvfs_test_t * test)215*ea7b7d8aSRobert Mustacchi statvfs_open_door(const fstatvfs_test_t *test)
216*ea7b7d8aSRobert Mustacchi {
217*ea7b7d8aSRobert Mustacchi int fd = door_create(statvfs_close_door, NULL, 0);
218*ea7b7d8aSRobert Mustacchi if (fd < 0) {
219*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "TEST FAILED: failed to create door");
220*ea7b7d8aSRobert Mustacchi }
221*ea7b7d8aSRobert Mustacchi return (fd);
222*ea7b7d8aSRobert Mustacchi }
223*ea7b7d8aSRobert Mustacchi
224*ea7b7d8aSRobert Mustacchi static const fstatvfs_test_t fstatvfs_tests[] = {
225*ea7b7d8aSRobert Mustacchi { statvfs_open_socket, "localhost socket", "sockfs", 0 },
226*ea7b7d8aSRobert Mustacchi { statvfs_open_uds, "UDS socket", "sockfs", 0 },
227*ea7b7d8aSRobert Mustacchi { statvfs_open_pipe, "pipe", NULL, ENOSYS },
228*ea7b7d8aSRobert Mustacchi { statvfs_open_file, "/dev/tcp", NULL, ENOSYS },
229*ea7b7d8aSRobert Mustacchi { statvfs_open_negfd, "bad fd (-1)", NULL, EBADF },
230*ea7b7d8aSRobert Mustacchi { statvfs_open_negfd, "bad fd (-1)", NULL, EBADF },
231*ea7b7d8aSRobert Mustacchi { statvfs_open_bigfd, "bad fd (0x7777)", NULL, EBADF },
232*ea7b7d8aSRobert Mustacchi { statvfs_open_portfs, "event port", NULL, ENOSYS },
233*ea7b7d8aSRobert Mustacchi { statvfs_open_door, "door server", NULL, ENOSYS }
234*ea7b7d8aSRobert Mustacchi };
235*ea7b7d8aSRobert Mustacchi
236*ea7b7d8aSRobert Mustacchi static bool
fstatvfs_test(const fstatvfs_test_t * test)237*ea7b7d8aSRobert Mustacchi fstatvfs_test(const fstatvfs_test_t *test)
238*ea7b7d8aSRobert Mustacchi {
239*ea7b7d8aSRobert Mustacchi struct statvfs sv;
240*ea7b7d8aSRobert Mustacchi int ret, fd, e;
241*ea7b7d8aSRobert Mustacchi
242*ea7b7d8aSRobert Mustacchi /*
243*ea7b7d8aSRobert Mustacchi * Some tests will specifically use a bad fd value trying to get EBADF.
244*ea7b7d8aSRobert Mustacchi * In those cases don't try to close the fd again.
245*ea7b7d8aSRobert Mustacchi */
246*ea7b7d8aSRobert Mustacchi fd = test->ft_open(test);
247*ea7b7d8aSRobert Mustacchi ret = fstatvfs(fd, &sv);
248*ea7b7d8aSRobert Mustacchi e = errno;
249*ea7b7d8aSRobert Mustacchi if (test->ft_ret != EBADF) {
250*ea7b7d8aSRobert Mustacchi VERIFY0(close(fd));
251*ea7b7d8aSRobert Mustacchi }
252*ea7b7d8aSRobert Mustacchi
253*ea7b7d8aSRobert Mustacchi if (ret != 0) {
254*ea7b7d8aSRobert Mustacchi if (test->ft_ret == 0) {
255*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: fstatvfs on %s failed with %s, but "
256*ea7b7d8aSRobert Mustacchi "expected success", test->ft_path,
257*ea7b7d8aSRobert Mustacchi strerrorname_np(errno));
258*ea7b7d8aSRobert Mustacchi return (false);
259*ea7b7d8aSRobert Mustacchi }
260*ea7b7d8aSRobert Mustacchi
261*ea7b7d8aSRobert Mustacchi if (e != test->ft_ret) {
262*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: fstatvfs on %s returned wrong "
263*ea7b7d8aSRobert Mustacchi "errno: expected %s, found %s", test->ft_path,
264*ea7b7d8aSRobert Mustacchi strerrorname_np(test->ft_ret), strerrorname_np(e));
265*ea7b7d8aSRobert Mustacchi return (false);
266*ea7b7d8aSRobert Mustacchi }
267*ea7b7d8aSRobert Mustacchi
268*ea7b7d8aSRobert Mustacchi (void) printf("TEST PASSED: fstatvfs on %s correctly failed "
269*ea7b7d8aSRobert Mustacchi "with %s\n", test->ft_path, strerrorname_np(test->ft_ret));
270*ea7b7d8aSRobert Mustacchi return (true);
271*ea7b7d8aSRobert Mustacchi }
272*ea7b7d8aSRobert Mustacchi
273*ea7b7d8aSRobert Mustacchi if (test->ft_ret != 0) {
274*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: fstatvfs on %s passed, but expected %s",
275*ea7b7d8aSRobert Mustacchi test->ft_path, strerrorname_np(test->ft_ret));
276*ea7b7d8aSRobert Mustacchi return (false);
277*ea7b7d8aSRobert Mustacchi }
278*ea7b7d8aSRobert Mustacchi
279*ea7b7d8aSRobert Mustacchi (void) printf("TEST PASSED: fstatvfs on %s worked\n", test->ft_path);
280*ea7b7d8aSRobert Mustacchi if (test->ft_fs == NULL) {
281*ea7b7d8aSRobert Mustacchi return (true);
282*ea7b7d8aSRobert Mustacchi }
283*ea7b7d8aSRobert Mustacchi
284*ea7b7d8aSRobert Mustacchi if (strcmp(sv.f_basetype, test->ft_fs) != 0) {
285*ea7b7d8aSRobert Mustacchi warnx("TEST FAILED: fstatvfs on %s has wrong fs: expected %s, "
286*ea7b7d8aSRobert Mustacchi "found %s", test->ft_path, test->ft_fs, sv.f_basetype);
287*ea7b7d8aSRobert Mustacchi return (false);
288*ea7b7d8aSRobert Mustacchi }
289*ea7b7d8aSRobert Mustacchi
290*ea7b7d8aSRobert Mustacchi (void) printf("TEST PASSED: fstatvfs on %s correctly indicated fs %s\n",
291*ea7b7d8aSRobert Mustacchi test->ft_path, test->ft_fs);
292*ea7b7d8aSRobert Mustacchi return (true);
293*ea7b7d8aSRobert Mustacchi }
294*ea7b7d8aSRobert Mustacchi
295*ea7b7d8aSRobert Mustacchi int
main(void)296*ea7b7d8aSRobert Mustacchi main(void)
297*ea7b7d8aSRobert Mustacchi {
298*ea7b7d8aSRobert Mustacchi int ret = EXIT_SUCCESS;
299*ea7b7d8aSRobert Mustacchi void *unmap;
300*ea7b7d8aSRobert Mustacchi long page;
301*ea7b7d8aSRobert Mustacchi
302*ea7b7d8aSRobert Mustacchi page = sysconf(_SC_PAGESIZE);
303*ea7b7d8aSRobert Mustacchi VERIFY3S(page, >=, sizeof (struct statvfs));
304*ea7b7d8aSRobert Mustacchi unmap = mmap(NULL, page, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
305*ea7b7d8aSRobert Mustacchi if (unmap == MAP_FAILED) {
306*ea7b7d8aSRobert Mustacchi err(EXIT_FAILURE, "INTERNAL TEST FAILURE: failed to mmap our "
307*ea7b7d8aSRobert Mustacchi "empty page");
308*ea7b7d8aSRobert Mustacchi }
309*ea7b7d8aSRobert Mustacchi
310*ea7b7d8aSRobert Mustacchi if (!statvfs_fail("/elbe12th!", ENOENT, NULL)) {
311*ea7b7d8aSRobert Mustacchi ret = EXIT_FAILURE;
312*ea7b7d8aSRobert Mustacchi }
313*ea7b7d8aSRobert Mustacchi
314*ea7b7d8aSRobert Mustacchi if (!statvfs_fail("/usr/sbin/dtrace/wait", ENOTDIR, NULL)) {
315*ea7b7d8aSRobert Mustacchi ret = EXIT_FAILURE;
316*ea7b7d8aSRobert Mustacchi }
317*ea7b7d8aSRobert Mustacchi
318*ea7b7d8aSRobert Mustacchi if (!statvfs_fail("/", EFAULT, unmap)) {
319*ea7b7d8aSRobert Mustacchi ret = EXIT_FAILURE;
320*ea7b7d8aSRobert Mustacchi }
321*ea7b7d8aSRobert Mustacchi
322*ea7b7d8aSRobert Mustacchi /*
323*ea7b7d8aSRobert Mustacchi * Each passing statvfs test should be a passing fstatvfs test as well.
324*ea7b7d8aSRobert Mustacchi */
325*ea7b7d8aSRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(statvfs_passes); i++) {
326*ea7b7d8aSRobert Mustacchi fstatvfs_test_t ft;
327*ea7b7d8aSRobert Mustacchi
328*ea7b7d8aSRobert Mustacchi if (!statvfs_pass(statvfs_passes[i].sp_path,
329*ea7b7d8aSRobert Mustacchi statvfs_passes[i].sp_fs)) {
330*ea7b7d8aSRobert Mustacchi ret = EXIT_FAILURE;
331*ea7b7d8aSRobert Mustacchi }
332*ea7b7d8aSRobert Mustacchi
333*ea7b7d8aSRobert Mustacchi ft.ft_open = statvfs_open_file;
334*ea7b7d8aSRobert Mustacchi ft.ft_path = statvfs_passes[i].sp_path;
335*ea7b7d8aSRobert Mustacchi ft.ft_fs = statvfs_passes[i].sp_fs;
336*ea7b7d8aSRobert Mustacchi ft.ft_ret = 0;
337*ea7b7d8aSRobert Mustacchi
338*ea7b7d8aSRobert Mustacchi if (!fstatvfs_test(&ft)) {
339*ea7b7d8aSRobert Mustacchi ret = EXIT_FAILURE;
340*ea7b7d8aSRobert Mustacchi }
341*ea7b7d8aSRobert Mustacchi }
342*ea7b7d8aSRobert Mustacchi
343*ea7b7d8aSRobert Mustacchi for (size_t i = 0; i < ARRAY_SIZE(fstatvfs_tests); i++) {
344*ea7b7d8aSRobert Mustacchi if (!fstatvfs_test(&fstatvfs_tests[i])) {
345*ea7b7d8aSRobert Mustacchi ret = EXIT_FAILURE;
346*ea7b7d8aSRobert Mustacchi }
347*ea7b7d8aSRobert Mustacchi }
348*ea7b7d8aSRobert Mustacchi
349*ea7b7d8aSRobert Mustacchi if (ret == EXIT_SUCCESS) {
350*ea7b7d8aSRobert Mustacchi (void) printf("All tests completed successfully\n");
351*ea7b7d8aSRobert Mustacchi }
352*ea7b7d8aSRobert Mustacchi return (ret);
353*ea7b7d8aSRobert Mustacchi }
354