21f1d0f7fb9011a1f3239dc99bab9f230253500a
[openafs.git] / src / bucoord / ttest.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 <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <netdb.h>
14 #include <lwp.h>
15 #include <rx/rx.h>
16 #include <rpc/types.h>
17 #include <afs/bubasics.h>
18 #include <afs/butc.h>
19 #include <afs/budb.h>
20
21 #include "bc.h"
22
23 extern TC_ExecuteRequest();
24
25 /* dump information */
26 static afs_int32 transID = 1000;        /* dump or restore transaction id */
27 static afs_int32 bytesDumped = 0;
28
29 #include "AFS_component_version_number.c"
30
31 main(argc, argv)
32      int argc;
33      char **argv;
34 {
35     register int i;
36     register afs_int32 code;
37     register struct rx_service *tservice;
38     struct rx_securityClass *rxsc[1];
39
40     for (i = 1; i < argc; i++) {
41         /* parse args */
42         if (*argv[i] == '-') {
43             /* switch */
44         } else {
45             printf("ttest takes only switches (not '%s')\n", argv[i]);
46             exit(1);
47         }
48     }
49     code = rx_Init(htons(BC_TAPEPORT));
50     if (code) {
51         printf("ttest: could not initialize rx, code %d.\n", code);
52         exit(1);
53     }
54     rxsc[0] = rxnull_NewServerSecurityObject();
55     tservice =
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 */
60     /* never returns */
61     printf("RETURNED FROM STARTSERVER!\n");
62     exit(1);
63 }
64
65 STC_LabelTape(acall)
66      struct rx_call *acall;
67 {
68     printf("Got a tape labelling call.\n");
69     return 0;
70 }
71
72 STC_PerformDump(acall, adumpName, atapeSet, adumpArray, aparent, alevel,
73                 adumpID)
74      struct rx_call *acall;
75      char *adumpName;
76      afs_int32 aparent, alevel;
77      struct tc_tapeSet *atapeSet;
78      struct tc_dumpArray *adumpArray;
79      afs_int32 *adumpID;
80 {
81     register int i;
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;
88     afs_int32 new;
89
90     printf("tape controller received request to start dump %s.\n", adumpName);
91     *adumpID = ++transID;       /* send result back to caller */
92
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 */
103     tdentry.tapes.b = 0;
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);
110     if (code) {
111         printf("ttape: failed to create dump, code %d\n", code);
112         return code;
113     }
114     printf("created dump %d\n", tdentry.id);
115
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 */
121     ttentry.seq = 0;
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);
125     if (code) {
126         printf("ttape: failed to start tape %s, code %d\n", ttentry.name,
127                code);
128         return code;
129     }
130
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,
136                tdescr->date);
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);
148         if (code) {
149             printf("failed to append volume entry for volume %d, code %d\n",
150                    tdescr->vid, code);
151             return code;
152         }
153     }
154
155     ttentry.flags = BUDB_TAPE_WRITTEN;
156     code = bcdb_FinishTape(&ttentry);
157     if (code) {
158         printf("ttape: failed to finish tape, code %d\n", code);
159         return code;
160     }
161
162     code = bcdb_FinishDump(&tdentry);
163     if (code) {
164         printf("ttest: failed to finish dump, code %d\n", code);
165         return code;
166     }
167     bytesDumped = 0;
168     return 0;
169 }
170
171 STC_PerformRestore(acall, aname, arestore, adumpID)
172      struct rx_call *acall;
173      char *aname;
174      struct tc_restoreArray *arestore;
175      afs_int32 *adumpID;
176 {
177     register int i;
178     register struct tc_restoreDesc *tdescr;
179     struct sockaddr_in taddr;
180
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));
185         printf
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);
190     }
191     *adumpID = ++transID;
192     bytesDumped = 0;
193     return 0;
194 }
195
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;
201      afs_int32 adumpID;
202      struct tc_dumpStat *astatus;
203 {
204     if (adumpID != transID)
205         return 2;
206     astatus->dumpID = adumpID;
207     astatus->bytesDumped = (bytesDumped += 1470);
208     astatus->flags = 0;
209     if (bytesDumped > 2000)
210         astatus->flags = TC_STAT_DONE;
211     return 0;
212 }
213
214 STC_AbortDump(acall, adumpID)
215      struct rx_call *acall;
216      afs_int32 adumpID;
217 {
218     return 0;
219 }
220
221 /* this call waits for a dump to complete; it ties up an LWP on the tape 
222 coordinator */
223 STC_WaitForDump()
224 {
225     return 1;
226 }
227
228 STC_EndDump(acall, adumpID)
229      struct rx_call *acall;
230      afs_int32 adumpID;
231 {
232     return 0;
233 }
234
235 STC_GetTMInfo(acall)
236      struct rx_call *acall;
237 {
238     return 0;
239 }