]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/xnu_quick_test/32bit_inode_tests.c
209c64030e26bfb3a0fc12c931124992d743c724
[apple/xnu.git] / tools / tests / xnu_quick_test / 32bit_inode_tests.c
1 /*
2 * 32bit_inode_tests.c
3 * xnu_quick_test
4 *
5 * Created by Ryan Branche on 2/17/08.
6 * Copyright 2008 Apple Inc. All rights reserved.
7 *
8 */
9
10 /*
11 * Explicitely turn off 64-bit inodes because we are testing the 32-bit inode
12 * versions of statfs functions and getdirentries doesn't support 64-bit inodes.
13 */
14 #define _DARWIN_NO_64_BIT_INODE 1
15
16 #include "tests.h"
17 #include <mach/mach.h>
18 #include <dirent.h>
19
20 extern char g_target_path[ PATH_MAX ];
21 extern int g_skip_setuid_tests;
22 extern int g_is_single_user;
23
24 /* **************************************************************************************************************
25 * Test getdirentries system call.
26 * **************************************************************************************************************
27 */
28 struct test_attr_buf {
29 uint32_t length;
30 fsobj_type_t obj_type;
31 fsobj_id_t obj_id;
32 struct timespec backup_time;
33 };
34
35 typedef struct test_attr_buf test_attr_buf;
36
37 int getdirentries_test( void * the_argp )
38 {
39 int my_err, done, found_it, i;
40 int my_fd = -1;
41 int is_ufs = 0;
42 char * my_pathp = NULL;
43 char * my_bufp = NULL;
44 char * my_file_namep;
45 long my_base;
46 unsigned long my_count;
47 unsigned long my_new_state;
48 fsobj_id_t my_obj_id;
49 struct timespec my_new_backup_time;
50 struct attrlist my_attrlist;
51 test_attr_buf my_attr_buf[4];
52 struct statfs my_statfs_buf;
53 kern_return_t my_kr;
54
55 /* need to know type of file system */
56 my_err = statfs( &g_target_path[0], &my_statfs_buf );
57 if ( my_err == -1 ) {
58 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
59 goto test_failed_exit;
60 }
61 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
62 is_ufs = 1;
63 }
64
65 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE);
66 if(my_kr != KERN_SUCCESS){
67 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
68 goto test_failed_exit;
69 }
70
71 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
72 if(my_kr != KERN_SUCCESS){
73 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
74 goto test_failed_exit;
75 }
76
77 *my_pathp = 0x00;
78 strcat( my_pathp, &g_target_path[0] );
79 strcat( my_pathp, "/" );
80
81 /* create a test file */
82 my_err = create_random_name( my_pathp, 1 );
83 if ( my_err != 0 ) {
84 goto test_failed_exit;
85 }
86
87 /* get pointer to just the file name */
88 my_file_namep = strrchr( my_pathp, '/' );
89 my_file_namep++;
90
91 /* check out the test directory */
92 my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
93 if ( my_fd == -1 ) {
94 printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
95 goto test_failed_exit;
96 }
97
98 done = found_it = 0;
99 while ( done == 0 ) {
100 int my_result, i;
101 struct dirent * my_dirent_p;
102
103 /* This call requires that 64-bit inodes are disabled */
104 my_result = getdirentries( my_fd, my_bufp, (1024 * 5), &my_base );
105 if ( my_result <= 0 )
106 break;
107 for ( i = 0; i < my_result; ) {
108 my_dirent_p = (struct dirent *) (my_bufp + i);
109 #if DEBUG
110 printf( "d_ino %d d_reclen %d d_type %d d_namlen %d \"%s\" \n",
111 my_dirent_p->d_ino, my_dirent_p->d_reclen, my_dirent_p->d_type,
112 my_dirent_p->d_namlen, &my_dirent_p->d_name[0] );
113 #endif
114
115 i += my_dirent_p->d_reclen;
116 /* validate results by looking for our test file */
117 if ( my_dirent_p->d_type == DT_REG && my_dirent_p->d_ino != 0 &&
118 strlen( my_file_namep ) == my_dirent_p->d_namlen &&
119 memcmp( &my_dirent_p->d_name[0], my_file_namep, my_dirent_p->d_namlen ) == 0 ) {
120 done = found_it = 1;
121 break;
122 }
123 }
124 }
125 if ( found_it == 0 ) {
126 printf( "getdirentries failed to find test file. \n" );
127 goto test_failed_exit;
128 }
129
130 test_failed_exit:
131 if(my_err != 0)
132 my_err = -1;
133
134 test_passed_exit:
135 if ( my_fd != -1 )
136 close( my_fd );
137 if ( my_pathp != NULL ) {
138 remove( my_pathp );
139 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
140 }
141 if ( my_bufp != NULL ) {
142 vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5));
143 }
144
145 return( my_err );
146 }
147
148
149 /* **************************************************************************************************************
150 * Test 32-bit inode versions of statfs, fstatfs, and getfsstat system calls.
151 * **************************************************************************************************************
152 */
153
154 #pragma pack(4)
155 struct vol_attr_buf {
156 u_int32_t length;
157 off_t volume_size;
158 u_int32_t io_blksize;
159 };
160 #pragma pack()
161 typedef struct vol_attr_buf vol_attr_buf;
162
163 int statfs_32bit_inode_tests( void * the_argp )
164 {
165 int my_err, my_count, i;
166 int my_buffer_size;
167 int my_fd = -1;
168 int is_ufs = 0;
169 void * my_bufferp = NULL;
170 struct statfs * my_statfsp;
171 long my_io_size;
172 fsid_t my_fsid;
173 struct attrlist my_attrlist;
174 vol_attr_buf my_attr_buf;
175 kern_return_t my_kr;
176
177 my_buffer_size = (sizeof(struct statfs) * 10);
178 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufferp, my_buffer_size, VM_FLAGS_ANYWHERE);
179 if(my_kr != KERN_SUCCESS){
180 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
181 goto test_failed_exit;
182 }
183
184 my_statfsp = (struct statfs *) my_bufferp;
185 my_err = statfs( "/", my_statfsp );
186 if ( my_err == -1 ) {
187 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
188 goto test_failed_exit;
189 }
190 if ( memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ) {
191 is_ufs = 1;
192 }
193
194 my_count = getfsstat( (struct statfs *)my_bufferp, my_buffer_size, MNT_NOWAIT );
195 if ( my_count == -1 ) {
196 printf( "getfsstat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
197 goto test_failed_exit;
198 }
199
200 /* validate results */
201 my_statfsp = (struct statfs *) my_bufferp;
202 for ( i = 0; i < my_count; i++, my_statfsp++ ) {
203 if ( memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
204 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ||
205 memcmp( &my_statfsp->f_fstypename[0], "devfs", 5 ) == 0 ||
206 memcmp( &my_statfsp->f_fstypename[0], "volfs", 5 ) == 0 ) {
207 /* found a valid entry */
208 break;
209 }
210 }
211 if ( i >= my_count ) {
212 printf( "getfsstat call failed. could not find valid f_fstypename! \n" );
213 goto test_failed_exit;
214 }
215
216 /* set up to validate results via multiple sources. we use getattrlist to get volume
217 * related attributes to verify against results from fstatfs and statfs - but only if
218 * we are not targeting ufs volume since it doesn't support getattr calls
219 */
220 if ( is_ufs == 0 ) {
221 memset( &my_attrlist, 0, sizeof(my_attrlist) );
222 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
223 my_attrlist.volattr = (ATTR_VOL_SIZE | ATTR_VOL_IOBLOCKSIZE);
224 my_err = getattrlist( "/", &my_attrlist, &my_attr_buf, sizeof(my_attr_buf), 0 );
225 if ( my_err != 0 ) {
226 printf( "getattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) );
227 goto test_failed_exit;
228 }
229 }
230
231 /* open kernel to use as test file for fstatfs */
232 my_fd = open( "/System/Library/Kernels/kernel", O_RDONLY, 0 );
233 if ( my_fd == -1 ) {
234 printf( "open call failed. got errno %d - %s. \n", errno, strerror( errno ) );
235 goto test_failed_exit;
236 }
237
238 /* testing fstatfs */
239 my_statfsp = (struct statfs *) my_bufferp;
240 my_err = fstatfs( my_fd, my_statfsp );
241 if ( my_err == -1 ) {
242 printf( "fstatfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
243 goto test_failed_exit;
244 }
245
246 /* validate results */
247 if ( !(memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
248 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0) ) {
249 printf( "fstatfs call failed. could not find valid f_fstypename! \n" );
250 goto test_failed_exit;
251 }
252 my_io_size = my_statfsp->f_iosize;
253 my_fsid = my_statfsp->f_fsid;
254 if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
255 printf( "fstatfs and getattrlist results do not match for volume block size \n" );
256 goto test_failed_exit;
257 }
258
259 /* try again with statfs */
260 my_err = statfs( "/System/Library/Kernels/kernel", my_statfsp );
261 if ( my_err == -1 ) {
262 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
263 goto test_failed_exit;
264 }
265
266 /* validate resutls */
267 if ( my_io_size != my_statfsp->f_iosize || my_fsid.val[0] != my_statfsp->f_fsid.val[0] ||
268 my_fsid.val[1] != my_statfsp->f_fsid.val[1] ) {
269 printf( "statfs call failed. wrong f_iosize or f_fsid! \n" );
270 goto test_failed_exit;
271 }
272 if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
273 printf( "statfs and getattrlist results do not match for volume block size \n" );
274 goto test_failed_exit;
275 }
276
277 /* We passed the test */
278 my_err = 0;
279
280 test_failed_exit:
281 if(my_err != 0)
282 my_err = -1;
283
284 test_passed_exit:
285 if ( my_fd != -1 )
286 close( my_fd );
287 if ( my_bufferp != NULL ) {
288 vm_deallocate(mach_task_self(), (vm_address_t)my_bufferp, my_buffer_size);
289 }
290
291 return( my_err );
292 }
293