blob: 8c0458c3585a5e22c8361d4837f93c1f345ca45b [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"
52#include "usctest.h"
53
Wanlong Gao354ebb42012-12-07 10:10:04 +080054char *TCID = "diotest01"; /* Test program identifier. */
55int TST_TOTAL = 1; /* Total number of test conditions */
robbiew8680e9b2003-11-19 15:29:01 +000056
robbiew96f4bb32003-03-13 15:39:53 +000057#ifdef O_DIRECT
58
robbiewbfb98f92002-06-13 05:26:55 +000059#define BUFSIZE 8192
60#define NBLKS 20
61#define LEN 30
62#define TRUE 1
63
subrata_modak4bb656a2009-02-26 12:02:09 +000064/*
robbiewbfb98f92002-06-13 05:26:55 +000065 * prg_usage: display the program usage.
66*/
Wanlong Gao354ebb42012-12-07 10:10:04 +080067void prg_usage()
robbiewbfb98f92002-06-13 05:26:55 +000068{
Wanlong Gao354ebb42012-12-07 10:10:04 +080069 fprintf(stderr,
70 "Usage: diotest1 [-b bufsize] [-n numblks] [-i infile] [-o outfile]\n");
Cyril Hrubis526fdf82014-12-04 14:35:01 +010071 tst_brkm(TBROK, NULL, "usage");
robbiewbfb98f92002-06-13 05:26:55 +000072}
73
74/*
75 * fail_clean: cleanup and exit.
76*/
Wanlong Gao354ebb42012-12-07 10:10:04 +080077void fail_clean(int fd1, int fd2, char *infile, char *outfile)
robbiewbfb98f92002-06-13 05:26:55 +000078{
79 close(fd1);
80 close(fd2);
81 unlink(infile);
82 unlink(outfile);
Cyril Hrubis526fdf82014-12-04 14:35:01 +010083 tst_brkm(TFAIL, NULL, "Test failed");
robbiewbfb98f92002-06-13 05:26:55 +000084}
85
Wanlong Gao354ebb42012-12-07 10:10:04 +080086int main(int argc, char *argv[])
robbiewbfb98f92002-06-13 05:26:55 +000087{
Wanlong Gao354ebb42012-12-07 10:10:04 +080088 int bufsize = BUFSIZE; /* Buffer size. Default 8k */
89 int numblks = NBLKS; /* Number of blocks. Default 20 */
90 char infile[LEN]; /* Input file. Default "infile" */
91 char outfile[LEN]; /* Output file. Default "outfile" */
92 int fd, fd1, fd2;
93 int i, n, offset;
94 char *buf;
robbiewbfb98f92002-06-13 05:26:55 +000095
96 /* Options */
97 strcpy(infile, "infile"); /* Default input file */
98 strcpy(outfile, "outfile"); /* Default outfile file */
99 while ((i = getopt(argc, argv, "b:n:i:o:")) != -1) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800100 switch (i) {
robbiewbfb98f92002-06-13 05:26:55 +0000101 case 'b':
102 if ((bufsize = atoi(optarg)) <= 0) {
103 fprintf(stderr, "bufsize must be > 0\n");
104 prg_usage();
105 }
106 if (bufsize % 4096 != 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800107 fprintf(stderr,
108 "bufsize must be multiple of 4k\n");
robbiewbfb98f92002-06-13 05:26:55 +0000109 prg_usage();
110 }
111 break;
112 case 'n':
113 if ((numblks = atoi(optarg)) <= 0) {
114 fprintf(stderr, "numblks must be > 0\n");
115 prg_usage();
116 }
117 break;
118 case 'i':
119 strcpy(infile, optarg);
120 break;
121 case 'o':
122 strcpy(outfile, optarg);
123 break;
124 default:
125 prg_usage();
126 }
127 }
128
robbiew8680e9b2003-11-19 15:29:01 +0000129 /* Test for filesystem support of O_DIRECT */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800130 if ((fd = open(infile, O_DIRECT | O_RDWR | O_CREAT, 0666)) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100131 tst_brkm(TCONF,
132 NULL,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800133 "O_DIRECT is not supported by this filesystem.");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134 } else {
robbiew8680e9b2003-11-19 15:29:01 +0000135 close(fd);
136 }
137
robbiewbfb98f92002-06-13 05:26:55 +0000138 /* Open files */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800139 if ((fd1 = open(infile, O_DIRECT | O_RDWR | O_CREAT, 0666)) < 0) {
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100140 tst_brkm(TFAIL, NULL, "open infile failed: %s",
141 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000142 }
143
Wanlong Gao354ebb42012-12-07 10:10:04 +0800144 if ((fd2 = open(outfile, O_DIRECT | O_RDWR | O_CREAT, 0666)) < 0) {
robbiewbfb98f92002-06-13 05:26:55 +0000145 close(fd1);
robbiew92b688b2004-03-01 22:36:38 +0000146 unlink(infile);
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100147 tst_brkm(TFAIL, NULL, "open outfile failed: %s",
148 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000149 }
150
151 /* Allocate for buf, Create input file */
152 if ((buf = valloc(bufsize)) == 0) {
vapier0bdbaa32006-02-12 10:56:55 +0000153 tst_resm(TFAIL, "valloc() failed: %s", strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000154 fail_clean(fd1, fd2, infile, outfile);
155 }
156 for (i = 0; i < numblks; i++) {
157 fillbuf(buf, bufsize, (char)(i % 256));
subrata_modak4bb656a2009-02-26 12:02:09 +0000158 if (write(fd1, buf, bufsize) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800159 tst_resm(TFAIL, "write infile failed: %s",
160 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000161 fail_clean(fd1, fd2, infile, outfile);
162 }
163 }
164
165 /* Copy infile to outfile using direct read and direct write */
166 offset = 0;
167 if (lseek(fd1, offset, SEEK_SET) < 0) {
vapier0bdbaa32006-02-12 10:56:55 +0000168 tst_resm(TFAIL, "lseek(infd) failed: %s", strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000169 fail_clean(fd1, fd2, infile, outfile);
170 }
171 while ((n = read(fd1, buf, bufsize)) > 0) {
172 if (lseek(fd2, offset, SEEK_SET) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800173 tst_resm(TFAIL, "lseek(outfd) failed: %s",
174 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000175 fail_clean(fd1, fd2, infile, outfile);
176 }
177 if (write(fd2, buf, n) < n) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800178 tst_resm(TFAIL, "write(outfd) failed: %s",
179 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000180 fail_clean(fd1, fd2, infile, outfile);
181 }
182 offset += n;
183 if (lseek(fd1, offset, SEEK_SET) < 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800184 tst_resm(TFAIL, "lseek(infd) failed: %s",
185 strerror(errno));
robbiewbfb98f92002-06-13 05:26:55 +0000186 fail_clean(fd1, fd2, infile, outfile);
187 }
188 }
189
190 /* Verify */
Garrett Cooperdf3eb162010-11-28 22:44:32 -0800191 if (filecmp(infile, outfile) != 0) {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800192 tst_resm(TFAIL, "file compare failed for %s and %s",
193 infile, outfile);
robbiewbfb98f92002-06-13 05:26:55 +0000194 fail_clean(fd1, fd2, infile, outfile);
195 }
robbiewbfb98f92002-06-13 05:26:55 +0000196
197 /* Cleanup */
198 close(fd1);
199 close(fd2);
200 unlink(infile);
201 unlink(outfile);
robbiew92b688b2004-03-01 22:36:38 +0000202 tst_resm(TPASS, "Test passed");
203 tst_exit();
robbiewbfb98f92002-06-13 05:26:55 +0000204}
robbiew96f4bb32003-03-13 15:39:53 +0000205
206#else /* O_DIRECT */
207
Wanlong Gao354ebb42012-12-07 10:10:04 +0800208int main()
209{
Cyril Hrubis526fdf82014-12-04 14:35:01 +0100210 tst_brkm(TCONF, NULL, "O_DIRECT is not defined.");
robbiew96f4bb32003-03-13 15:39:53 +0000211}
Chris Dearmanec6edca2012-10-17 19:54:01 -0700212#endif /* O_DIRECT */