3b1dc84a3197d901d9b006c4a9ad9861286a9a5f
[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     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         }
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] = (struct rx_securityClass *) rxnull_NewServerSecurityObject();
56     tservice = 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     printf("Got a tape labelling call.\n");
68     return 0;
69 }
70
71 STC_PerformDump(acall, adumpName, atapeSet, adumpArray, aparent, alevel, 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     register int i;
79     register struct tc_dumpDesc *tdescr;
80     register afs_int32 code;
81     struct sockaddr_in taddr;
82     struct budb_dumpEntry tdentry;
83     struct budb_volumeEntry tventry;
84     struct budb_tapeEntry ttentry;
85     afs_int32 new;
86
87     printf("tape controller received request to start dump %s.\n", adumpName);
88     *adumpID = ++transID;       /* send result back to caller */
89     
90     bzero(&tdentry, sizeof(tdentry));
91     tdentry.created = time(0);
92     strcpy(tdentry.name, atapeSet->format);
93     strcat(tdentry.name, ".");
94     strcat(tdentry.name, adumpName);
95     tdentry.parent = aparent;
96     tdentry.level = alevel;
97     tdentry.incTime = 0;        /* useless? */
98     tdentry.nVolumes = 1000000000;      /* bogus, but not important */
99     tdentry.tapes.a = 1;                /* a*x+b is tape numbering scheme */
100     tdentry.tapes.b = 0;
101     tdentry.tapes.maxTapes = 1000000000;        /* don't care */
102     strcpy(tdentry.tapes.format, atapeSet->format); /* base name (e.g. sys) */
103     strcat(tdentry.tapes.format, ".");
104     strcat(tdentry.tapes.format, adumpName);    /* e.g. .daily */
105     strcat(tdentry.tapes.format, ".%d");        /* so we get basename.0, basename.1, etc */
106     code = bcdb_CreateDump(&tdentry);
107     if (code) {
108         printf("ttape: failed to create dump, code %d\n", code);
109         return code;
110     }
111     printf("created dump %d\n", tdentry.id);
112
113     /* start tape (preent all fits on one tape at first */
114     bzero(&ttentry, sizeof(ttentry));
115     sprintf(ttentry.name, tdentry.tapes.format, 1);
116     ttentry.written = time(0);
117     ttentry.dump = tdentry.id;          /* dump we're in */
118     ttentry.seq = 0;
119     ttentry.nVolumes = 0;               /* perhaps we'll adjust during dump */
120     ttentry.flags = BUDB_TAPE_BEINGWRITTEN;     /* starting I/O */
121     code = bcdb_UseTape(&ttentry, &new);
122     if (code) {
123         printf("ttape: failed to start tape %s, code %d\n", ttentry.name, code);
124         return code;
125     }
126
127     tdescr = adumpArray->tc_dumpArray_val;
128     for(i=0;i<adumpArray->tc_dumpArray_len;i++, tdescr++) {
129         bcopy(tdescr->hostID, &taddr, sizeof(taddr));
130         printf("dumping volid %s(%d) from host %08x since date %d\n", tdescr->name,
131                tdescr->vid, taddr.sin_addr.s_addr, tdescr->date);
132         bzero(&tventry, sizeof(tventry));
133         strcpy(tventry.name, tdescr->name);
134         tventry.clone = tdescr->date;
135         tventry.seq = 0;        /* frag in volume */
136         tventry.incTime = tdescr->date; /* date from which this is an incremental? */
137         tventry.id = tdescr->vid;
138         tventry.dump = tdentry.id;
139         strcpy(tventry.tape, ttentry.name);
140         tventry.position = i;
141         tventry.flags = (BUDB_VOL_LASTFRAG | BUDB_VOL_FIRSTFRAG);
142         code = bcdb_AddVolume(&tventry);
143         if (code) {
144             printf("failed to append volume entry for volume %d, code %d\n", tdescr->vid, code);
145             return code;
146         }
147     }
148
149     ttentry.flags = BUDB_TAPE_WRITTEN;
150     code = bcdb_FinishTape(&ttentry);
151     if (code) {
152         printf("ttape: failed to finish tape, code %d\n", code);
153         return code;
154     }
155
156     code = bcdb_FinishDump(&tdentry);
157     if (code) {
158         printf("ttest: failed to finish dump, code %d\n", code);
159         return code;
160     }
161     bytesDumped = 0;
162     return 0;
163 }
164
165 STC_PerformRestore(acall, aname, arestore, adumpID)
166 struct rx_call *acall;
167 char *aname;
168 struct tc_restoreArray *arestore;
169 afs_int32 *adumpID; {
170     register int i;
171     register struct tc_restoreDesc *tdescr;
172     struct sockaddr_in taddr;
173
174     printf("tape controller received request to start restore %s.\n", aname);
175     tdescr = arestore->tc_restoreArray_val;
176     for(i=0;i<arestore->tc_restoreArray_len; i++, tdescr++) {
177         bcopy(tdescr->hostID, &taddr, sizeof(taddr));
178         printf("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",
179                tdescr->frag, tdescr->oldName, tdescr->tapeName, tdescr->position, tdescr->newName,
180                tdescr->vid, taddr.sin_addr.s_addr, tdescr->partition);
181     }
182     *adumpID = ++transID;
183     bytesDumped = 0;
184     return 0;
185 }
186
187 /* check the status of a dump; the tape coordinator is assumed to sit on
188     the status of completed dumps for a reasonable period (2 - 12 hours)
189     so that they can be examined later */
190 STC_CheckDump(acall, adumpID, astatus)
191 struct rx_call *acall;
192 afs_int32 adumpID;
193 struct tc_dumpStat *astatus; {
194     if (adumpID != transID) return 2;
195     astatus->dumpID = adumpID;
196     astatus->bytesDumped = (bytesDumped += 1470);
197     astatus->flags =0;
198     if (bytesDumped > 2000) astatus->flags = TC_STAT_DONE;
199     return 0;
200 }
201
202 STC_AbortDump(acall, adumpID)
203 struct rx_call *acall;
204 afs_int32 adumpID; {
205     return 0;
206 }
207
208 /* this call waits for a dump to complete; it ties up an LWP on the tape 
209 coordinator */
210 STC_WaitForDump() {
211     return 1;
212 }
213
214 STC_EndDump(acall, adumpID)
215 struct rx_call *acall;
216 afs_int32 adumpID; {
217     return 0;
218 }
219
220 STC_GetTMInfo(acall)
221 struct rx_call *acall; {
222     return 0;
223 }