blob: ca3289843b477deed7073abe468ab53e66040137 [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
Wanlong Gao4548c6c2012-10-19 18:03:36 +080017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
robbiewbfb98f92002-06-13 05:26:55 +000018 */
19
robbiewbfb98f92002-06-13 05:26:55 +000020/*
21 * NAME
22 * diotest1.c
23 *
24 * DESCRIPTION
subrata_modak4bb656a2009-02-26 12:02:09 +000025 * Copy the contents of the input file to output file using direct read
26 * and direct write. The input file size is numblks*bufsize.
27 * The read and write calls use bufsize to perform IO. Input and output
28 * files can be specified through commandline and is useful for running
robbiewbfb98f92002-06-13 05:26:55 +000029 * test with raw devices as files.
subrata_modakbdbaec52009-02-26 12:14:51 +000030 *
robbiewbfb98f92002-06-13 05:26:55 +000031 * USAGE
32 * diotest1 [-b bufsize] [-n numblks] [-i infile] [-o outfile]
subrata_modak4bb656a2009-02-26 12:02:09 +000033 *
robbiewbfb98f92002-06-13 05:26:55 +000034 * History
35 * 04/22/2002 Narasimha Sharoff nsharoff@us.ibm.com
36 *
37 * RESTRICTIONS
38 * None
39*/
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <unistd.h>
44#include <signal.h>
45#include <string.h>
46#include <sys/fcntl.h>
47#include <errno.h>
48
robbiew8680e9b2003-11-19 15:29:01 +000049#include "diotest_routines.h"
50
robbiew96f4bb32003-03-13 15:39:53 +000051#include "test.h"
robbiew96f4bb32003-03-13 15:39:53 +000052
Wanlong Gao354ebb42012-12-07 10:10:04 +080053char *TCID = "diotest01"; /* Test program identifier. */
54int TST_TOTAL = 1; /* Total number of test conditions */
robbiew8680e9b2003-11-19 15:29:01 +000055
robbiew96f4bb32003-03-13 15:39:53 +000056#ifdef O_DIRECT
57
robbiewbfb98f92002-06-13 05:26:55 +000058#define BUFSIZE 8192
59#define NBLKS 20
60#define LEN 30
61#define TRUE 1
62
subrata_modak4bb656a2009-02-26 12:02:09 +000063/*
robbiewbfb98f92002-06-13 05:26:55 +000064 * prg_usage: display the program usage.
65*/
Wanlong Gao354ebb42012-12-07 10:10:04 +080066void prg_usage()
robbiewbfb98f92002-06-13 05:26:55 +000067{
Wanlong Gao354ebb42012-12-07 10:10:04 +080068 fprintf(stderr,
69 "Usage: diotest1 [-b bufsize] [-n numblks] [-i infile] [-o outfile]\n");
Cyril Hrubis526fdf82014-12-04 14:35:01 +010070 tst_brkm(TBROK, NULL, "usage");
robbiewbfb98f92002-06-13 05:26:55 +000071}
72
73/*
74 * fail_clean: cleanup and exit.
75*/
Wanlong Gao354ebb42012-12-07 10:10:04 +080076void fail_clean(int fd1, int fd2, char *infile, char *outfile)
robbiewbfb98f92002-06-13 05:26:55 +000077{
78 close(fd1);
79 close(fd2);
80 unlink(infile);
81 unlink(outfile);
Cyril Hrubis526fdf82014-12-04 14:35:01 +010082 tst_brkm(TFAIL, NULL, "Test failed");
robbiewbfb98f92002-06-13 05:26:55 +000083}
84
Wanlong Gao354ebb42012-12-07 10:10:04 +080085int main(int argc, char *argv[])
robbiewbfb98f92002-06-13 05:26:55 +000086{
Wanlong Gao354ebb42012-12-07 10:10:04 +080087 int bufsize = BUFSIZE; /* Buffer size. Default 8k */
88 int numblks = NBLKS; /* Number of blocks. Default 20 */
89 char infile[LEN]; /* Input file. Default "infile" */
90 char outfile[LEN]; /* Output file. Default "outfile" */
91 int fd, fd1, fd2;
92 int i, n, offset;
93 char *buf;
robbiewbfb98f92002-06-13 05:26:55 +000094
95 /* Options */
96 strcpy(infile, "infile"); /* Default input file */
97 strcpy(outfile, "outfile"); /* Default outfile file */
98 while ((i = getopt(argc, argv, "b:n:i:o:")) != -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +080099 switch (i) {
robbiewbfb98f92002-06-13 05:26:55 +0000100 case 'b':
101 if ((bufsize = atoi(optarg)) <= 0) {
102 fprintf(stderr, "bufsize must be > 0\n");
103 prg_usage();
104 }
105 if (bufsize % 4096 != 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800106 fprintf(stderr,
107 "bufsize must be multiple of 4k\n");
robbiewbfb98f92002-06-13 05:26:55 +0000108 prg_usage();
109 }
110 break;
111 case 'n':
112 if ((numblks = atoi(optarg)) <= 0) {
113 fprintf(stderr, "numblks must be > 0\n");
114 prg_usage();
115 }
116 break;
117 case 'i':
118 strcpy(infile, optarg);
119 break;
120 case 'o':
121 strcpy(outfile, optarg);
122 break;
123 default:
124 prg_usage();
125 }
126 }
127
robbiew8680e9b2003-11-19 15:29:01 +0000128 /* Test for filesystem support of O_DIRECT */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800129 if ((fd = open(infile, O_DIRECT | O_RDWR | O_CREAT, 0666)) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100130 tst_brkm(TCONF,
131 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800132 "O_DIRECT is not supported by this filesystem.");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800133 } else {
robbiew8680e9b2003-11-19 15:29:01 +0000134 close(fd);
135 }
136
robbiewbfb98f92002-06-13 05:26:55 +0000137 /* Open files */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800138 if ((fd1 = open(infile, O_DIRECT | O_RDWR | O_CREAT, 0666)) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100139 tst_brkm(TFAIL, NULL, "open infile failed: %s",
140 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000141 }
142
Wanlong Gao354ebb42012-12-07 10:10:04 +0800143 if ((fd2 = open(outfile, O_DIRECT | O_RDWR | O_CREAT, 0666)) < 0) {
robbiewbfb98f92002-06-13 05:26:55 +0000144 close(fd1);
robbiew92b688b2004-03-01 22:36:38 +0000145 unlink(infile);
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100146 tst_brkm(TFAIL, NULL, "open outfile failed: %s",
147 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000148 }
149
150 /* Allocate for buf, Create input file */
151 if ((buf = valloc(bufsize)) == 0) {
vapier0bdbaa32006-02-12 10:56:55 +0000152 tst_resm(TFAIL, "valloc() failed: %s", strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000153 fail_clean(fd1, fd2, infile, outfile);
154 }
155 for (i = 0; i < numblks; i++) {
156 fillbuf(buf, bufsize, (char)(i % 256));
subrata_modak4bb656a2009-02-26 12:02:09 +0000157 if (write(fd1, buf, bufsize) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800158 tst_resm(TFAIL, "write infile failed: %s",
159 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000160 fail_clean(fd1, fd2, infile, outfile);
161 }
162 }
163
164 /* Copy infile to outfile using direct read and direct write */
165 offset = 0;
166 if (lseek(fd1, offset, SEEK_SET) < 0) {
vapier0bdbaa32006-02-12 10:56:55 +0000167 tst_resm(TFAIL, "lseek(infd) failed: %s", strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000168 fail_clean(fd1, fd2, infile, outfile);
169 }
170 while ((n = read(fd1, buf, bufsize)) > 0) {
171 if (lseek(fd2, offset, SEEK_SET) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800172 tst_resm(TFAIL, "lseek(outfd) failed: %s",
173 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000174 fail_clean(fd1, fd2, infile, outfile);
175 }
176 if (write(fd2, buf, n) < n) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800177 tst_resm(TFAIL, "write(outfd) failed: %s",
178 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000179 fail_clean(fd1, fd2, infile, outfile);
180 }
181 offset += n;
182 if (lseek(fd1, offset, SEEK_SET) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800183 tst_resm(TFAIL, "lseek(infd) failed: %s",
184 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000185 fail_clean(fd1, fd2, infile, outfile);
186 }
187 }
188
189 /* Verify */
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800190 if (filecmp(infile, outfile) != 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800191 tst_resm(TFAIL, "file compare failed for %s and %s",
192 infile, outfile);
robbiewbfb98f92002-06-13 05:26:55 +0000193 fail_clean(fd1, fd2, infile, outfile);
194 }
robbiewbfb98f92002-06-13 05:26:55 +0000195
196 /* Cleanup */
197 close(fd1);
198 close(fd2);
199 unlink(infile);
200 unlink(outfile);
robbiew92b688b2004-03-01 22:36:38 +0000201 tst_resm(TPASS, "Test passed");
202 tst_exit();
robbiewbfb98f92002-06-13 05:26:55 +0000203}
robbiew96f4bb32003-03-13 15:39:53 +0000204
205#else /* O_DIRECT */
206
Wanlong Gao354ebb42012-12-07 10:10:04 +0800207int main()
208{
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100209 tst_brkm(TCONF, NULL, "O_DIRECT is not defined.");
robbiew96f4bb32003-03-13 15:39:53 +0000210}
Chris Dearmanec6edca2012-10-17 19:54:01 -0700211#endif /* O_DIRECT */