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