Print this page
15291 zfs-tests errno flaws exposed by 15220
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/test/zfs-tests/cmd/file_write/file_write.c
+++ new/usr/src/test/zfs-tests/cmd/file_write/file_write.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 +/*
28 + * Copyright 2022 MNX Cloud, Inc.
29 + */
30 +
27 31 #include "../file_common.h"
28 32 #include <libgen.h>
29 33
30 34 static unsigned char bigbuffer[BIGBUFFERSIZE];
31 35
32 36 /*
33 37 * Writes (or appends) a given value to a file repeatedly.
34 38 * See header file for defaults.
35 39 */
36 40
37 41 static void usage(void);
38 42
39 43 int
40 44 main(int argc, char **argv)
41 45 {
42 46 int bigfd;
43 47 int c;
44 48 int oflag = 0;
45 49 int err = 0;
46 50 int k;
47 51 long i;
48 52 int64_t good_writes = 0;
49 53 uchar_t nxtfillchar;
50 54 /*
51 55 * Default Parameters
|
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
52 56 */
53 57 int write_count = BIGFILESIZE;
54 58 uchar_t fillchar = DATA;
55 59 int block_size = BLOCKSZ;
56 60 char *filename = NULL;
57 61 char *operation = NULL;
58 62 offset_t noffset, offset = 0;
59 63 int verbose = 0;
60 64 int rsync = 0;
61 65 int wsync = 0;
66 + int exitcode;
62 67
63 68 /*
64 69 * Process Arguments
65 70 */
66 71 while ((c = getopt(argc, argv, "b:c:d:s:f:o:vwr")) != -1) {
67 72 switch (c) {
68 73 case 'b':
69 74 block_size = atoi(optarg);
70 75 break;
71 76 case 'c':
72 77 write_count = atoi(optarg);
73 78 break;
74 79 case 'd':
75 80 fillchar = atoi(optarg);
76 81 break;
77 82 case 's':
78 83 offset = atoll(optarg);
79 84 break;
80 85 case 'f':
81 86 filename = optarg;
82 87 break;
83 88 case 'o':
84 89 operation = optarg;
85 90 break;
86 91 case 'v':
87 92 verbose = 1;
88 93 break;
89 94 case 'w':
90 95 wsync = 1;
91 96 break;
92 97 case 'r':
93 98 rsync = 1;
94 99 break;
95 100 case '?':
96 101 (void) printf("unknown arg %c\n", optopt);
97 102 usage();
98 103 break;
99 104 }
100 105 }
101 106
102 107 /*
103 108 * Validate Parameters
104 109 */
105 110 if (!filename) {
106 111 (void) printf("Filename not specified (-f <file>)\n");
107 112 err++;
108 113 }
109 114
110 115 if (!operation) {
111 116 (void) printf("Operation not specified (-o <operation>).\n");
112 117 err++;
113 118 }
114 119
115 120 if (block_size > BIGBUFFERSIZE) {
116 121 (void) printf("block_size is too large max==%d.\n",
117 122 BIGBUFFERSIZE);
118 123 err++;
119 124 }
120 125
121 126 if (err) usage();
122 127
123 128 /*
124 129 * Prepare the buffer and determine the requested operation
125 130 */
126 131 nxtfillchar = fillchar;
127 132 k = 0;
128 133
129 134 for (i = 0; i < block_size; i++) {
130 135 bigbuffer[i] = nxtfillchar;
131 136
132 137 if (fillchar == 0) {
133 138 if ((k % DATA_RANGE) == 0) {
134 139 k = 0;
135 140 }
136 141 nxtfillchar = k++;
137 142 }
138 143 }
139 144
140 145 /*
141 146 * using the strncmp of operation will make the operation match the
142 147 * first shortest match - as the operations are unique from the first
143 148 * character this means that we match single character operations
144 149 */
145 150 if ((strncmp(operation, "create", strlen(operation) + 1)) == 0 ||
146 151 (strncmp(operation, "overwrite", strlen(operation) + 1)) == 0) {
147 152 oflag = (O_RDWR|O_CREAT);
148 153 } else if ((strncmp(operation, "append", strlen(operation) + 1)) == 0) {
149 154 oflag = (O_RDWR|O_APPEND);
150 155 } else {
151 156 (void) printf("valid operations are <create|append> not '%s'\n",
152 157 operation);
153 158 usage();
154 159 }
155 160
156 161 if (rsync) {
157 162 oflag = oflag | O_RSYNC;
158 163 }
|
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
159 164
160 165 if (wsync) {
161 166 oflag = oflag | O_SYNC;
162 167 }
163 168
164 169 /*
165 170 * Given an operation (create/overwrite/append), open the file
166 171 * accordingly and perform a write of the appropriate type.
167 172 */
168 173 if ((bigfd = open(filename, oflag, 0666)) == -1) {
174 + exitcode = errno;
169 175 (void) printf("open %s: failed [%s]%d. Aborting!\n", filename,
170 176 strerror(errno), errno);
171 - exit(errno);
177 + exit(exitcode);
172 178 }
173 179 noffset = llseek(bigfd, offset, SEEK_SET);
174 180 if (noffset != offset) {
181 + exitcode = errno;
175 182 (void) printf("llseek %s (%lld/%lld) failed [%s]%d.Aborting!\n",
176 183 filename, offset, noffset, strerror(errno), errno);
177 - exit(errno);
184 + exit(exitcode);
178 185 }
179 186
180 187 if (verbose) {
181 188 (void) printf("%s: block_size = %d, write_count = %d, "
182 189 "offset = %lld, data = %s%d\n", filename, block_size,
183 190 write_count, offset,
184 191 (fillchar == 0) ? "0->" : "",
185 192 (fillchar == 0) ? DATA_RANGE : fillchar);
186 193 }
187 194
188 195 for (i = 0; i < write_count; i++) {
189 196 ssize_t n;
190 197
191 198 if ((n = write(bigfd, &bigbuffer, block_size)) == -1) {
199 + exitcode = errno;
192 200 (void) printf("write failed (%ld), good_writes = %lld, "
193 201 "error: %s[%d]\n", (long)n, good_writes,
194 202 strerror(errno),
195 203 errno);
196 - exit(errno);
204 + exit(exitcode);
197 205 }
198 206 good_writes++;
199 207 }
200 208
201 209 if (verbose) {
202 210 (void) printf("Success: good_writes = %lld (%lld)\n",
203 211 good_writes, (good_writes * block_size));
204 212 }
205 213
206 214 return (0);
207 215 }
208 216
209 217 static void
210 218 usage(void)
211 219 {
212 220 char *base = (char *)"file_write";
213 221 char *exec = (char *)getexecname();
214 222
215 223 if (exec != NULL)
216 224 exec = strdup(exec);
217 225 if (exec != NULL)
218 226 base = basename(exec);
219 227
220 228 (void) printf("Usage: %s [-v] -o {create,overwrite,append} -f file_name"
221 229 " [-b block_size]\n"
222 230 "\t[-s offset] [-c write_count] [-d data]\n"
223 231 "\twhere [data] equal to zero causes chars "
224 232 "0->%d to be repeated throughout\n", base, DATA_RANGE);
225 233
226 234 if (exec) {
227 235 free(exec);
228 236 }
229 237
230 238 exit(1);
231 239 }
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX