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 /* procedures invoked by the rpc stub */
12 #include <afsconfig.h>
13 #include <afs/param.h>
15 #include <afs/procmgmt.h>
20 #include <afs/afsint.h>
21 #include <afs/prs_fs.h>
25 #include <afs/cellconfig.h>
28 #include <afs/tcdata.h>
29 #include <afs/budb_client.h>
30 #include <afs/bucoord_prototypes.h>
32 #include "error_macros.h"
33 #include "butc_xbsa.h"
34 #include "butc_prototypes.h"
35 #include "butc_internal.h"
36 #include "afs/audit.h"
38 static int CopyDumpDesc(struct tc_dumpDesc
*, tc_dumpArray
*);
39 static int CopyRestoreDesc(struct tc_restoreDesc
*, tc_restoreArray
*);
40 static int CopyTapeSetDesc(struct tc_tapeSet
*, struct tc_tapeSet
*);
42 /* Helpers implementing RPC backends */
43 static afs_int32
SLabelTape(struct rx_call
*acid
, struct tc_tapeLabel
*label
,
45 static afs_int32
SPerformDump(struct rx_call
*rxCallId
,
46 struct tc_dumpInterface
*tcdiPtr
,
47 tc_dumpArray
*tc_dumpArrayPtr
, afs_int32
*taskId
);
48 static afs_int32
SPerformRestore(struct rx_call
*acid
, char *dumpSetName
,
49 tc_restoreArray
*arestores
, afs_int32
*taskId
);
50 static afs_int32
SReadLabel(struct rx_call
*acid
, struct tc_tapeLabel
*label
,
52 static afs_int32
SRestoreDb(struct rx_call
*rxCall
, afs_uint32
*taskId
);
53 static afs_int32
SSaveDb(struct rx_call
*rxCall
, Date archiveTime
,
55 static afs_int32
SScanDumps(struct rx_call
*acid
, afs_int32 addDbFlag
,
57 static afs_int32
STCInfo(struct rx_call
*acid
, struct tc_tcInfo
*tciptr
);
58 static afs_int32
SDeleteDump(struct rx_call
*acid
, afs_uint32 dumpID
,
62 callPermitted(struct rx_call
*call
)
65 * If in backwards compat mode, allow anyone; otherwise, only
66 * superusers are allowed.
70 return afsconf_SuperIdentity(butc_confdir
, call
, NULL
);
73 /* -----------------------------
75 * -----------------------------
79 CopyDumpDesc(struct tc_dumpDesc
*toDump
, tc_dumpArray
*fromDump
)
81 struct tc_dumpDesc
*toPtr
, *fromPtr
;
85 fromPtr
= fromDump
->tc_dumpArray_val
;
86 for (i
= 0; i
< fromDump
->tc_dumpArray_len
; i
++) {
87 toPtr
->vid
= fromPtr
->vid
;
88 toPtr
->vtype
= fromPtr
->vtype
;
89 toPtr
->partition
= fromPtr
->partition
;
90 toPtr
->date
= fromPtr
->date
;
91 toPtr
->cloneDate
= fromPtr
->cloneDate
;
92 toPtr
->hostAddr
= fromPtr
->hostAddr
;
93 strcpy(toPtr
->name
, fromPtr
->name
);
102 CopyRestoreDesc(struct tc_restoreDesc
*toRestore
, tc_restoreArray
*fromRestore
)
104 struct tc_restoreDesc
*toPtr
, *fromPtr
;
108 fromPtr
= fromRestore
->tc_restoreArray_val
;
109 for (i
= 0; i
< fromRestore
->tc_restoreArray_len
; i
++) {
110 toPtr
->flags
= fromPtr
->flags
;
111 toPtr
->position
= fromPtr
->position
;
112 strcpy(toPtr
->tapeName
, fromPtr
->tapeName
);
113 toPtr
->dbDumpId
= fromPtr
->dbDumpId
;
114 toPtr
->initialDumpId
= fromPtr
->initialDumpId
;
115 toPtr
->origVid
= fromPtr
->origVid
;
116 toPtr
->vid
= fromPtr
->vid
;
117 toPtr
->partition
= fromPtr
->partition
;
118 toPtr
->dumpLevel
= fromPtr
->dumpLevel
;
119 toPtr
->hostAddr
= fromPtr
->hostAddr
;
120 strcpy(toPtr
->newName
, fromPtr
->newName
);
121 strcpy(toPtr
->oldName
, fromPtr
->oldName
);
130 CopyTapeSetDesc(struct tc_tapeSet
*toPtr
, struct tc_tapeSet
*fromPtr
)
133 toPtr
->id
= fromPtr
->id
;
134 toPtr
->maxTapes
= fromPtr
->maxTapes
;
135 toPtr
->a
= fromPtr
->a
;
136 toPtr
->b
= fromPtr
->b
;
137 strcpy(toPtr
->tapeServer
, fromPtr
->tapeServer
);
138 strcpy(toPtr
->format
, fromPtr
->format
);
140 toPtr
->expDate
= fromPtr
->expDate
;
141 toPtr
->expType
= fromPtr
->expType
;
145 /* -------------------------
146 * butc - interface routines - alphabetic order
147 * -------------------------
151 STC_LabelTape(struct rx_call
*acid
, struct tc_tapeLabel
*label
, afs_uint32
*taskId
)
155 code
= SLabelTape(acid
, label
, taskId
);
156 osi_auditU(acid
, TC_LabelTapeEvent
, code
,
157 AUD_TLBL
, label
, AUD_INT
, *taskId
, AUD_END
);
162 SLabelTape(struct rx_call
*acid
, struct tc_tapeLabel
*label
, afs_uint32
*taskId
)
164 #ifdef AFS_PTHREAD_ENV
166 pthread_attr_t tattr
;
171 struct labelTapeIf
*ptr
;
172 statusP statusPtr
= NULL
;
177 return (TC_BADTASK
); /* LabelTape does not apply if XBSA */
180 if (callPermitted(acid
) == 0)
181 return (TC_NOTPERMITTED
);
183 ptr
= malloc(sizeof(*ptr
));
185 ERROR_EXIT(TC_NOMEMORY
);
186 memcpy(&ptr
->label
, label
, sizeof(ptr
->label
));
188 /* set up the status node */
189 *taskId
= allocTaskId(); /* for bucoord */
190 ptr
->taskId
= *taskId
;
192 statusPtr
= createStatusNode();
194 ERROR_EXIT(TC_INTERNALERROR
);
197 statusPtr
->taskId
= *taskId
;
198 statusPtr
->lastPolled
= time(0);
199 statusPtr
->flags
&= ~STARTING
; /* ok to examine */
200 strncpy(statusPtr
->taskName
, "Labeltape", sizeof(statusPtr
->taskName
));
203 /* create the LWP to do the real work behind the scenes */
204 #ifdef AFS_PTHREAD_ENV
205 code
= pthread_attr_init(&tattr
);
209 code
= pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_DETACHED
);
214 code
= pthread_create(&pid
, &tattr
, Labeller
, ptr
);
215 AFS_SIGSET_RESTORE();
218 LWP_CreateProcess(Labeller
, 32768, 1, (void *)ptr
, "labeller process",
225 deleteStatusNode(statusPtr
);
234 * Tape coordinator server routine to do a dump
238 STC_PerformDump(struct rx_call
*call
, struct tc_dumpInterface
*di
,
239 tc_dumpArray
*da
, afs_int32
*taskId
)
243 code
= SPerformDump(call
, di
, da
, taskId
);
244 osi_auditU(call
, TC_PerformDumpEvent
, code
,
245 AUD_TDI
, di
, AUD_TDA
, da
, AUD_INT
, *taskId
, AUD_END
);
250 SPerformDump(struct rx_call
*rxCallId
, struct tc_dumpInterface
*tcdiPtr
,
251 tc_dumpArray
*tc_dumpArrayPtr
, afs_int32
*taskId
)
253 struct dumpNode
*newNode
= 0;
254 statusP statusPtr
= 0;
255 #ifdef AFS_PTHREAD_ENV
257 pthread_attr_t tattr
;
264 if (callPermitted(rxCallId
) == 0)
265 return (TC_NOTPERMITTED
);
267 /* should be verifying parameter validity */
270 /* this creates a node in list, alots an id for it and prepares it for locking */
271 CreateNode(&newNode
);
273 /*set up the parameters in the node, to be used by LWP */
274 strcpy(newNode
->dumpSetName
, tcdiPtr
->dumpName
);
276 newNode
->dumpName
= strdup(tcdiPtr
->dumpPath
);
277 newNode
->volumeSetName
= strdup(tcdiPtr
->volumeSetName
);
279 CopyTapeSetDesc(&(newNode
->tapeSetDesc
), &tcdiPtr
->tapeSet
);
281 newNode
->dumps
= malloc(sizeof(struct tc_dumpDesc
) *
282 tc_dumpArrayPtr
->tc_dumpArray_len
);
283 newNode
->arraySize
= tc_dumpArrayPtr
->tc_dumpArray_len
;
284 CopyDumpDesc(newNode
->dumps
, tc_dumpArrayPtr
);
286 newNode
->parent
= tcdiPtr
->parentDumpId
;
287 newNode
->level
= tcdiPtr
->dumpLevel
;
288 newNode
->doAppend
= tcdiPtr
->doAppend
;
291 newNode
->doAppend
= 0; /* Append flag is ignored if talking to XBSA */
294 /* create the status node */
295 statusPtr
= createStatusNode();
297 ERROR_EXIT(TC_INTERNALERROR
);
300 statusPtr
->taskId
= newNode
->taskID
;
301 statusPtr
->lastPolled
= time(0);
302 statusPtr
->flags
&= ~STARTING
; /* ok to examine */
303 strncpy(statusPtr
->taskName
, "Dump", sizeof(statusPtr
->taskName
));
306 newNode
->statusNodePtr
= statusPtr
;
308 /* create the LWP to do the real work behind the scenes */
309 #ifdef AFS_PTHREAD_ENV
310 code
= pthread_attr_init(&tattr
);
314 code
= pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_DETACHED
);
319 code
= pthread_create(&pid
, &tattr
, Dumper
, newNode
);
320 AFS_SIGSET_RESTORE();
323 LWP_CreateProcess(Dumper
, 32768, 1, (void *)newNode
, "dumper process",
329 *taskId
= newNode
->taskID
;
334 deleteStatusNode(statusPtr
);
335 FreeNode(newNode
->taskID
); /* failed to create LWP to do the dump. */
342 STC_PerformRestore(struct rx_call
*call
, char *dumpSetName
,
343 tc_restoreArray
*ra
, afs_int32
*taskId
)
347 code
= SPerformRestore(call
, dumpSetName
, ra
, taskId
);
348 osi_auditU(call
, TC_PerformRestoreEvent
, code
,
349 AUD_STR
, dumpSetName
, AUD_TRA
, ra
, AUD_INT
, *taskId
, AUD_END
);
354 SPerformRestore(struct rx_call
*acid
, char *dumpSetName
,
355 tc_restoreArray
*arestores
, afs_int32
*taskID
)
357 struct dumpNode
*newNode
;
360 #ifdef AFS_PTHREAD_ENV
362 pthread_attr_t tattr
;
368 if (callPermitted(acid
) == 0)
369 return (TC_NOTPERMITTED
);
371 /* should verify parameter validity */
373 /* this creates a node in list, alots an id for it and prepares it for locking */
374 CreateNode(&newNode
);
376 newNode
->restores
= malloc(sizeof(struct tc_restoreDesc
) *
377 arestores
->tc_restoreArray_len
);
378 newNode
->arraySize
= arestores
->tc_restoreArray_len
;
379 CopyRestoreDesc(newNode
->restores
, arestores
);
380 *taskID
= newNode
->taskID
;
382 /* should log the intent */
384 /* create the status node */
385 statusPtr
= createStatusNode();
387 ERROR_EXIT(TC_INTERNALERROR
);
390 statusPtr
->taskId
= newNode
->taskID
;
391 statusPtr
->flags
&= ~STARTING
; /* ok to examine */
392 statusPtr
->lastPolled
= time(0);
393 strncpy(statusPtr
->taskName
, "Restore", sizeof(statusPtr
->taskName
));
396 newNode
->statusNodePtr
= statusPtr
;
398 /* create the LWP to do the real work behind the scenes */
399 #ifdef AFS_PTHREAD_ENV
400 code
= pthread_attr_init(&tattr
);
404 code
= pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_DETACHED
);
409 code
= pthread_create(&pid
, &tattr
, Restorer
, newNode
);
410 AFS_SIGSET_RESTORE();
413 LWP_CreateProcess(Restorer
, 65368, 1, (void *)newNode
,
414 "restorer process", &pid
);
420 deleteStatusNode(statusPtr
);
421 FreeNode(newNode
->taskID
); /* failed to create LWP to do the dump. */
428 STC_ReadLabel(struct rx_call
*call
, struct tc_tapeLabel
*label
, afs_uint32
*taskId
)
432 code
= SReadLabel(call
, label
, taskId
);
433 osi_auditU(call
, TC_ReadLabelEvent
, code
,
434 AUD_TLBL
, label
, AUD_INT
, *taskId
, AUD_END
);
439 SReadLabel(struct rx_call
*acid
, struct tc_tapeLabel
*label
, afs_uint32
*taskId
)
443 memset(label
, 0, sizeof(*label
));
444 /* Synchronous, so no "real" ID; don't send stack garbage on the wire */
448 return (TC_BADTASK
); /* ReadLabel does not apply if XBSA */
451 if (callPermitted(acid
) == 0)
452 return (TC_NOTPERMITTED
);
454 code
= ReadLabel(label
); /* Synchronous */
459 * restore the backup database from tape
463 STC_RestoreDb(struct rx_call
*call
, afs_uint32
*taskId
)
467 code
= SRestoreDb(call
, taskId
);
468 osi_auditU(call
, TC_RestoreDbEvent
, code
, AUD_INT
, *taskId
, AUD_END
);
473 SRestoreDb(struct rx_call
*rxCall
, afs_uint32
*taskId
)
475 #ifdef AFS_PTHREAD_ENV
477 pthread_attr_t tattr
;
487 return (TC_BADTASK
); /* LabelTape does not apply if XBSA */
490 if (callPermitted(rxCall
) == 0)
491 return (TC_NOTPERMITTED
);
493 *taskId
= allocTaskId();
495 /* create the status node */
496 statusPtr
= createStatusNode();
498 ERROR_EXIT(TC_INTERNALERROR
);
501 statusPtr
->taskId
= *taskId
;
502 statusPtr
->flags
&= ~STARTING
; /* ok to examine */
503 statusPtr
->lastPolled
= time(0);
504 strncpy(statusPtr
->taskName
, "RestoreDb", sizeof(statusPtr
->taskName
));
507 #ifdef AFS_PTHREAD_ENV
508 code
= pthread_attr_init(&tattr
);
512 code
= pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_DETACHED
);
517 code
= pthread_create(&pid
, &tattr
, restoreDbFromTape
, (void *)(intptr_t)*taskId
);
518 AFS_SIGSET_RESTORE();
521 LWP_CreateProcess(restoreDbFromTape
, 32768, 1, (void *)(intptr_t)*taskId
,
528 deleteStatusNode(statusPtr
);
535 * restore the backup database from tape
539 STC_SaveDb(struct rx_call
*call
, Date archiveTime
, afs_uint32
*taskId
)
543 code
= SSaveDb(call
, archiveTime
, taskId
);
544 osi_auditU(call
, TC_SaveDbEvent
, code
,
545 AUD_DATE
, archiveTime
, AUD_INT
, *taskId
, AUD_END
);
550 SSaveDb(struct rx_call
*rxCall
, Date archiveTime
, afs_uint32
*taskId
)
552 #ifdef AFS_PTHREAD_ENV
554 pthread_attr_t tattr
;
559 statusP statusPtr
= NULL
;
561 struct saveDbIf
*ptr
;
565 return (TC_BADTASK
); /* LabelTape does not apply if XBSA */
568 if (callPermitted(rxCall
) == 0)
569 return (TC_NOTPERMITTED
);
571 *taskId
= allocTaskId();
573 ptr
= malloc(sizeof(struct saveDbIf
));
575 ERROR_EXIT(TC_NOMEMORY
);
576 ptr
->archiveTime
= archiveTime
;
577 ptr
->taskId
= *taskId
;
579 /* create the status node */
580 statusPtr
= createStatusNode();
582 ERROR_EXIT(TC_INTERNALERROR
);
585 statusPtr
->taskId
= *taskId
;
586 statusPtr
->lastPolled
= time(0);
587 statusPtr
->flags
&= ~STARTING
; /* ok to examine */
588 strncpy(statusPtr
->taskName
, "SaveDb", sizeof(statusPtr
->taskName
));
591 ptr
->statusPtr
= statusPtr
;
593 #ifdef AFS_PTHREAD_ENV
594 code
= pthread_attr_init(&tattr
);
598 code
= pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_DETACHED
);
603 code
= pthread_create(&pid
, &tattr
, saveDbToTape
, ptr
);
604 AFS_SIGSET_RESTORE();
606 code
= LWP_CreateProcess(saveDbToTape
, 32768, 1, ptr
, "Db save", &pid
);
612 deleteStatusNode(statusPtr
);
622 * read a dump (maybe more than one tape), and print out a summary
623 * of its contents. If the flag is set, add to the database.
625 * addDbFlag - if set, the information will be added to the database
629 STC_ScanDumps(struct rx_call
*call
, afs_int32 addDbFlag
, afs_uint32
*taskId
)
633 code
= SScanDumps(call
, addDbFlag
, taskId
);
634 osi_auditU(call
, TC_ScanDumpsEvent
, code
,
635 AUD_INT
, addDbFlag
, AUD_INT
, *taskId
, AUD_END
);
640 SScanDumps(struct rx_call
*acid
, afs_int32 addDbFlag
, afs_uint32
*taskId
)
642 #ifdef AFS_PTHREAD_ENV
644 pthread_attr_t tattr
;
649 struct scanTapeIf
*ptr
;
650 statusP statusPtr
= NULL
;
655 return (TC_BADTASK
); /* ScanDumps does not apply if XBSA */
658 if (callPermitted(acid
) == 0)
659 return (TC_NOTPERMITTED
);
661 *taskId
= allocTaskId();
663 ptr
= malloc(sizeof(*ptr
));
665 ERROR_EXIT(TC_NOMEMORY
);
666 ptr
->addDbFlag
= addDbFlag
;
667 ptr
->taskId
= *taskId
;
669 /* create the status node */
670 statusPtr
= createStatusNode();
672 ERROR_EXIT(TC_INTERNALERROR
);
675 statusPtr
->taskId
= *taskId
;
676 statusPtr
->lastPolled
= time(0);
677 statusPtr
->flags
&= ~STARTING
; /* ok to examine */
678 strncpy(statusPtr
->taskName
, "Scantape", sizeof(statusPtr
->taskName
));
681 #ifdef AFS_PTHREAD_ENV
682 code
= pthread_attr_init(&tattr
);
686 code
= pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_DETACHED
);
691 code
= pthread_create(&pid
, &tattr
, ScanDumps
, ptr
);
692 AFS_SIGSET_RESTORE();
695 LWP_CreateProcess(ScanDumps
, 32768, 1, ptr
, "scandump process", &pid
);
701 deleteStatusNode(statusPtr
);
710 * return information about the tape coordinator. Currently this
711 * is just the version number of the interface
715 STC_TCInfo(struct rx_call
*call
, struct tc_tcInfo
*ti
)
719 code
= STCInfo(call
, ti
);
720 osi_auditU(call
, TC_TCInfoEvent
, code
, AUD_INT
, ti
->tcVersion
, AUD_END
);
725 STCInfo(struct rx_call
*acid
, struct tc_tcInfo
*tciptr
)
727 if (callPermitted(acid
) == 0)
728 return (TC_NOTPERMITTED
);
730 tciptr
->tcVersion
= CUR_BUTC_VERSION
;
737 STC_DeleteDump(struct rx_call
*call
, afs_uint32 dumpID
, afs_uint32
*taskId
)
741 code
= SDeleteDump(call
, dumpID
, taskId
);
742 osi_auditU(call
, TC_DeleteDumpEvent
, code
,
743 AUD_DATE
, dumpID
, AUD_INT
, *taskId
, AUD_END
);
748 SDeleteDump(struct rx_call
*acid
, afs_uint32 dumpID
, afs_uint32
*taskId
)
750 afs_int32 code
= TC_BADTASK
; /* If not compiled -Dxbsa then fail */
752 struct deleteDumpIf
*ptr
= 0;
753 statusP statusPtr
= 0;
754 #ifdef AFS_PTHREAD_ENV
756 pthread_attr_t tattr
;
765 return (TC_BADTASK
); /* Only do if butc is started as XBSA */
769 if (callPermitted(acid
) == 0)
770 return (TC_NOTPERMITTED
);
772 ptr
= malloc(sizeof(*ptr
));
774 ERROR_EXIT(TC_NOMEMORY
);
776 *taskId
= allocTaskId();
777 ptr
->dumpID
= dumpID
;
778 ptr
->taskId
= *taskId
;
780 statusPtr
= createStatusNode();
782 ERROR_EXIT(TC_INTERNALERROR
);
785 statusPtr
->taskId
= *taskId
;
786 statusPtr
->lastPolled
= time(0);
787 statusPtr
->flags
&= ~STARTING
;
788 strncpy(statusPtr
->taskName
, "DeleteDump", sizeof(statusPtr
->taskName
));
791 #ifdef AFS_PTHREAD_ENV
792 code
= pthread_attr_init(&tattr
);
796 code
= pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_DETACHED
);
801 code
= pthread_create(&pid
, &tattr
, DeleteDump
, ptr
);
802 AFS_SIGSET_RESTORE();
805 LWP_CreateProcess(DeleteDump
, 32768, 1, ptr
, "deletedump process",
812 deleteStatusNode(statusPtr
);