2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
33 #include <sys/types.h>
37 #include <lib/errtest.h>
43 /*---------------------------------------------------------------------------
45 Test program used to test the DMAPI function dm_punch_hole(). The
48 test_hole [-v] [-s sid] pathname
52 is the path to a specific copy of ls, important only for its size
54 is the path to the test filesystem
56 is the session ID whose events you you are interested in.
58 ----------------------------------------------------------------------------*/
61 extern char *sys_errlist[];
72 fprintf(stderr, "usage:\t%s [-v] [-s sid] ls_path directoryname\n",
83 dm_sessid_t sid = DM_NO_SESSION;
84 char *pathname = NULL;
88 dm_extent_t extent[20];
93 dm_token_t test_token;
101 dm_off_t blocksize = 5;
104 struct stat checkbuf;
107 if (Progname = strrchr(argv[0], '/')) {
113 /* Crack and validate the command line options. */
115 while ((opt = getopt(argc, argv, "vs:")) != EOF) {
127 if (optind + 2 != argc)
129 ls_path = argv[optind];
130 pathname = argv[optind+1];
132 if (dm_init_service(&name) == -1) {
133 fprintf(stdout, "Can't initialize the DMAPI\n");
136 if (sid == DM_NO_SESSION)
137 find_test_session(&sid);
139 /* Get the directory handle. */
141 if (dm_path_to_handle(pathname, &hanp, &hlen)) {
143 "ERROR: can't get handle for directory %s\n", pathname);
147 printf("Hole test beginning...\n");
148 sprintf(filename, "%s/VeryLongUnlikelyFilename.HOLETEST", pathname);
149 sprintf(command, "cp %s %s \n", ls_path, filename);
152 if (dm_path_to_handle(filename, &hanp, &hlen)) {
153 fprintf(stdout, "can't get handle for %s\n; aborting test",
156 sprintf(command, "rm %s \n", filename);
158 fprintf(stdout, "\tHole test aborted.\n");
160 dm_handle_free(hanp, hlen);
164 /* ## Get the block size using a length-1 probe. ## */
165 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 1, 0,
169 fprintf(stdout, "Error: block size appears to be 0!\n");
171 sprintf(command, "rm %s \n", filename);
173 fprintf(stdout, "\tHole test aborted.\n");
175 dm_handle_free(hanp, hlen);
179 /* Check that dm_probe_hole returns an extent from the next
180 * highest multiple of the block size, to the end of the file
182 for (offset = 0; offset < 29604; offset++) {
183 if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
185 fprintf(stdout, "dm_probe_hole failed on pass %lld (%s)\n",
186 (long long)offset, ERR_NAME);
191 "Error: hole did not extend to end of file!\n");
193 if (blocksize*(roff/blocksize) != roff) {
195 "Error: offset not a multiple of block size!\n");
200 /* Be sure dm_punch_hole doesn't change the time stamp,
201 * and verify that dm_get_allocinfo shows a hole
202 * followed by an extent to the end of the file.
204 for(offset = 28672; offset > 0; offset-=blocksize) {
205 if (stat(filename, &buf)){
207 "Error: unable to stat the test file; %s (1st)\n",
211 if (dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
213 fprintf(stdout, "dm_probe_hole failed, %s\n",
217 if (roff != offset) {
219 "Error: presumed offset was not %lld.\n",
222 if (dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN,
224 fprintf(stdout, "dm_punch_hole failed, %s\n",
228 if (stat(filename, &checkbuf)){
230 "Error: unable to stat the test file. (2nd)\n");
234 /* COMPARE BUF AND CHECKBUF! */
236 if ((buf.st_atime == checkbuf.st_atime) &&
237 (buf.st_mtime == checkbuf.st_mtime) &&
238 (buf.st_ctime == checkbuf.st_ctime))
240 if ((buf.st_atim.tv_sec == checkbuf.st_atim.tv_sec) &&
241 (buf.st_atim.tv_nsec == checkbuf.st_atim.tv_nsec) &&
242 (buf.st_mtim.tv_sec == checkbuf.st_mtim.tv_sec) &&
243 (buf.st_mtim.tv_nsec == checkbuf.st_mtim.tv_nsec) &&
244 (buf.st_ctim.tv_sec == checkbuf.st_ctim.tv_sec) &&
245 (buf.st_ctim.tv_nsec == checkbuf.st_ctim.tv_nsec))
250 "\tTime stamp unchanged by hole from offset %lld.\n",
251 (long long)(offset));
256 "Error: punch_hole changed file's time stamp.\n");
259 if ((dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN,
260 &ex_off, 1, extent, &nelem) == 1) &&
261 (extent->ex_type == DM_EXTENT_RES) &&
262 (dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN,
263 &ex_off, 1, extent, &nelem) == 0) &&
264 (extent->ex_type == DM_EXTENT_HOLE)) {
265 if (extent->ex_offset == roff){
267 fprintf(stdout, "\tVerified hole at %lld\n",
268 (long long)(extent->ex_offset));
272 fprintf(stdout, "\tError: get_allocinfo found hole at %lld\n",
273 (long long)(extent->ex_offset));
277 fprintf(stdout, "\tError: get_allocinfo did not find an "
278 "extent followed by a hole!\n");
282 /*------------------------*\
283 |* ## Errno subtests ## *|
284 \*------------------------*/
285 fprintf(stdout, "\t(beginning errno subtests...)\n");
286 /*---------------------------------------------------------*/
288 "probe (from past EOF)",
289 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 30000, length,
291 /*---------------------------------------------------------*/
293 PROBLEM: No error is produced.
294 off+len >= filesize should produce E2BIG...
297 "probe (to past EOF)",
298 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, 15000, 150000,
301 /*---------------------------------------------------------*/
302 SHAREDTEST("probe", hanp, hlen, test_token,
303 dm_probe_hole(sid, hanp, hlen, test_token,
305 /*---------------------------------------------------------*/
306 EXCLTEST("punch", hanp, hlen, test_token,
307 dm_punch_hole(sid, hanp, hlen, test_token, 0, 0))
308 /*---------------------------------------------------------*/
311 dm_punch_hole(sid, hanp, hlen, DM_NO_TOKEN,
313 /*---------------------------------------------------------*/
314 if ((test_vp = handle_clone(hanp, hlen)) == NULL) {
316 "Cannot create a test handle (%s); skipping EBADF test\n",
320 ((char *) test_vp)[hlen/2]++;
323 dm_probe_hole(sid, test_vp, hlen, DM_NO_TOKEN,
328 dm_punch_hole(sid, test_vp, hlen, DM_NO_TOKEN,
331 dm_handle_free(test_vp, hlen);
332 /*---------------------------------------------------------*/
334 "probe (null handle)",
335 dm_probe_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length,
339 dm_probe_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length,
340 &roff, (dm_size_t*)(-1000)))
343 dm_probe_hole(sid, hanp, hlen, DM_NO_TOKEN, offset, length,
344 (dm_off_t*)(-1000), &rlen))
345 /*---------------------------------------------------------*/
348 dm_punch_hole(sid, 0, hlen, DM_NO_TOKEN, offset, length))
349 /*---------------------------------------------------------*/
351 "probe (bad session)",
352 dm_probe_hole(-100, hanp, hlen, DM_NO_TOKEN, offset, length,
354 /*---------------------------------------------------------*/
357 dm_probe_hole(sid, hanp, hlen, 0, offset, length,
359 /*---------------------------------------------------------*/
361 "probe (bad token 2)",
362 dm_probe_hole(sid, hanp, hlen, 0, offset, length,
364 /*---------------------------------------------------------*/
365 fprintf(stdout, "\t(errno subtests complete)\n");
368 sprintf(command, "rm %s \n", filename);
370 printf("Hole test complete.\n");
372 dm_handle_free(hanp, hlen);