Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | #include <afsconfig.h> | |
11 | #include <afs/param.h> | |
12 | ||
13 | #include <afs/procmgmt.h> | |
14 | #include <roken.h> | |
15 | ||
16 | #include <afs/cmd.h> | |
17 | #include <afs/usd.h> | |
18 | ||
19 | /* structure for writing data to tape */ | |
20 | typedef struct tapeDataBuffer { | |
21 | struct tapeDataBuffer *tdb_next; | |
22 | char *tdb_buffer; | |
23 | } tapeDataBufferT; | |
24 | typedef tapeDataBufferT *tapeDataBufferP; | |
25 | ||
26 | /* globals */ | |
27 | char *tapeDevice = 0; /* device pathname */ | |
28 | afs_int32 eotEnabled = 1; | |
29 | ||
30 | /* prototypes */ | |
31 | int fileMark(usd_handle_t hTape); | |
32 | int fileMarkSize(char *tapeDevice); | |
33 | static int tt_fileMarkSize(struct cmd_syndesc *as, void *arock); | |
34 | afs_int32 rewindTape(usd_handle_t hTape); | |
35 | int dataBlock(usd_handle_t, afs_int32); | |
36 | ||
37 | #define ERROR(evalue) do { \ | |
38 | code = evalue; \ | |
39 | goto error_exit; \ | |
40 | } while (0) | |
41 | ||
42 | #define MAXV 100 | |
43 | ||
44 | #ifndef AFS_NT40_ENV | |
45 | #include "AFS_component_version_number.c" | |
46 | #endif | |
47 | ||
48 | void quitFms(int); | |
49 | ||
50 | int | |
51 | main(int argc, char **argv) | |
52 | { | |
53 | struct sigaction intaction, oldaction; | |
54 | struct cmd_syndesc *cptr; | |
55 | ||
56 | memset(&intaction, 0, sizeof(intaction)); | |
57 | intaction.sa_handler = quitFms; | |
58 | ||
59 | sigaction(SIGINT, &intaction, &oldaction); | |
60 | ||
61 | cptr = | |
62 | cmd_CreateSyntax(NULL, tt_fileMarkSize, NULL, 0, | |
63 | "write a tape full of file marks"); | |
64 | cmd_AddParm(cptr, "-tape", CMD_SINGLE, CMD_REQUIRED, "tape special file"); | |
65 | ||
66 | cmd_Dispatch(argc, argv); | |
67 | return 0; | |
68 | } | |
69 | ||
70 | static int | |
71 | tt_fileMarkSize(struct cmd_syndesc *as, void *arock) | |
72 | { | |
73 | char *tapeDevice; | |
74 | ||
75 | tapeDevice = as->parms[0].items->data; | |
76 | ||
77 | fileMarkSize(tapeDevice); | |
78 | ||
79 | return 0; | |
80 | } | |
81 | ||
82 | ||
83 | int | |
84 | fileMarkSize(char *tapeDevice) | |
85 | { | |
86 | afs_uint32 nFileMarks, nBlocks, nbfTape; | |
87 | double tpSize, fmSize; | |
88 | afs_uint32 bufferSize = 16384; | |
89 | usd_handle_t hTape; | |
90 | FILE *logFile; | |
91 | int count = 0; | |
92 | afs_uint32 countr; | |
93 | afs_int32 code = 0; | |
94 | ||
95 | code = | |
96 | usd_Open(tapeDevice, (USD_OPEN_RDWR | USD_OPEN_WLOCK), 0777, &hTape); | |
97 | if (code) { | |
98 | printf("Can't open tape device %s\n", tapeDevice); | |
99 | fflush(stdout); | |
100 | exit(1); | |
101 | } | |
102 | ||
103 | logFile = fopen("fms.log", "w+"); | |
104 | if (logFile == NULL) { | |
105 | printf("Can't open log file\n"); | |
106 | fflush(stdout); | |
107 | exit(1); | |
108 | } | |
109 | fprintf(logFile, "fms test started\n"); | |
110 | fflush(logFile); | |
111 | ||
112 | code = rewindTape(hTape); | |
113 | if (code) { | |
114 | fprintf(logFile, "Can't rewind tape\n"); | |
115 | fflush(logFile); | |
116 | ERROR(code); | |
117 | } | |
118 | ||
119 | /* measure capacity of tape */ | |
120 | nbfTape = 0; | |
121 | countr = 0; | |
122 | while (1) { | |
123 | code = dataBlock(hTape, bufferSize); | |
124 | nbfTape++; | |
125 | count++; | |
126 | countr++; | |
127 | if (code) | |
128 | break; | |
129 | ||
130 | if (count >= 5) { | |
131 | count = 0; | |
132 | printf("\rwrote block: %d", nbfTape); | |
133 | } | |
134 | ||
135 | } | |
136 | ||
137 | fprintf(logFile, "wrote %d blocks\n", nbfTape); | |
138 | fflush(logFile); | |
139 | printf("\rwrote %d blocks\n", nbfTape); | |
140 | printf("Finished data capacity test - rewinding\n"); | |
141 | /* reset the tape device */ | |
142 | code = USD_CLOSE(hTape); | |
143 | if (code) { | |
144 | fprintf(logFile, "Can't close tape device at end of pass 1\n"); | |
145 | fflush(logFile); | |
146 | printf("Can't close tape device %s\n", tapeDevice); | |
147 | goto error_exit; | |
148 | } | |
149 | code = | |
150 | usd_Open(tapeDevice, (USD_OPEN_RDWR | USD_OPEN_WLOCK), 0777, &hTape); | |
151 | if (code) { | |
152 | fprintf(logFile, "Can't open tape device for pass 2\n"); | |
153 | fflush(logFile); | |
154 | printf("Can't open tape device %s\n", tapeDevice); | |
155 | goto error_exit; | |
156 | } | |
157 | ||
158 | code = rewindTape(hTape); | |
159 | if (code) { | |
160 | fprintf(logFile, "Can't rewind tape\n"); | |
161 | fflush(logFile); | |
162 | ERROR(code); | |
163 | } | |
164 | ||
165 | /* now measure file mark size */ | |
166 | nFileMarks = 0; | |
167 | nBlocks = 0; | |
168 | count = 0; | |
169 | countr = 0; | |
170 | while (1) { | |
171 | code = dataBlock(hTape, bufferSize); | |
172 | nBlocks++; | |
173 | if (code) | |
174 | break; | |
175 | code = fileMark(hTape); | |
176 | nFileMarks++; | |
177 | if (code) | |
178 | break; | |
179 | count++; | |
180 | countr++; | |
181 | ||
182 | if (count >= 2) { | |
183 | count = 0; | |
184 | printf("\rwrote %d blocks, %d filemarks", nBlocks, nFileMarks); | |
185 | } | |
186 | ||
187 | } | |
188 | printf("\nFinished filemark test\n"); | |
189 | tpSize = (double)nbfTape *(double)bufferSize; | |
190 | fmSize = | |
191 | (((double)nbfTape - | |
192 | (double)nBlocks) * (double)bufferSize) / (double)nFileMarks; | |
193 | printf("Tape capacity is %.0f bytes\n", tpSize); | |
194 | printf("File marks are %.0f bytes\n", fmSize); | |
195 | fprintf(logFile, "Tape capacity is %.0f bytes\n", tpSize); | |
196 | fprintf(logFile, "File marks are %.0f bytes\n", fmSize); | |
197 | fflush(logFile); | |
198 | fclose(logFile); | |
199 | error_exit: | |
200 | USD_CLOSE(hTape); | |
201 | return (code); | |
202 | } | |
203 | ||
204 | void | |
205 | quitFms(int sig) | |
206 | { | |
207 | exit(0); | |
208 | } | |
209 | ||
210 | ||
211 | /* -------------------------- | |
212 | * device handling routines | |
213 | * -------------------------- | |
214 | */ | |
215 | ||
216 | /* rewindTape() - rewinds tape to beginning */ | |
217 | afs_int32 | |
218 | rewindTape(usd_handle_t hTape) | |
219 | { | |
220 | usd_tapeop_t tapeop; | |
221 | int rcode; | |
222 | ||
223 | tapeop.tp_op = USDTAPE_REW; | |
224 | tapeop.tp_count = 1; | |
225 | rcode = USD_IOCTL(hTape, USD_IOCTL_TAPEOPERATION, (void *)&tapeop); | |
226 | return rcode; | |
227 | } | |
228 | ||
229 | /* write an EOF marker */ | |
230 | int | |
231 | fileMark(usd_handle_t hTape) | |
232 | { | |
233 | usd_tapeop_t tapeop; | |
234 | int rcode; | |
235 | ||
236 | tapeop.tp_op = USDTAPE_WEOF; | |
237 | tapeop.tp_count = 1; | |
238 | rcode = USD_IOCTL(hTape, USD_IOCTL_TAPEOPERATION, (void *)&tapeop); | |
239 | return rcode; | |
240 | } | |
241 | ||
242 | /* dataBlock | |
243 | * write a block of data on tape | |
244 | * entry: | |
245 | * blocksize - size of block in bytes | |
246 | */ | |
247 | int | |
248 | dataBlock(usd_handle_t hTape, afs_int32 reqSize) | |
249 | { | |
250 | static char *dB_buffer = 0; | |
251 | static afs_int32 dB_buffersize = 0; | |
252 | static int dB_count = 0; | |
253 | int *ptr; | |
254 | afs_int32 code = 0; | |
255 | afs_uint32 xferd; | |
256 | ||
257 | /* dbBuffersize is only valid when dB_buffer is non-zero */ | |
258 | ||
259 | if ((dB_buffer != 0) | |
260 | && (dB_buffersize != reqSize) | |
261 | ) { | |
262 | free(dB_buffer); | |
263 | dB_buffer = 0; | |
264 | } | |
265 | ||
266 | if (dB_buffer == 0) { | |
267 | dB_buffer = calloc(1, reqSize); | |
268 | if (dB_buffer == 0) | |
269 | ERROR(-1); | |
270 | dB_buffersize = reqSize; | |
271 | } | |
272 | ||
273 | ptr = (int *)dB_buffer; | |
274 | *ptr = dB_count++; | |
275 | ||
276 | code = USD_WRITE(hTape, dB_buffer, dB_buffersize, &xferd); | |
277 | if (code || xferd != dB_buffersize) | |
278 | ERROR(-1); | |
279 | ||
280 | error_exit: | |
281 | return (code); | |
282 | } |