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 <afsconfig.h>
11 #include <afs/param.h>
17 #include <afs/bubasics.h>
23 /* dump information */
24 static afs_int32 transID
= 1000; /* dump or restore transaction id */
25 static afs_int32 bytesDumped
= 0;
27 #include "AFS_component_version_number.c"
35 struct rx_service
*tservice
;
36 struct rx_securityClass
*rxsc
[1];
38 for (i
= 1; i
< argc
; i
++) {
40 if (*argv
[i
] == '-') {
43 printf("ttest takes only switches (not '%s')\n", argv
[i
]);
47 code
= rx_Init(htons(BC_TAPEPORT
));
49 printf("ttest: could not initialize rx, code %d.\n", code
);
52 rxsc
[0] = rxnull_NewServerSecurityObject();
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 */
59 printf("RETURNED FROM STARTSERVER!\n");
64 struct rx_call
*acall
;
66 printf("Got a tape labelling call.\n");
70 STC_PerformDump(acall
, adumpName
, atapeSet
, adumpArray
, aparent
, alevel
,
72 struct rx_call
*acall
;
74 afs_int32 aparent
, alevel
;
75 struct tc_tapeSet
*atapeSet
;
76 struct tc_dumpArray
*adumpArray
;
80 struct tc_dumpDesc
*tdescr
;
82 struct sockaddr_in taddr
;
83 struct budb_dumpEntry tdentry
;
84 struct budb_volumeEntry tventry
;
85 struct budb_tapeEntry ttentry
;
88 printf("tape controller received request to start dump %s.\n", adumpName
);
89 *adumpID
= ++transID
; /* send result back to caller */
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 */
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
);
109 printf("ttape: failed to create dump, code %d\n", code
);
112 printf("created dump %d\n", tdentry
.id
);
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 */
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);
124 printf("ttape: failed to start tape %s, code %d\n", ttentry
.name
,
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
,
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
);
147 printf("failed to append volume entry for volume %d, code %d\n",
153 ttentry
.flags
= BUDB_TAPE_WRITTEN
;
154 code
= bcdb_FinishTape(&ttentry
);
156 printf("ttape: failed to finish tape, code %d\n", code
);
160 code
= bcdb_FinishDump(&tdentry
);
162 printf("ttest: failed to finish dump, code %d\n", code
);
169 STC_PerformRestore(acall
, aname
, arestore
, adumpID
)
170 struct rx_call
*acall
;
172 struct tc_restoreArray
*arestore
;
176 struct tc_restoreDesc
*tdescr
;
177 struct sockaddr_in taddr
;
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
));
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
);
189 *adumpID
= ++transID
;
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
;
200 struct tc_dumpStat
*astatus
;
202 if (adumpID
!= transID
)
204 astatus
->dumpID
= adumpID
;
205 astatus
->bytesDumped
= (bytesDumped
+= 1470);
207 if (bytesDumped
> 2000)
208 astatus
->flags
= TC_STAT_DONE
;
212 STC_AbortDump(acall
, adumpID
)
213 struct rx_call
*acall
;
219 /* this call waits for a dump to complete; it ties up an LWP on the tape
226 STC_EndDump(acall
, adumpID
)
227 struct rx_call
*acall
;
234 struct rx_call
*acall
;