5 * Created by Ryan Branche on 2/17/08.
6 * Copyright 2008 Apple Inc. All rights reserved.
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.
14 #define _DARWIN_NO_64_BIT_INODE 1
17 #include <mach/mach.h>
20 extern char g_target_path
[ PATH_MAX
];
21 extern int g_skip_setuid_tests
;
22 extern int g_is_under_rosetta
;
23 extern int g_is_single_user
;
25 /* **************************************************************************************************************
26 * Test getdirentries system call.
27 * **************************************************************************************************************
29 struct test_attr_buf
{
31 fsobj_type_t obj_type
;
33 struct timespec backup_time
;
36 typedef struct test_attr_buf test_attr_buf
;
38 int getdirentries_test( void * the_argp
)
40 int my_err
, done
, found_it
, i
;
43 char * my_pathp
= NULL
;
44 char * my_bufp
= NULL
;
46 unsigned long my_base
;
47 unsigned long my_count
;
48 unsigned long my_new_state
;
50 struct timespec my_new_backup_time
;
51 struct attrlist my_attrlist
;
52 test_attr_buf my_attr_buf
[4];
53 struct statfs my_statfs_buf
;
56 /* need to know type of file system */
57 my_err
= statfs( &g_target_path
[0], &my_statfs_buf
);
59 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
60 goto test_failed_exit
;
62 if ( memcmp( &my_statfs_buf
.f_fstypename
[0], "ufs", 3 ) == 0 ) {
66 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_bufp
, (1024 * 5), VM_FLAGS_ANYWHERE
);
67 if(my_kr
!= KERN_SUCCESS
){
68 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
69 goto test_failed_exit
;
72 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
73 if(my_kr
!= KERN_SUCCESS
){
74 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
75 goto test_failed_exit
;
79 strcat( my_pathp
, &g_target_path
[0] );
80 strcat( my_pathp
, "/" );
82 /* create a test file */
83 my_err
= create_random_name( my_pathp
, 1 );
85 goto test_failed_exit
;
88 /* get pointer to just the file name */
89 my_file_namep
= strrchr( my_pathp
, '/' );
92 /* check out the test directory */
93 my_fd
= open( &g_target_path
[0], (O_RDONLY
), 0 );
95 printf( "open failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
96 goto test_failed_exit
;
100 while ( done
== 0 ) {
102 struct dirent
* my_dirent_p
;
104 /* This call requires that 64-bit inodes are disabled */
105 my_result
= getdirentries( my_fd
, my_bufp
, (1024 * 5), &my_base
);
106 if ( my_result
<= 0 )
108 for ( i
= 0; i
< my_result
; ) {
109 my_dirent_p
= (struct dirent
*) (my_bufp
+ i
);
111 printf( "d_ino %d d_reclen %d d_type %d d_namlen %d \"%s\" \n",
112 my_dirent_p
->d_ino
, my_dirent_p
->d_reclen
, my_dirent_p
->d_type
,
113 my_dirent_p
->d_namlen
, &my_dirent_p
->d_name
[0] );
116 i
+= my_dirent_p
->d_reclen
;
117 /* validate results by looking for our test file */
118 if ( my_dirent_p
->d_type
== DT_REG
&& my_dirent_p
->d_ino
!= 0 &&
119 strlen( my_file_namep
) == my_dirent_p
->d_namlen
&&
120 memcmp( &my_dirent_p
->d_name
[0], my_file_namep
, my_dirent_p
->d_namlen
) == 0 ) {
126 if ( found_it
== 0 ) {
127 printf( "getdirentries failed to find test file. \n" );
128 goto test_failed_exit
;
138 if ( my_pathp
!= NULL
) {
140 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
142 if ( my_bufp
!= NULL
) {
143 vm_deallocate(mach_task_self(), (vm_address_t
)my_bufp
, (1024 * 5));
150 /* **************************************************************************************************************
151 * Test 32-bit inode versions of statfs, fstatfs, and getfsstat system calls.
152 * **************************************************************************************************************
156 struct vol_attr_buf
{
159 u_int32_t io_blksize
;
162 typedef struct vol_attr_buf vol_attr_buf
;
164 int statfs_32bit_inode_tests( void * the_argp
)
166 int my_err
, my_count
, i
;
170 void * my_bufferp
= NULL
;
171 struct statfs
* my_statfsp
;
174 struct attrlist my_attrlist
;
175 vol_attr_buf my_attr_buf
;
178 my_buffer_size
= (sizeof(struct statfs
) * 10);
179 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_bufferp
, my_buffer_size
, VM_FLAGS_ANYWHERE
);
180 if(my_kr
!= KERN_SUCCESS
){
181 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
182 goto test_failed_exit
;
185 my_statfsp
= (struct statfs
*) my_bufferp
;
186 my_err
= statfs( "/", my_statfsp
);
187 if ( my_err
== -1 ) {
188 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
189 goto test_failed_exit
;
191 if ( memcmp( &my_statfsp
->f_fstypename
[0], "ufs", 3 ) == 0 ) {
195 my_count
= getfsstat( (struct statfs
*)my_bufferp
, my_buffer_size
, MNT_NOWAIT
);
196 if ( my_count
== -1 ) {
197 printf( "getfsstat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
198 goto test_failed_exit
;
201 /* validate results */
202 my_statfsp
= (struct statfs
*) my_bufferp
;
203 for ( i
= 0; i
< my_count
; i
++, my_statfsp
++ ) {
204 if ( memcmp( &my_statfsp
->f_fstypename
[0], "hfs", 3 ) == 0 ||
205 memcmp( &my_statfsp
->f_fstypename
[0], "ufs", 3 ) == 0 ||
206 memcmp( &my_statfsp
->f_fstypename
[0], "devfs", 5 ) == 0 ||
207 memcmp( &my_statfsp
->f_fstypename
[0], "volfs", 5 ) == 0 ) {
208 /* found a valid entry */
212 if ( i
>= my_count
) {
213 printf( "getfsstat call failed. could not find valid f_fstypename! \n" );
214 goto test_failed_exit
;
217 /* set up to validate results via multiple sources. we use getattrlist to get volume
218 * related attributes to verify against results from fstatfs and statfs - but only if
219 * we are not targeting ufs volume since it doesn't support getattr calls
222 memset( &my_attrlist
, 0, sizeof(my_attrlist
) );
223 my_attrlist
.bitmapcount
= ATTR_BIT_MAP_COUNT
;
224 my_attrlist
.volattr
= (ATTR_VOL_SIZE
| ATTR_VOL_IOBLOCKSIZE
);
225 my_err
= getattrlist( "/", &my_attrlist
, &my_attr_buf
, sizeof(my_attr_buf
), 0 );
227 printf( "getattrlist call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
228 goto test_failed_exit
;
232 /* open kernel to use as test file for fstatfs */
233 my_fd
= open( "/mach_kernel", O_RDONLY
, 0 );
235 printf( "open call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
236 goto test_failed_exit
;
239 /* testing fstatfs */
240 my_statfsp
= (struct statfs
*) my_bufferp
;
241 my_err
= fstatfs( my_fd
, my_statfsp
);
242 if ( my_err
== -1 ) {
243 printf( "fstatfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
244 goto test_failed_exit
;
247 /* validate results */
248 if ( !(memcmp( &my_statfsp
->f_fstypename
[0], "hfs", 3 ) == 0 ||
249 memcmp( &my_statfsp
->f_fstypename
[0], "ufs", 3 ) == 0) ) {
250 printf( "fstatfs call failed. could not find valid f_fstypename! \n" );
251 goto test_failed_exit
;
253 my_io_size
= my_statfsp
->f_iosize
;
254 my_fsid
= my_statfsp
->f_fsid
;
255 if ( is_ufs
== 0 && my_statfsp
->f_iosize
!= my_attr_buf
.io_blksize
) {
256 printf( "fstatfs and getattrlist results do not match for volume block size \n" );
257 goto test_failed_exit
;
260 /* try again with statfs */
261 my_err
= statfs( "/mach_kernel", my_statfsp
);
262 if ( my_err
== -1 ) {
263 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
264 goto test_failed_exit
;
267 /* validate resutls */
268 if ( my_io_size
!= my_statfsp
->f_iosize
|| my_fsid
.val
[0] != my_statfsp
->f_fsid
.val
[0] ||
269 my_fsid
.val
[1] != my_statfsp
->f_fsid
.val
[1] ) {
270 printf( "statfs call failed. wrong f_iosize or f_fsid! \n" );
271 goto test_failed_exit
;
273 if ( is_ufs
== 0 && my_statfsp
->f_iosize
!= my_attr_buf
.io_blksize
) {
274 printf( "statfs and getattrlist results do not match for volume block size \n" );
275 goto test_failed_exit
;
278 /* We passed the test */
288 if ( my_bufferp
!= NULL
) {
289 vm_deallocate(mach_task_self(), (vm_address_t
)my_bufferp
, my_buffer_size
);