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 <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
17 #include <rpc/types.h>
18 #include <afs/bubasics.h>
24 extern TC_ExecuteRequest();
26 /* dump information */
27 static afs_int32 transID = 1000; /* dump or restore transaction id */
28 static afs_int32 bytesDumped = 0;
30 #include "AFS_component_version_number.c"
37 register afs_int32 code;
38 register struct rx_service *tservice;
39 struct rx_securityClass *rxsc[1];
41 for (i = 1; i < argc; i++) {
43 if (*argv[i] == '-') {
46 printf("ttest takes only switches (not '%s')\n", argv[i]);
50 code = rx_Init(htons(BC_TAPEPORT));
52 printf("ttest: could not initialize rx, code %d.\n", code);
55 rxsc[0] = rxnull_NewServerSecurityObject();
57 rx_NewService(0, 1, "tape-controller", rxsc, 1, TC_ExecuteRequest);
58 rx_SetMinProcs(tservice, 3);
59 rx_SetMaxProcs(tservice, 5);
60 rx_StartServer(1); /* don't donate this process to the rpc pool; it has work to do */
62 printf("RETURNED FROM STARTSERVER!\n");
67 struct rx_call *acall;
69 printf("Got a tape labelling call.\n");
73 STC_PerformDump(acall, adumpName, atapeSet, adumpArray, aparent, alevel,
75 struct rx_call *acall;
77 afs_int32 aparent, alevel;
78 struct tc_tapeSet *atapeSet;
79 struct tc_dumpArray *adumpArray;
83 register struct tc_dumpDesc *tdescr;
84 register afs_int32 code;
85 struct sockaddr_in taddr;
86 struct budb_dumpEntry tdentry;
87 struct budb_volumeEntry tventry;
88 struct budb_tapeEntry ttentry;
91 printf("tape controller received request to start dump %s.\n", adumpName);
92 *adumpID = ++transID; /* send result back to caller */
94 memset(&tdentry, 0, sizeof(tdentry));
95 tdentry.created = time(0);
96 strcpy(tdentry.name, atapeSet->format);
97 strcat(tdentry.name, ".");
98 strcat(tdentry.name, adumpName);
99 tdentry.parent = aparent;
100 tdentry.level = alevel;
101 tdentry.incTime = 0; /* useless? */
102 tdentry.nVolumes = 1000000000; /* bogus, but not important */
103 tdentry.tapes.a = 1; /* a*x+b is tape numbering scheme */
105 tdentry.tapes.maxTapes = 1000000000; /* don't care */
106 strcpy(tdentry.tapes.format, atapeSet->format); /* base name (e.g. sys) */
107 strcat(tdentry.tapes.format, ".");
108 strcat(tdentry.tapes.format, adumpName); /* e.g. .daily */
109 strcat(tdentry.tapes.format, ".%d"); /* so we get basename.0, basename.1, etc */
110 code = bcdb_CreateDump(&tdentry);
112 printf("ttape: failed to create dump, code %d\n", code);
115 printf("created dump %d\n", tdentry.id);
117 /* start tape (preent all fits on one tape at first */
118 memset(&ttentry, 0, sizeof(ttentry));
119 sprintf(ttentry.name, tdentry.tapes.format, 1);
120 ttentry.written = time(0);
121 ttentry.dump = tdentry.id; /* dump we're in */
123 ttentry.nVolumes = 0; /* perhaps we'll adjust during dump */
124 ttentry.flags = BUDB_TAPE_BEINGWRITTEN; /* starting I/O */
125 code = bcdb_UseTape(&ttentry, &new);
127 printf("ttape: failed to start tape %s, code %d\n", ttentry.name,
132 tdescr = adumpArray->tc_dumpArray_val;
133 for (i = 0; i < adumpArray->tc_dumpArray_len; i++, tdescr++) {
134 memcpy(&taddr, tdescr->hostID, sizeof(taddr));
135 printf("dumping volid %s(%d) from host %08x since date %d\n",
136 tdescr->name, tdescr->vid, taddr.sin_addr.s_addr,
138 memset(&tventry, 0, sizeof(tventry));
139 strcpy(tventry.name, tdescr->name);
140 tventry.clone = tdescr->date;
141 tventry.seq = 0; /* frag in volume */
142 tventry.incTime = tdescr->date; /* date from which this is an incremental? */
143 tventry.id = tdescr->vid;
144 tventry.dump = tdentry.id;
145 strcpy(tventry.tape, ttentry.name);
146 tventry.position = i;
147 tventry.flags = (BUDB_VOL_LASTFRAG | BUDB_VOL_FIRSTFRAG);
148 code = bcdb_AddVolume(&tventry);
150 printf("failed to append volume entry for volume %d, code %d\n",
156 ttentry.flags = BUDB_TAPE_WRITTEN;
157 code = bcdb_FinishTape(&ttentry);
159 printf("ttape: failed to finish tape, code %d\n", code);
163 code = bcdb_FinishDump(&tdentry);
165 printf("ttest: failed to finish dump, code %d\n", code);
172 STC_PerformRestore(acall, aname, arestore, adumpID)
173 struct rx_call *acall;
175 struct tc_restoreArray *arestore;
179 register struct tc_restoreDesc *tdescr;
180 struct sockaddr_in taddr;
182 printf("tape controller received request to start restore %s.\n", aname);
183 tdescr = arestore->tc_restoreArray_val;
184 for (i = 0; i < arestore->tc_restoreArray_len; i++, tdescr++) {
185 memcpy(&taddr, tdescr->hostID, sizeof(taddr));
187 ("restoring frag %d of volume %s from tape %s at position %d.\n New name is '%s', new vid is %d, new host is %08x, new partition is %d\n",
188 tdescr->frag, tdescr->oldName, tdescr->tapeName,
189 tdescr->position, tdescr->newName, tdescr->vid,
190 taddr.sin_addr.s_addr, tdescr->partition);
192 *adumpID = ++transID;
197 /* check the status of a dump; the tape coordinator is assumed to sit on
198 the status of completed dumps for a reasonable period (2 - 12 hours)
199 so that they can be examined later */
200 STC_CheckDump(acall, adumpID, astatus)
201 struct rx_call *acall;
203 struct tc_dumpStat *astatus;
205 if (adumpID != transID)
207 astatus->dumpID = adumpID;
208 astatus->bytesDumped = (bytesDumped += 1470);
210 if (bytesDumped > 2000)
211 astatus->flags = TC_STAT_DONE;
215 STC_AbortDump(acall, adumpID)
216 struct rx_call *acall;
222 /* this call waits for a dump to complete; it ties up an LWP on the tape
229 STC_EndDump(acall, adumpID)
230 struct rx_call *acall;
237 struct rx_call *acall;