blob: bcdbfb00857370937e206b00cb368ad85e42f8d0 [file] [log] [blame]
robbiewbfb98f92002-06-13 05:26:55 +00001/*
2 *
3 * Copyright (c) International Business Machines Corp., 2002
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20
21/*
22 * NAME
23 * diotest1.c
24 *
25 * DESCRIPTION
26 * Copy the contents of the input file to output file using direct read
27 * and direct write. The input file size is numblks*bufsize.
28 * The read and write calls use bufsize to perform IO. Input and output
29 * files can be specified through commandline and is useful for running
30 * test with raw devices as files.
31 *
32 * USAGE
33 * diotest1 [-b bufsize] [-n numblks] [-i infile] [-o outfile]
34 *
35 * History
36 * 04/22/2002 Narasimha Sharoff nsharoff@us.ibm.com
37 *
38 * RESTRICTIONS
39 * None
40*/
41
42#include <stdio.h>
43#include <stdlib.h>
44#include <unistd.h>
45#include <signal.h>
46#include <string.h>
47#include <sys/fcntl.h>
48#include <errno.h>
49
robbiew8680e9b2003-11-19 15:29:01 +000050#include "diotest_routines.h"
51
robbiew96f4bb32003-03-13 15:39:53 +000052#include "test.h"
53#include "usctest.h"
54
robbiew8680e9b2003-11-19 15:29:01 +000055char *TCID="diotest01"; /* Test program identifier. */
56int TST_TOTAL=1; /* Total number of test conditions */
57
robbiewf7dc1be2003-03-14 16:20:37 +000058
robbiew96f4bb32003-03-13 15:39:53 +000059#ifdef O_DIRECT
60
robbiewbfb98f92002-06-13 05:26:55 +000061#define BUFSIZE 8192
62#define NBLKS 20
63#define LEN 30
64#define TRUE 1
65
66extern char *valloc();
67
68/*
69 * prg_usage: display the program usage.
70*/
71void
72prg_usage()
73{
74 fprintf(stderr, "Usage: diotest1 [-b bufsize] [-n numblks] [-i infile] [-o outfile]\n");
75 exit(1);
76}
77
78/*
79 * fail_clean: cleanup and exit.
80*/
81void
82fail_clean(int fd1, int fd2, char *infile, char *outfile)
83{
84 close(fd1);
85 close(fd2);
86 unlink(infile);
87 unlink(outfile);
88 exit(1);
89}
90
91int
92main(int argc, char *argv[])
93{
94 int bufsize = BUFSIZE; /* Buffer size. Default 8k */
95 int numblks = NBLKS; /* Number of blocks. Default 20 */
96 char infile[LEN]; /* Input file. Default "infile" */
97 char outfile[LEN]; /* Output file. Default "outfile" */
robbiew8680e9b2003-11-19 15:29:01 +000098 int fd, fd1, fd2;
robbiewbfb98f92002-06-13 05:26:55 +000099 int i, n, offset;
100 char *buf;
101
102 /* Options */
103 strcpy(infile, "infile"); /* Default input file */
104 strcpy(outfile, "outfile"); /* Default outfile file */
105 while ((i = getopt(argc, argv, "b:n:i:o:")) != -1) {
106 switch(i) {
107 case 'b':
108 if ((bufsize = atoi(optarg)) <= 0) {
109 fprintf(stderr, "bufsize must be > 0\n");
110 prg_usage();
111 }
112 if (bufsize % 4096 != 0) {
113 fprintf(stderr, "bufsize must be multiple of 4k\n");
114 prg_usage();
115 }
116 break;
117 case 'n':
118 if ((numblks = atoi(optarg)) <= 0) {
119 fprintf(stderr, "numblks must be > 0\n");
120 prg_usage();
121 }
122 break;
123 case 'i':
124 strcpy(infile, optarg);
125 break;
126 case 'o':
127 strcpy(outfile, optarg);
128 break;
129 default:
130 prg_usage();
131 }
132 }
133
robbiew8680e9b2003-11-19 15:29:01 +0000134 /* Test for filesystem support of O_DIRECT */
135 if ((fd = open(infile, O_DIRECT, 0666)) < 0) {
136 tst_resm(TCONF,"O_DIRECT is not supported by this filesystem.");
137 tst_exit();
138 }else{
139 close(fd);
140 }
141
robbiewbfb98f92002-06-13 05:26:55 +0000142 /* Open files */
143 if ((fd1 = open(infile, O_DIRECT|O_RDWR|O_CREAT, 0666)) < 0) {
144 fprintf(stderr, "open infile: %s\n", strerror(errno));
145 exit(1);
146 }
147
148 if ((fd2 = open(outfile, O_DIRECT|O_RDWR|O_CREAT, 0666)) < 0) {
149 fprintf(stderr, "open outfile: %s\n", strerror(errno));
150 close(fd1);
151 unlink("infile");
152 exit(1);
153 }
154
155 /* Allocate for buf, Create input file */
156 if ((buf = valloc(bufsize)) == 0) {
157 fprintf(stderr, "valloc buf: %s\n", strerror(errno));
158 fail_clean(fd1, fd2, infile, outfile);
159 }
160 for (i = 0; i < numblks; i++) {
161 fillbuf(buf, bufsize, (char)(i % 256));
162 if (write(fd1, buf, bufsize) < 0) {
163 fprintf(stderr, "write infile failed: %s\n",
164 strerror(errno));
165 fail_clean(fd1, fd2, infile, outfile);
166 }
167 }
168
169 /* Copy infile to outfile using direct read and direct write */
170 offset = 0;
171 if (lseek(fd1, offset, SEEK_SET) < 0) {
172 fprintf(stderr, "lseek infd:%s\n", strerror(errno));
173 fail_clean(fd1, fd2, infile, outfile);
174 }
175 while ((n = read(fd1, buf, bufsize)) > 0) {
176 if (lseek(fd2, offset, SEEK_SET) < 0) {
177 fprintf(stderr, "lseek outfd:%s\n", strerror(errno));
178 fail_clean(fd1, fd2, infile, outfile);
179 }
180 if (write(fd2, buf, n) < n) {
181 fprintf(stderr, "write failed:%s\n", strerror(errno));
182 fail_clean(fd1, fd2, infile, outfile);
183 }
184 offset += n;
185 if (lseek(fd1, offset, SEEK_SET) < 0) {
186 fprintf(stderr, "lseek infd:%s\n", strerror(errno));
187 fail_clean(fd1, fd2, infile, outfile);
188 }
189 }
190
191 /* Verify */
192 if(filecmp(infile, outfile) != 0) {
193 fprintf(stderr,"diotest1: file compare failed for %s and %s\n",
194 infile, outfile);
195 fail_clean(fd1, fd2, infile, outfile);
196 }
197 fprintf(stdout, "diotest1: 1 testblock completed\n");
198
199 /* Cleanup */
200 close(fd1);
201 close(fd2);
202 unlink(infile);
203 unlink(outfile);
204 exit(0);
205}
robbiew96f4bb32003-03-13 15:39:53 +0000206
207#else /* O_DIRECT */
208
robbiew96f4bb32003-03-13 15:39:53 +0000209int
210main() {
211
212 tst_resm(TCONF,"O_DIRECT is not defined.");
robbiew8680e9b2003-11-19 15:29:01 +0000213 tst_exit();
robbiew96f4bb32003-03-13 15:39:53 +0000214}
215#endif /* O_DIRECT */