Commit | Line | Data |
---|---|---|
805e021f CE |
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 <roken.h> | |
14 | ||
15 | #include <lwp.h> | |
16 | #include <rx/rx.h> | |
17 | #include <afs/bubasics.h> | |
18 | #include <afs/butc.h> | |
19 | #include <afs/budb.h> | |
20 | ||
21 | #include "bc.h" | |
22 | ||
23 | /* dump information */ | |
24 | static afs_int32 transID = 1000; /* dump or restore transaction id */ | |
25 | static afs_int32 bytesDumped = 0; | |
26 | ||
27 | #include "AFS_component_version_number.c" | |
28 | ||
29 | main(argc, argv) | |
30 | int argc; | |
31 | char **argv; | |
32 | { | |
33 | int i; | |
34 | afs_int32 code; | |
35 | struct rx_service *tservice; | |
36 | struct rx_securityClass *rxsc[1]; | |
37 | ||
38 | for (i = 1; i < argc; i++) { | |
39 | /* parse args */ | |
40 | if (*argv[i] == '-') { | |
41 | /* switch */ | |
42 | } else { | |
43 | printf("ttest takes only switches (not '%s')\n", argv[i]); | |
44 | exit(1); | |
45 | } | |
46 | } | |
47 | code = rx_Init(htons(BC_TAPEPORT)); | |
48 | if (code) { | |
49 | printf("ttest: could not initialize rx, code %d.\n", code); | |
50 | exit(1); | |
51 | } | |
52 | rxsc[0] = rxnull_NewServerSecurityObject(); | |
53 | tservice = | |
54 | rx_NewService(0, 1, "tape-controller", rxsc, 1, TC_ExecuteRequest); | |
55 | rx_SetMinProcs(tservice, 3); | |
56 | rx_SetMaxProcs(tservice, 5); | |
57 | rx_StartServer(1); /* don't donate this process to the rpc pool; it has work to do */ | |
58 | /* never returns */ | |
59 | printf("RETURNED FROM STARTSERVER!\n"); | |
60 | exit(1); | |
61 | } | |
62 | ||
63 | STC_LabelTape(acall) | |
64 | struct rx_call *acall; | |
65 | { | |
66 | printf("Got a tape labelling call.\n"); | |
67 | return 0; | |
68 | } | |
69 | ||
70 | STC_PerformDump(acall, adumpName, atapeSet, adumpArray, aparent, alevel, | |
71 | adumpID) | |
72 | struct rx_call *acall; | |
73 | char *adumpName; | |
74 | afs_int32 aparent, alevel; | |
75 | struct tc_tapeSet *atapeSet; | |
76 | struct tc_dumpArray *adumpArray; | |
77 | afs_int32 *adumpID; | |
78 | { | |
79 | int i; | |
80 | struct tc_dumpDesc *tdescr; | |
81 | afs_int32 code; | |
82 | struct sockaddr_in taddr; | |
83 | struct budb_dumpEntry tdentry; | |
84 | struct budb_volumeEntry tventry; | |
85 | struct budb_tapeEntry ttentry; | |
86 | afs_int32 new; | |
87 | ||
88 | printf("tape controller received request to start dump %s.\n", adumpName); | |
89 | *adumpID = ++transID; /* send result back to caller */ | |
90 | ||
91 | memset(&tdentry, 0, sizeof(tdentry)); | |
92 | tdentry.created = time(0); | |
93 | strcpy(tdentry.name, atapeSet->format); | |
94 | strcat(tdentry.name, "."); | |
95 | strcat(tdentry.name, adumpName); | |
96 | tdentry.parent = aparent; | |
97 | tdentry.level = alevel; | |
98 | tdentry.incTime = 0; /* useless? */ | |
99 | tdentry.nVolumes = 1000000000; /* bogus, but not important */ | |
100 | tdentry.tapes.a = 1; /* a*x+b is tape numbering scheme */ | |
101 | tdentry.tapes.b = 0; | |
102 | tdentry.tapes.maxTapes = 1000000000; /* don't care */ | |
103 | strcpy(tdentry.tapes.format, atapeSet->format); /* base name (e.g. sys) */ | |
104 | strcat(tdentry.tapes.format, "."); | |
105 | strcat(tdentry.tapes.format, adumpName); /* e.g. .daily */ | |
106 | strcat(tdentry.tapes.format, ".%d"); /* so we get basename.0, basename.1, etc */ | |
107 | code = bcdb_CreateDump(&tdentry); | |
108 | if (code) { | |
109 | printf("ttape: failed to create dump, code %d\n", code); | |
110 | return code; | |
111 | } | |
112 | printf("created dump %d\n", tdentry.id); | |
113 | ||
114 | /* start tape (preent all fits on one tape at first */ | |
115 | memset(&ttentry, 0, sizeof(ttentry)); | |
116 | sprintf(ttentry.name, tdentry.tapes.format, 1); | |
117 | ttentry.written = time(0); | |
118 | ttentry.dump = tdentry.id; /* dump we're in */ | |
119 | ttentry.seq = 0; | |
120 | ttentry.nVolumes = 0; /* perhaps we'll adjust during dump */ | |
121 | ttentry.flags = BUDB_TAPE_BEINGWRITTEN; /* starting I/O */ | |
122 | code = bcdb_UseTape(&ttentry, &new); | |
123 | if (code) { | |
124 | printf("ttape: failed to start tape %s, code %d\n", ttentry.name, | |
125 | code); | |
126 | return code; | |
127 | } | |
128 | ||
129 | tdescr = adumpArray->tc_dumpArray_val; | |
130 | for (i = 0; i < adumpArray->tc_dumpArray_len; i++, tdescr++) { | |
131 | memcpy(&taddr, tdescr->hostID, sizeof(taddr)); | |
132 | printf("dumping volid %s(%d) from host %08x since date %d\n", | |
133 | tdescr->name, tdescr->vid, taddr.sin_addr.s_addr, | |
134 | tdescr->date); | |
135 | memset(&tventry, 0, sizeof(tventry)); | |
136 | strcpy(tventry.name, tdescr->name); | |
137 | tventry.clone = tdescr->date; | |
138 | tventry.seq = 0; /* frag in volume */ | |
139 | tventry.incTime = tdescr->date; /* date from which this is an incremental? */ | |
140 | tventry.id = tdescr->vid; | |
141 | tventry.dump = tdentry.id; | |
142 | strcpy(tventry.tape, ttentry.name); | |
143 | tventry.position = i; | |
144 | tventry.flags = (BUDB_VOL_LASTFRAG | BUDB_VOL_FIRSTFRAG); | |
145 | code = bcdb_AddVolume(&tventry); | |
146 | if (code) { | |
147 | printf("failed to append volume entry for volume %d, code %d\n", | |
148 | tdescr->vid, code); | |
149 | return code; | |
150 | } | |
151 | } | |
152 | ||
153 | ttentry.flags = BUDB_TAPE_WRITTEN; | |
154 | code = bcdb_FinishTape(&ttentry); | |
155 | if (code) { | |
156 | printf("ttape: failed to finish tape, code %d\n", code); | |
157 | return code; | |
158 | } | |
159 | ||
160 | code = bcdb_FinishDump(&tdentry); | |
161 | if (code) { | |
162 | printf("ttest: failed to finish dump, code %d\n", code); | |
163 | return code; | |
164 | } | |
165 | bytesDumped = 0; | |
166 | return 0; | |
167 | } | |
168 | ||
169 | STC_PerformRestore(acall, aname, arestore, adumpID) | |
170 | struct rx_call *acall; | |
171 | char *aname; | |
172 | struct tc_restoreArray *arestore; | |
173 | afs_int32 *adumpID; | |
174 | { | |
175 | int i; | |
176 | struct tc_restoreDesc *tdescr; | |
177 | struct sockaddr_in taddr; | |
178 | ||
179 | printf("tape controller received request to start restore %s.\n", aname); | |
180 | tdescr = arestore->tc_restoreArray_val; | |
181 | for (i = 0; i < arestore->tc_restoreArray_len; i++, tdescr++) { | |
182 | memcpy(&taddr, tdescr->hostID, sizeof(taddr)); | |
183 | printf | |
184 | ("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", | |
185 | tdescr->frag, tdescr->oldName, tdescr->tapeName, | |
186 | tdescr->position, tdescr->newName, tdescr->vid, | |
187 | taddr.sin_addr.s_addr, tdescr->partition); | |
188 | } | |
189 | *adumpID = ++transID; | |
190 | bytesDumped = 0; | |
191 | return 0; | |
192 | } | |
193 | ||
194 | /* check the status of a dump; the tape coordinator is assumed to sit on | |
195 | the status of completed dumps for a reasonable period (2 - 12 hours) | |
196 | so that they can be examined later */ | |
197 | STC_CheckDump(acall, adumpID, astatus) | |
198 | struct rx_call *acall; | |
199 | afs_int32 adumpID; | |
200 | struct tc_dumpStat *astatus; | |
201 | { | |
202 | if (adumpID != transID) | |
203 | return 2; | |
204 | astatus->dumpID = adumpID; | |
205 | astatus->bytesDumped = (bytesDumped += 1470); | |
206 | astatus->flags = 0; | |
207 | if (bytesDumped > 2000) | |
208 | astatus->flags = TC_STAT_DONE; | |
209 | return 0; | |
210 | } | |
211 | ||
212 | STC_AbortDump(acall, adumpID) | |
213 | struct rx_call *acall; | |
214 | afs_int32 adumpID; | |
215 | { | |
216 | return 0; | |
217 | } | |
218 | ||
219 | /* this call waits for a dump to complete; it ties up an LWP on the tape | |
220 | coordinator */ | |
221 | STC_WaitForDump() | |
222 | { | |
223 | return 1; | |
224 | } | |
225 | ||
226 | STC_EndDump(acall, adumpID) | |
227 | struct rx_call *acall; | |
228 | afs_int32 adumpID; | |
229 | { | |
230 | return 0; | |
231 | } | |
232 | ||
233 | STC_GetTMInfo(acall) | |
234 | struct rx_call *acall; | |
235 | { | |
236 | return 0; | |
237 | } |