2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
18 #include <afs/afsutil.h>
20 #include <afs/com_err.h>
23 #include "error_macros.h"
25 int isafile = 0, debugLevel = 1;
27 /* Format of the config file is now
28 * <capacity devicename portno isafile>
29 * capacity - size of tape or file in bytes
30 * devicename - tape device or file name to write data into
31 * portno - tape coordinator port no. (irrelevant)
32 * isafile - Is this entry a file or a tape?
34 * test_ftm goes through the lines in the config file and selects the
35 * entry that has a port no. of 0 and tries to open the device.
38 static char *whoami = "test_TM";
41 typedef struct TestInfo {
42 char *tapeName; /* tape name */
43 struct tapeConfig *tc_Infop; /* tape config info (size, devname etc..) */
44 int nFiles; /* no. of files to be dumped */
45 char **files; /* names of files to be dumped */
46 char dumpDone; /* event that signals the completion of
47 * the dump test thread.
49 int appended; /* do an appended test? */
53 char mark[sizeof(struct blockMark)];
54 char data[BUTM_BLKSIZE];
57 struct tapeConfig confInfo;
59 int PerformDumpTest(TestInfo * tip);
62 GetDeviceInfo(filename, config)
64 struct tapeConfig *config;
69 afs_int32 aport, capacity, notfound;
73 devFile = fopen(filename, "r");
75 fprintf(stderr, "failed to open %s\n", filename);
80 if (fgets(line, 100, devFile) == NULL)
82 sscanf(line, "%u %s %u %u\n", &capacity, devName, &aport, &isafile);
83 if (aport == portOffset) {
84 config->capacity = capacity;
85 config->portOffset = aport;
86 strncpy(config->device, devName, 100);
96 #include "AFS_component_version_number.c"
103 char *tape = "testtape.0", *parent_pid, *pid;
110 initialize_BUTM_error_table();
114 files = (char **)malloc(argc * sizeof(char *));
116 for (i = 1; i < argc; i++) {
117 if (argv[i][0] == '-') {
118 if (strncmp(argv[i], "-configuration", strlen(argv[i])) == 0)
120 else if (strncmp(argv[i], "-tapename", strlen(argv[i])) == 0)
123 afs_com_err(whoami, 0, "unexpected command argument: '%s'",
129 if (stat(argv[i], &buf)) {
130 afs_com_err(whoami, errno, "can't stat filename parameter %s\n",
133 if ((buf.st_mode & S_IFREG) && (buf.st_mode & 0444))
134 files[nFiles++] = argv[i];
136 printf("skipping non-file '%s'\n", argv[i]);
143 if ((strlen(tape) == 0) || (strlen(tape) >= BU_MAXTAPELEN)) {
144 afs_com_err(whoami, 0, "bogus tape name");
147 code = GetDeviceInfo(config, &confInfo);
149 afs_com_err(whoami, 0, "cant find tape config info");
154 ti.tc_Infop = &confInfo;
158 printf("%s: Beginning Dump Tests\n", whoami);
159 code = LWP_InitializeProcessSupport(1, &parent_pid);
161 afs_com_err(whoami, code, "Can't init LWP lib");
164 code = IOMGR_Initialize();
166 afs_com_err(whoami, code, "Can't init LWP IOMGR lib");
169 /* Perform normal test */
171 LWP_CreateProcess(PerformDumpTest, 100000, 0, (void *)&ti,
172 "BUTM Tester", &pid);
174 afs_com_err(whoami, code, "libbutm.a: Normal Tests failed!. :-( ");
177 LWP_WaitProcess(&ti.dumpDone);
178 LWP_DestroyProcess(pid);
180 /* Perform Appended Test, on tapes */
184 LWP_CreateProcess(PerformDumpTest, 100000, 0, (void *)&ti,
185 "BUTM Tester", &pid);
187 afs_com_err(whoami, code, "libbutm.a: Appended Tests failed!. :-( ");
191 LWP_WaitProcess(&ti.dumpDone);
192 LWP_DestroyProcess(pid);
196 LWP_TerminateProcessSupport();
202 ("usage is: %s [-configuration <config file>] [-tapename <name>] <file>*\n",
209 PerformDumpTest(TestInfo * tip)
210 { /* Dump Files into target tape/file */
211 struct butm_tapeInfo info;
212 struct butm_tapeLabel label;
216 bufferBlock = (struct BufferBlock *)malloc(sizeof(struct BufferBlock));
218 info.structVersion = BUTM_MAJORVERSION;
219 if (code = butm_file_Instantiate(&info, tip->tc_Infop)) {
220 afs_com_err(whoami, code, "instantiating file tape");
224 memset(&label, 0, sizeof(label));
225 gettimeofday(&tp, 0);
226 label.structVersion = CUR_TAPE_VERSION;
227 label.creationTime = tp.tv_sec;
228 label.size = info.tapeSize;
230 #define T_NAME "AFS 3.5"
232 #define T_CELL "cellname"
233 #define T_REALM "cellname"
234 #define T_COMMENT "Testing the butm library.."
235 strcpy(label.AFSName, tip->tapeName);
236 strcpy(label.creator.name, T_NAME);
237 strcpy(label.creator.instance, T_INST);
238 strcpy(label.creator.cell, T_CELL);
239 strcpy(label.cell, T_REALM);
240 strcpy(label.comment, T_COMMENT);
242 if (code = butm_Mount(&info, tip->tapeName)) {
243 afs_com_err(whoami, code, "setting up tape");
246 if (tip->appended) { /* This is to be an appended dump */
247 code = butm_SeekEODump(&info, tip->nFiles + 1);
249 afs_com_err(whoami, code,
250 "Can't append: Can't position to end of dump on tape\n");
254 if ((code = butm_Create(&info, &label, !tip->appended /*Rewind */ ))) {
255 afs_com_err(whoami, code, "Writing tape label");
260 for (i = 0; i < tip->nFiles; i++) {
262 int fid = open(tip->files[i], O_RDONLY, 0);
264 afs_com_err(whoami, errno, "opening file to write on tape");
267 if (code = butm_WriteFileBegin(&info)) {
268 afs_com_err(whoami, code, "beginning butm write file");
271 while ((len = read(fid, bufferBlock->data, BUTM_BLKSIZE)) > 0) {
272 if (code = butm_WriteFileData(&info, bufferBlock->data, 1, len)) {
273 afs_com_err(whoami, code, "butm writing file data");
278 afs_com_err(whoami, errno, "reading file data");
281 if (code = butm_WriteFileEnd(&info)) {
282 afs_com_err(whoami, code, "ending butm write file");
285 if (close(fid) < 0) {
286 afs_com_err(whoami, errno, "closing file");
290 if ((code = butm_WriteEOT(&info)) || (code = butm_Dismount(&info))) {
291 afs_com_err(whoami, code, "finishing up tape");
295 /* now read the tape back in and make sure everything is OK */
297 label.structVersion = BUTM_MAJORVERSION;
298 if (code = butm_Mount(&info, tip->tapeName)) {
299 afs_com_err(whoami, code, "setting up tape");
302 if (tip->appended) { /* This is to be an appended dump */
303 code = butm_SeekEODump(&info, tip->nFiles + 1);
305 afs_com_err(whoami, code,
306 "Can't append: Can't position to end of dump on tape\n");
310 if (code = butm_ReadLabel(&info, &label, !tip->appended /*rewind */ )) {
311 afs_com_err(whoami, code, "reading tape label");
314 past = time(0) - label.creationTime;
315 if ((past < 0) || (past > 5 * 60)) {
316 time_t t = label.creationTime;
317 printf("label creation time is long ago: %s\n", ctime(&t));
320 if (strcmp(label.AFSName, tip->tapeName) != 0) {
321 printf("label tape name is bogus: %s, should be %s\n", label.AFSName,
325 if ((strcmp(label.creator.name, T_NAME) != 0)
326 || (strcmp(label.creator.instance, T_INST) != 0)
327 || (strcmp(label.creator.cell, T_CELL) != 0)
328 || (strcmp(label.cell, T_REALM) != 0)
329 || (strcmp(label.comment, T_COMMENT) != 0)) {
330 printf("label strings are bad: creator %s.%s@%s from realm %s (%s)\n",
331 label.creator.name, label.creator.instance, label.creator.cell,
332 label.cell, label.comment);
335 for (i = 0; i < sizeof(label.spare); i++)
336 if (*(char *)label.spare) {
337 printf("Label's spare fields not zero\n");
341 for (i = 0; i < tip->nFiles; i++) {
342 char *tbuffer = bufferBlock->data;
344 char fbuffer[BUTM_BLKSIZE];
346 int tprogress, fprogress;
349 fid = open(tip->files[i], O_RDONLY, 0);
351 afs_com_err(whoami, errno, "Opening %dth file to compare with tape",
355 if (code = butm_ReadFileBegin(&info)) {
356 afs_com_err(whoami, code, "Beginning butm %dth read file", i + 1);
360 tprogress = tlen = fprogress = flen = 0;
362 memset(tbuffer, 0, BUTM_BLKSIZE);
363 code = butm_ReadFileData(&info, tbuffer, BUTM_BLKSIZE, &tlen);
365 if (code && code != BUTM_STATUS_EOF) {
366 afs_com_err(whoami, code, "Reading %dth tape data", i + 1);
369 memset(fbuffer, 0, BUTM_BLKSIZE);
370 flen = read(fid, fbuffer, sizeof(fbuffer));
372 afs_com_err(whoami, errno, "Reading %dth file data", i + 1);
375 if (code == BUTM_STATUS_EOF)
377 if ((tlen == 0) && (flen == 0))
378 break; /* correct termination */
380 printf("File length mismatch for %dth file (%s)\n", i,
384 if (tbuffer[tprogress++] != fbuffer[fprogress++]) {
385 printf("Data mismatch for %dth file (%s)\n", i + 1,
389 if (tlen < BUTM_BLKSIZE)
393 if (code = butm_ReadFileEnd(&info)) {
394 afs_com_err(whoami, code, "Ending butm %dth read file", i + 1);
397 if (close(fid) < 0) {
398 afs_com_err(whoami, errno, "Closing %dth file", i + 1);
403 if ((info.status & BUTM_STATUS_EOD) == 0) {
404 code = butm_ReadFileBegin(&info);
405 if (code && (code != BUTM_EOD)) {
406 afs_com_err(whoami, code, "Should have encountered an 'End Of Tape'");
410 if (code = butm_Dismount(&info)) {
411 afs_com_err(whoami, code, "Finishing up tape");
416 printf("%d files Appended: All OK\n", tip->nFiles);
418 printf("%d files written: All OK\n", tip->nFiles);
421 LWP_SignalProcess(&tip->dumpDone);