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