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);