Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / bu_utils / fms.c
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 }