]>
git.saurik.com Git - apple/hfs.git/blob - tests/cases/test-throttled-io.c
4 #include <sys/resource.h>
5 #include <CommonCrypto/CommonDigest.h>
12 #include <sys/errno.h>
13 #include <libkern/OSAtomic.h>
17 #include "hfs-tests.h"
18 #include "test-utils.h"
19 #include "disk-image.h"
23 static disk_image_t
*gDI
;
24 static char *gFile1
, *gFile2
, *gFile3
;
26 static pid_t gPID
= 0;
28 static const size_t gBuf_size
= 64 * 1024 * 1024;
30 static void start_background_io(void)
33 asprintf(&of
, "of=%s", gFile1
);
35 assert_no_err(posix_spawn(&gPID
, "/bin/dd", NULL
, NULL
,
36 (char *[]){ "/bin/dd", "if=/dev/random",
41 static void end_background_io(void)
52 static int run_test1(void)
55 // Kick off another process to ensure we get throttled
56 start_background_io();
58 assert_no_err(setiopolicy_np(IOPOL_TYPE_DISK
, IOPOL_SCOPE_PROCESS
,
62 assert_with_errno((fd
= open("/dev/random", O_RDONLY
)) >= 0);
63 assert_with_errno((fd2
= open(gFile2
,
64 O_RDWR
| O_CREAT
| O_TRUNC
, 0666)) >= 0);
66 assert_no_err(fcntl(fd2
, F_SINGLE_WRITER
, 1));
67 assert_no_err(fcntl(fd2
, F_NOCACHE
, 1));
69 gBuf
= valloc(gBuf_size
);
73 ssize_t res
= check_io(read(fd
, gBuf
, gBuf_size
), gBuf_size
);
75 CC_SHA1_Update(&ctx
, gBuf
, (CC_LONG
)res
);
77 res
= check_io(write(fd2
, gBuf
, res
), res
);
79 bzero(gBuf
, gBuf_size
);
84 lseek(fd2
, 0, SEEK_SET
);
86 res
= check_io(read(fd2
, gBuf
, gBuf_size
), gBuf_size
);
88 CC_SHA1_Update(&ctx2
, gBuf
, (CC_LONG
)res
);
90 uint8_t digest1
[CC_SHA1_DIGEST_LENGTH
], digest2
[CC_SHA1_DIGEST_LENGTH
];
91 CC_SHA1_Final(digest1
, &ctx
);
92 CC_SHA1_Final(digest2
, &ctx2
);
94 assert(!memcmp(digest1
, digest2
, CC_SHA1_DIGEST_LENGTH
));
96 assert_no_err (close(fd
));
97 assert_no_err (close(fd2
));
104 static volatile uint64_t written
;
105 static volatile bool done
;
107 static void test2_thread(void)
109 int fd
= open(gFile3
, O_RDONLY
);
112 void *b
= gBuf
+ gBuf_size
/ 2;
113 uLong seq
= crc32(0, Z_NULL
, 0);
120 res
= check_io(pread(fd
, b
, gBuf_size
/ 2, offset
), -1);
121 } while (res
== 0 && !done
);
123 assert (res
% 4 == 0);
127 for (uLong
*p
= b
; res
; ++p
, res
-= sizeof(uLong
)) {
128 seq
= crc32(Z_NULL
, (void *)&seq
, 4);
132 if (offset
< written
)
137 assert_no_err (close(fd
));
141 static int run_test2(void)
143 start_background_io();
145 int fd
= open(gFile3
, O_RDWR
| O_CREAT
| O_TRUNC
, 0666);
148 assert_no_err(fcntl(fd
, F_SINGLE_WRITER
, 1));
149 assert_no_err(fcntl(fd
, F_NOCACHE
, 1));
152 pthread_create(&thread
, NULL
, (void *(*)(void *))test2_thread
, NULL
);
153 uLong seq
= crc32(0, Z_NULL
, 0);
155 for (int i
= 0; i
< 4; ++i
) {
157 for (unsigned i
= 0; i
< gBuf_size
/ 2 / sizeof(uLong
); ++i
) {
158 seq
= crc32(Z_NULL
, (void *)&seq
, 4);
162 ssize_t res
= check_io(write(fd
, gBuf
, gBuf_size
/ 2), gBuf_size
/ 2);
171 pthread_join(thread
, NULL
);
173 assert_no_err (close(fd
));
180 static bool clean_up(void)
195 int run_throttled_io(__unused test_ctx_t
*ctx
)
197 gDI
= disk_image_get();
199 asprintf(&gFile1
, "%s/throttled_io.1", gDI
->mount_point
);
200 asprintf(&gFile2
, "%s/throttled_io.2", gDI
->mount_point
);
201 asprintf(&gFile3
, "%s/throttled_io.3", gDI
->mount_point
);
203 test_cleanup(^ bool {
207 int res
= run_test1();