2 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <sys/types.h>
23 #include <lib/errtest.h>
29 /*---------------------------------------------------------------------------
31 Test program used to test the DMAPI function dm_punch_hole(). The
34 test_hole [-v] [-s sid] pathname
38 is the path to a specific copy of ls, important only for its size
40 is the path to the test filesystem
42 is the session ID whose events you you are interested in.
44 ----------------------------------------------------------------------------*/
47 extern char *sys_errlist[];
58 fprintf(stderr, "usage:\t%s [-v] [-s sid] ls_path directoryname\n",
69 dm_sessid_t sid = DM_NO_SESSION;
70 char *pathname = NULL;
74 dm_extent_t extent[20];
79 dm_token_t test_token;
87 dm_off_t blocksize = 5;
93 if (Progname = strrchr(argv[0], '/')) {
99 /* Crack and validate the command line options. */
101 while ((opt = getopt(argc, argv, "vs:")) != EOF) {
113 if (optind + 2 != argc)
115 ls_path = argv[optind];
116 pathname = argv[optind+1];
118 if (dm_init_service(&name) == -1) {
119 fprintf(stdout, "Can't initialize the DMAPI\n");
122 if (sid == DM_NO_SESSION)
123 find_test_session(&sid);
125 /* Get the directory handle. */
127 if (dm_path_to_handle(pathname, &hanp, &hlen)) {
129 "ERROR: can't get handle for directory %s\n", pathname);
133 printf("Hole test beginning...\n");
134 sprintf(filename, "%s/VeryLongUnlikelyFilename.HOLETEST", pathname);
135 sprintf(command, "cp %s %s \n", ls_path, filename);
138 if (dm_path_to_handle(filename, &hanp, &hlen)) {
139 fprintf(stdout, "can't get handle for %s\n; aborting test",
142 sprintf(command, "rm %s \n", filename);
144 fprintf(stdout, "\tHole test aborted.\n");
146 dm_handle_free(hanp, hlen);
150 /* ## Get the block size using a length-1 probe. ## */
151 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 1, 0,
155 fprintf(stdout, "Error: block size appears to be 0!\n");
157 sprintf(command, "rm %s \n", filename);
159 fprintf(stdout, "\tHole test aborted.\n");
161 dm_handle_free(hanp, hlen);
165 /* Check that dm_probe_hole returns an extent from the next
166 * highest multiple of the block size, to the end of the file
168 for (offset = 0; offset < 29604; offset++) {
169 if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
171 fprintf(stdout, "dm_probe_hole failed on pass %lld (%s)\n",
172 (long long)offset, ERR_NAME);
177 "Error: hole did not extend to end of file!\n");
179 if (blocksize*(roff/blocksize) != roff) {
181 "Error: offset not a multiple of block size!\n");
186 /* Be sure dm_punch_hole doesn't change the time stamp,
187 * and verify that dm_get_allocinfo shows a hole
188 * followed by an extent to the end of the file.
190 for(offset = 28672; offset > 0; offset-=blocksize) {
191 if (stat(filename, &buf)){
193 "Error: unable to stat the test file; %s (1st)\n",
197 if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
199 fprintf(stdout, "dm_probe_hole failed, %s\n",
203 if (roff != offset) {
205 "Error: presumed offset was not %lld.\n",
208 if (dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN,
210 fprintf(stdout, "dm_punch_hole failed, %s\n",
214 if (stat(filename, &checkbuf)){
216 "Error: unable to stat the test file. (2nd)\n");
220 /* COMPARE BUF AND CHECKBUF! */
222 if ((buf.st_atime == checkbuf.st_atime) &&
223 (buf.st_mtime == checkbuf.st_mtime) &&
224 (buf.st_ctime == checkbuf.st_ctime))
226 if ((buf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) &&
227 (buf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) &&
228 (buf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) &&
229 (buf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) &&
230 (buf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) &&
231 (buf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec))
236 "\tTime stamp unchanged by hole from offset %lld.\n",
237 (long long)(offset));
242 "Error: punch_hole changed file's time stamp.\n");
245 if ((dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN,
246 &ex_off, 1, extent, &nelem) == 1) &&
247 (extent->ex_type == DM_EXTENT_RES) &&
248 (dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN,
249 &ex_off, 1, extent, &nelem) == 0) &&
250 (extent->ex_type == DM_EXTENT_HOLE)) {
251 if (extent->ex_offset == roff){
253 fprintf(stdout, "\tVerified hole at %lld\n",
254 (long long)(extent->ex_offset));
258 fprintf(stdout, "\tError: get_allocinfo found hole at %lld\n",
259 (long long)(extent->ex_offset));
263 fprintf(stdout, "\tError: get_allocinfo did not find an "
264 "extent followed by a hole!\n");
268 /*------------------------*\
269 |* ## Errno subtests ## *|
270 \*------------------------*/
271 fprintf(stdout, "\t(beginning errno subtests...)\n");
272 /*---------------------------------------------------------*/
274 "probe (from past EOF)",
275 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 30000, length,
277 /*---------------------------------------------------------*/
279 PROBLEM: No error is produced.
280 off+len >= filesize should produce E2BIG...
283 "probe (to past EOF)",
284 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 15000, 150000,
287 /*---------------------------------------------------------*/
288 SHAREDTEST("probe", hanp, hlen, test_token,
289 dm_probe_hole(sid, hanp, hlen, test_token,
291 /*---------------------------------------------------------*/
292 EXCLTEST("punch", hanp, hlen, test_token,
293 dm_punch_hole(sid, hanp, hlen, test_token, 0, 0))
294 /*---------------------------------------------------------*/
297 dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN,
299 /*---------------------------------------------------------*/
300 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
302 "Cannot create a test handle (%s); skipping EBADF test\n",
306 ((char *) test_vp)[hlen/2]++;
309 dm_probe_hole(sid, test_vp, hlen, DM_NO_TOKEN,
314 dm_punch_hole(sid, test_vp, hlen, DM_NO_TOKEN,
317 dm_handle_free(test_vp, hlen);
318 /*---------------------------------------------------------*/
320 "probe (null handle)",
321 dm_probe_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length,
325 dm_probe_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length,
326 &roff, (dm_size_t*)(-1000)))
329 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
330 (dm_off_t*)(-1000), &rlen))
331 /*---------------------------------------------------------*/
334 dm_punch_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length))
335 /*---------------------------------------------------------*/
337 "probe (bad session)",
338 dm_probe_hole(-100, hanp, hlen, DM_NO_TOKEN, offset, length,
340 /*---------------------------------------------------------*/
343 dm_probe_hole(sid, hanp, hlen, 0, offset, length,
345 /*---------------------------------------------------------*/
347 "probe (bad token 2)",
348 dm_probe_hole(sid, hanp, hlen, 0, offset, length,
350 /*---------------------------------------------------------*/
351 fprintf(stdout, "\t(errno subtests complete)\n");
354 sprintf(command, "rm %s \n", filename);
356 printf("Hole test complete.\n");
358 dm_handle_free(hanp, hlen);