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>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
16 #include <rpc/types.h>
17 #include <afs/bubasics.h>
23 extern TC_ExecuteRequest();
25 /* dump information */
26 static afs_int32 transID = 1000; /* dump or restore transaction id */
27 static afs_int32 bytesDumped = 0;
29 #include "AFS_component_version_number.c"
36 register afs_int32 code;
37 register struct rx_service *tservice;
38 struct rx_securityClass *rxsc[1];
40 for (i = 1; i < argc; i++) {
42 if (*argv[i] == '-') {
45 printf("ttest takes only switches (not '%s')\n", argv[i]);
49 code = rx_Init(htons(BC_TAPEPORT));
51 printf("ttest: could not initialize rx, code %d.\n", code);
54 rxsc[0] = rxnull_NewServerSecurityObject();
56 rx_NewService(0, 1, "tape-controller", rxsc, 1, TC_ExecuteRequest);
57 rx_SetMinProcs(tservice, 3);
58 rx_SetMaxProcs(tservice, 5);
59 rx_StartServer(1); /* don't donate this process to the rpc pool; it has work to do */
61 printf("RETURNED FROM STARTSERVER!\n");
66 struct rx_call *acall;
68 printf("Got a tape labelling call.\n");
72 STC_PerformDump(acall, adumpName, atapeSet, adumpArray, aparent, alevel,
74 struct rx_call *acall;
76 afs_int32 aparent, alevel;
77 struct tc_tapeSet *atapeSet;
78 struct tc_dumpArray *adumpArray;
82 register struct tc_dumpDesc *tdescr;
83 register afs_int32 code;
84 struct sockaddr_in taddr;
85 struct budb_dumpEntry tdentry;
86 struct budb_volumeEntry tventry;
87 struct budb_tapeEntry ttentry;
90 printf("tape controller received request to start dump %s.\n", adumpName);
91 *adumpID = ++transID; /* send result back to caller */
93 memset(&tdentry, 0, sizeof(tdentry));
94 tdentry.created = time(0);
95 strcpy(tdentry.name, atapeSet->format);
96 strcat(tdentry.name, ".");
97 strcat(tdentry.name, adumpName);
98 tdentry.parent = aparent;
99 tdentry.level = alevel;
100 tdentry.incTime = 0; /* useless? */
101 tdentry.nVolumes = 1000000000; /* bogus, but not important */
102 tdentry.tapes.a = 1; /* a*x+b is tape numbering scheme */
104 tdentry.tapes.maxTapes = 1000000000; /* don't care */
105 strcpy(tdentry.tapes.format, atapeSet->format); /* base name (e.g. sys) */
106 strcat(tdentry.tapes.format, ".");
107 strcat(tdentry.tapes.format, adumpName); /* e.g. .daily */
108 strcat(tdentry.tapes.format, ".%d"); /* so we get basename.0, basename.1, etc */
109 code = bcdb_CreateDump(&tdentry);
111 printf("ttape: failed to create dump, code %d\n", code);
114 printf("created dump %d\n", tdentry.id);
116 /* start tape (preent all fits on one tape at first */
117 memset(&ttentry, 0, sizeof(ttentry));
118 sprintf(ttentry.name, tdentry.tapes.format, 1);
119 ttentry.written = time(0);
120 ttentry.dump = tdentry.id; /* dump we're in */
122 ttentry.nVolumes = 0; /* perhaps we'll adjust during dump */
123 ttentry.flags = BUDB_TAPE_BEINGWRITTEN; /* starting I/O */
124 code = bcdb_UseTape(&ttentry, &new);
126 printf("ttape: failed to start tape %s, code %d\n", ttentry.name,
131 tdescr = adumpArray->tc_dumpArray_val;
132 for (i = 0; i < adumpArray->tc_dumpArray_len; i++, tdescr++) {
133 memcpy(&taddr, tdescr->hostID, sizeof(taddr));
134 printf("dumping volid %s(%d) from host %08x since date %d\n",
135 tdescr->name, tdescr->vid, taddr.sin_addr.s_addr,
137 memset(&tventry, 0, sizeof(tventry));
138 strcpy(tventry.name, tdescr->name);
139 tventry.clone = tdescr->date;
140 tventry.seq = 0; /* frag in volume */
141 tventry.incTime = tdescr->date; /* date from which this is an incremental? */
142 tventry.id = tdescr->vid;
143 tventry.dump = tdentry.id;
144 strcpy(tventry.tape, ttentry.name);
145 tventry.position = i;
146 tventry.flags = (BUDB_VOL_LASTFRAG | BUDB_VOL_FIRSTFRAG);
147 code = bcdb_AddVolume(&tventry);
149 printf("failed to append volume entry for volume %d, code %d\n",
155 ttentry.flags = BUDB_TAPE_WRITTEN;
156 code = bcdb_FinishTape(&ttentry);
158 printf("ttape: failed to finish tape, code %d\n", code);
162 code = bcdb_FinishDump(&tdentry);
164 printf("ttest: failed to finish dump, code %d\n", code);
171 STC_PerformRestore(acall, aname, arestore, adumpID)
172 struct rx_call *acall;
174 struct tc_restoreArray *arestore;
178 register struct tc_restoreDesc *tdescr;
179 struct sockaddr_in taddr;
181 printf("tape controller received request to start restore %s.\n", aname);
182 tdescr = arestore->tc_restoreArray_val;
183 for (i = 0; i < arestore->tc_restoreArray_len; i++, tdescr++) {
184 memcpy(&taddr, tdescr->hostID, sizeof(taddr));
186 ("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",
187 tdescr->frag, tdescr->oldName, tdescr->tapeName,
188 tdescr->position, tdescr->newName, tdescr->vid,
189 taddr.sin_addr.s_addr, tdescr->partition);
191 *adumpID = ++transID;
196 /* check the status of a dump; the tape coordinator is assumed to sit on
197 the status of completed dumps for a reasonable period (2 - 12 hours)
198 so that they can be examined later */
199 STC_CheckDump(acall, adumpID, astatus)
200 struct rx_call *acall;
202 struct tc_dumpStat *astatus;
204 if (adumpID != transID)
206 astatus->dumpID = adumpID;
207 astatus->bytesDumped = (bytesDumped += 1470);
209 if (bytesDumped > 2000)
210 astatus->flags = TC_STAT_DONE;
214 STC_AbortDump(acall, adumpID)
215 struct rx_call *acall;
221 /* this call waits for a dump to complete; it ties up an LWP on the tape
228 STC_EndDump(acall, adumpID)
229 struct rx_call *acall;
236 struct rx_call *acall;