xref: /xnu-11417.101.15/tests/vfs/statfs_ext.c (revision e3723e1f17661b24996789d8afc084c0c3303b26)
1*e3723e1fSApple OSS Distributions /*
2*e3723e1fSApple OSS Distributions  * Copyright (c) 2024 Apple Computer, Inc. All rights reserved.
3*e3723e1fSApple OSS Distributions  *
4*e3723e1fSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*e3723e1fSApple OSS Distributions  *
6*e3723e1fSApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*e3723e1fSApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*e3723e1fSApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*e3723e1fSApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*e3723e1fSApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*e3723e1fSApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*e3723e1fSApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*e3723e1fSApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*e3723e1fSApple OSS Distributions  *
15*e3723e1fSApple OSS Distributions  * Please obtain a copy of the License at
16*e3723e1fSApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*e3723e1fSApple OSS Distributions  *
18*e3723e1fSApple OSS Distributions  * The Original Code and all software distributed under the License are
19*e3723e1fSApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*e3723e1fSApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*e3723e1fSApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*e3723e1fSApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*e3723e1fSApple OSS Distributions  * Please see the License for the specific language governing rights and
24*e3723e1fSApple OSS Distributions  * limitations under the License.
25*e3723e1fSApple OSS Distributions  *
26*e3723e1fSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*e3723e1fSApple OSS Distributions  */
28*e3723e1fSApple OSS Distributions 
29*e3723e1fSApple OSS Distributions /* compile: xcrun -sdk macosx.internal clang -ldarwintest -o statfs_ext statfs_ext.c -g -Weverything */
30*e3723e1fSApple OSS Distributions 
31*e3723e1fSApple OSS Distributions #include <stdlib.h>
32*e3723e1fSApple OSS Distributions #include <fcntl.h>
33*e3723e1fSApple OSS Distributions #include <sys/mount.h>
34*e3723e1fSApple OSS Distributions #include <sys/stat.h>
35*e3723e1fSApple OSS Distributions 
36*e3723e1fSApple OSS Distributions #include <darwintest.h>
37*e3723e1fSApple OSS Distributions #include <darwintest/utils.h>
38*e3723e1fSApple OSS Distributions 
39*e3723e1fSApple OSS Distributions #define RUN_TEST     TARGET_OS_OSX
40*e3723e1fSApple OSS Distributions 
41*e3723e1fSApple OSS Distributions #define FSTYPE_DEVFS "devfs"
42*e3723e1fSApple OSS Distributions static char template[MAXPATHLEN];
43*e3723e1fSApple OSS Distributions static char *testdir = NULL;
44*e3723e1fSApple OSS Distributions 
45*e3723e1fSApple OSS Distributions #define TEST_MODE_STATFS  0
46*e3723e1fSApple OSS Distributions #define TEST_MODE_FSTATFS 1
47*e3723e1fSApple OSS Distributions 
48*e3723e1fSApple OSS Distributions static const char *flag_name[] =
49*e3723e1fSApple OSS Distributions { "0", "STATFS_EXT_NOBLOCK" };
50*e3723e1fSApple OSS Distributions 
51*e3723e1fSApple OSS Distributions static const char *mode_name[] =
52*e3723e1fSApple OSS Distributions { "TEST_MODE_STATFS", "TEST_MODE_FSTATFS" };
53*e3723e1fSApple OSS Distributions 
54*e3723e1fSApple OSS Distributions T_GLOBAL_META(
55*e3723e1fSApple OSS Distributions 	T_META_NAMESPACE("xnu.vfs"),
56*e3723e1fSApple OSS Distributions 	T_META_RADAR_COMPONENT_NAME("xnu"),
57*e3723e1fSApple OSS Distributions 	T_META_RADAR_COMPONENT_VERSION("vfs"),
58*e3723e1fSApple OSS Distributions 	T_META_ASROOT(false),
59*e3723e1fSApple OSS Distributions 	T_META_ENABLED(RUN_TEST),
60*e3723e1fSApple OSS Distributions 	T_META_CHECK_LEAKS(false));
61*e3723e1fSApple OSS Distributions 
62*e3723e1fSApple OSS Distributions static void
cleanup(void)63*e3723e1fSApple OSS Distributions cleanup(void)
64*e3723e1fSApple OSS Distributions {
65*e3723e1fSApple OSS Distributions 	if (testdir) {
66*e3723e1fSApple OSS Distributions 		unmount(testdir, MNT_FORCE);
67*e3723e1fSApple OSS Distributions 		rmdir(testdir);
68*e3723e1fSApple OSS Distributions 	}
69*e3723e1fSApple OSS Distributions }
70*e3723e1fSApple OSS Distributions 
71*e3723e1fSApple OSS Distributions static void
statfs_compare(const char * path,struct statfs * sfs_ext,int mode,int flag,int expected_err)72*e3723e1fSApple OSS Distributions statfs_compare(const char *path, struct statfs *sfs_ext, int mode, int flag, int expected_err)
73*e3723e1fSApple OSS Distributions {
74*e3723e1fSApple OSS Distributions 	int fd;
75*e3723e1fSApple OSS Distributions 	struct statfs sfs;
76*e3723e1fSApple OSS Distributions 
77*e3723e1fSApple OSS Distributions 	T_LOG("Testing: path %s, sfs_ext %p, mode %s, flag 0x%x, expected_err %d", path, (void *) sfs_ext, mode_name[mode], flag, expected_err);
78*e3723e1fSApple OSS Distributions 
79*e3723e1fSApple OSS Distributions 	if (sfs_ext) {
80*e3723e1fSApple OSS Distributions 		bzero(sfs_ext, sizeof(struct statfs));
81*e3723e1fSApple OSS Distributions 	}
82*e3723e1fSApple OSS Distributions 
83*e3723e1fSApple OSS Distributions 	switch (mode) {
84*e3723e1fSApple OSS Distributions 	case TEST_MODE_STATFS:
85*e3723e1fSApple OSS Distributions 		if (expected_err) {
86*e3723e1fSApple OSS Distributions 			T_ASSERT_POSIX_FAILURE(statfs_ext(path, sfs_ext, flag), expected_err, "Verifying that statfs_ext() fails with %d (%s)", expected_err, strerror(expected_err));
87*e3723e1fSApple OSS Distributions 		} else {
88*e3723e1fSApple OSS Distributions 			T_ASSERT_POSIX_SUCCESS(statfs(path, &sfs), "Calling stafs()");
89*e3723e1fSApple OSS Distributions 			T_ASSERT_POSIX_SUCCESS(statfs_ext(path, sfs_ext, flag), "Calling statfs_ext() using the %s flag", flag_name[flag]);
90*e3723e1fSApple OSS Distributions 		}
91*e3723e1fSApple OSS Distributions 		break;
92*e3723e1fSApple OSS Distributions 	case TEST_MODE_FSTATFS:
93*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(fd = open(path, O_DIRECTORY | O_RDONLY), "Opening %s", path);
94*e3723e1fSApple OSS Distributions 		if (expected_err) {
95*e3723e1fSApple OSS Distributions 			T_ASSERT_POSIX_FAILURE(fstatfs_ext(fd, sfs_ext, flag), expected_err, "Verifying that fstatfs_ext() fails with %d (%s)", expected_err, strerror(expected_err));
96*e3723e1fSApple OSS Distributions 		} else {
97*e3723e1fSApple OSS Distributions 			T_ASSERT_POSIX_SUCCESS(fstatfs(fd, &sfs), "Calling fstafs()");
98*e3723e1fSApple OSS Distributions 			T_ASSERT_POSIX_SUCCESS(fstatfs_ext(fd, sfs_ext, flag), "Calling fstatfs_ext() using the %s flag", flag_name[flag]);
99*e3723e1fSApple OSS Distributions 		}
100*e3723e1fSApple OSS Distributions 		T_ASSERT_POSIX_SUCCESS(close(fd), "Closing fd");
101*e3723e1fSApple OSS Distributions 		break;
102*e3723e1fSApple OSS Distributions 	default:
103*e3723e1fSApple OSS Distributions 		T_FAIL("Unknown test mode");
104*e3723e1fSApple OSS Distributions 	}
105*e3723e1fSApple OSS Distributions 
106*e3723e1fSApple OSS Distributions 	if (expected_err) {
107*e3723e1fSApple OSS Distributions 		return;
108*e3723e1fSApple OSS Distributions 	}
109*e3723e1fSApple OSS Distributions 
110*e3723e1fSApple OSS Distributions 	switch (flag) {
111*e3723e1fSApple OSS Distributions 	case 0:
112*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(memcmp(&sfs, sfs_ext, sizeof(struct statfs)), 0, "Validating statfs structure");
113*e3723e1fSApple OSS Distributions 		break;
114*e3723e1fSApple OSS Distributions 	case STATFS_EXT_NOBLOCK:
115*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(sfs.f_fsid.val[0], sfs_ext->f_fsid.val[0], "Validating f_fsid.val[0]");
116*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(sfs.f_fsid.val[1], sfs_ext->f_fsid.val[1], "Validating f_fsid.val[1]");
117*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(sfs.f_owner, sfs_ext->f_owner, "Validating f_owner");
118*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(sfs.f_type, sfs_ext->f_type, "Validating f_type");
119*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(sfs.f_flags, sfs_ext->f_flags, "Validating f_flags");
120*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(sfs.f_fssubtype, sfs_ext->f_fssubtype, "Validating f_fssubtype");
121*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_STR(sfs.f_fstypename, sfs_ext->f_fstypename, "Validating f_fstypename");
122*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_STR(sfs.f_mntonname, sfs_ext->f_mntonname, "Validating f_mntonname");
123*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ_STR(sfs.f_mntfromname, sfs_ext->f_mntfromname, "Validating f_mntfromname");
124*e3723e1fSApple OSS Distributions 		T_ASSERT_EQ(sfs.f_flags_ext, sfs_ext->f_flags_ext, "Validating f_flags_ext");
125*e3723e1fSApple OSS Distributions 		break;
126*e3723e1fSApple OSS Distributions 	default:
127*e3723e1fSApple OSS Distributions 		T_FAIL("Unknown flag");
128*e3723e1fSApple OSS Distributions 	}
129*e3723e1fSApple OSS Distributions }
130*e3723e1fSApple OSS Distributions 
131*e3723e1fSApple OSS Distributions T_DECL(statfs_ext,
132*e3723e1fSApple OSS Distributions     "test statfs_ext and fstatfs_ext")
133*e3723e1fSApple OSS Distributions {
134*e3723e1fSApple OSS Distributions #if (!RUN_TEST)
135*e3723e1fSApple OSS Distributions 	T_SKIP("Not macOS");
136*e3723e1fSApple OSS Distributions #endif
137*e3723e1fSApple OSS Distributions 
138*e3723e1fSApple OSS Distributions 	struct statfs sfs_ext;
139*e3723e1fSApple OSS Distributions 
140*e3723e1fSApple OSS Distributions 	T_ATEND(cleanup);
141*e3723e1fSApple OSS Distributions 
142*e3723e1fSApple OSS Distributions 	T_SETUPBEGIN;
143*e3723e1fSApple OSS Distributions 
144*e3723e1fSApple OSS Distributions 	snprintf(template, sizeof(template), "%s/statfs_ext-XXXXXX", dt_tmpdir());
145*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_NOTNULL((testdir = mkdtemp(template)), "Creating test root dir");
146*e3723e1fSApple OSS Distributions 	T_ASSERT_POSIX_SUCCESS(mount(FSTYPE_DEVFS, testdir, MNT_RDONLY, NULL), "Mounting temporary %s mount using path %s", FSTYPE_DEVFS, testdir);
147*e3723e1fSApple OSS Distributions 
148*e3723e1fSApple OSS Distributions 	T_SETUPEND;
149*e3723e1fSApple OSS Distributions 
150*e3723e1fSApple OSS Distributions 	/* Test fstatfs_ext() with invalid flags */
151*e3723e1fSApple OSS Distributions 	statfs_compare("/dev", &sfs_ext, TEST_MODE_STATFS, 0x10, EINVAL);
152*e3723e1fSApple OSS Distributions 	statfs_compare(testdir, &sfs_ext, TEST_MODE_FSTATFS, STATFS_EXT_NOBLOCK | 0x8, EINVAL);
153*e3723e1fSApple OSS Distributions 
154*e3723e1fSApple OSS Distributions 	/* Test invalid inputs */
155*e3723e1fSApple OSS Distributions 	statfs_compare(NULL, &sfs_ext, TEST_MODE_STATFS, STATFS_EXT_NOBLOCK, EFAULT);
156*e3723e1fSApple OSS Distributions 	statfs_compare("/", NULL, TEST_MODE_STATFS, STATFS_EXT_NOBLOCK, EFAULT);
157*e3723e1fSApple OSS Distributions 	statfs_compare("/dev", NULL, TEST_MODE_FSTATFS, STATFS_EXT_NOBLOCK, EFAULT);
158*e3723e1fSApple OSS Distributions 
159*e3723e1fSApple OSS Distributions 	/* Test fstatfs_ext() with zero flags */
160*e3723e1fSApple OSS Distributions 	statfs_compare("/", &sfs_ext, TEST_MODE_STATFS, 0, 0);
161*e3723e1fSApple OSS Distributions 	statfs_compare("/private/var/tmp", &sfs_ext, TEST_MODE_FSTATFS, 0, 0);
162*e3723e1fSApple OSS Distributions 
163*e3723e1fSApple OSS Distributions 	/* Test fstatfs_ext() with the STATFS_EXT_NOBLOCK flag */
164*e3723e1fSApple OSS Distributions 	statfs_compare("/", &sfs_ext, TEST_MODE_STATFS, STATFS_EXT_NOBLOCK, 0);
165*e3723e1fSApple OSS Distributions 	statfs_compare("/dev", &sfs_ext, TEST_MODE_STATFS, STATFS_EXT_NOBLOCK, 0);
166*e3723e1fSApple OSS Distributions 	statfs_compare("/private/var/tmp", &sfs_ext, TEST_MODE_FSTATFS, STATFS_EXT_NOBLOCK, 0);
167*e3723e1fSApple OSS Distributions 	statfs_compare(testdir, &sfs_ext, TEST_MODE_FSTATFS, STATFS_EXT_NOBLOCK, 0);
168*e3723e1fSApple OSS Distributions }
169