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>
16 #include <sys/types.h>
22 #include <netinet/in.h>
26 #include <afs/afsint.h>
29 #include <afs/procmgmt.h>
30 #include <afs/assert.h>
31 #include <afs/prs_fs.h>
36 #include <afs/cellconfig.h>
39 #include <afs/tcdata.h>
40 #include "error_macros.h"
41 #include "butc_xbsa.h"
42 #include "butc_prototypes.h"
44 static CopyDumpDesc();
45 static CopyRestoreDesc();
46 static CopyTapeSetDesc();
50 callPermitted(struct rx_call *call)
52 /* before this code can be used, the rx connection, on the bucoord side, must */
53 /* be changed so that it will set up for token passing instead of using a */
54 /* simple rx connection that, below, returns a value of 0 from rx_SecurityClassOf */
58 /* -----------------------------
60 * -----------------------------
64 CopyDumpDesc(struct tc_dumpDesc *toDump, tc_dumpArray *fromDump)
66 struct tc_dumpDesc *toPtr, *fromPtr;
70 fromPtr = fromDump->tc_dumpArray_val;
71 for (i = 0; i < fromDump->tc_dumpArray_len; i++) {
72 toPtr->vid = fromPtr->vid;
73 toPtr->vtype = fromPtr->vtype;
74 toPtr->partition = fromPtr->partition;
75 toPtr->date = fromPtr->date;
76 toPtr->cloneDate = fromPtr->cloneDate;
77 toPtr->hostAddr = fromPtr->hostAddr;
78 strcpy(toPtr->name, fromPtr->name);
87 CopyRestoreDesc(struct tc_restoreDesc *toRestore, tc_restoreArray *fromRestore)
89 struct tc_restoreDesc *toPtr, *fromPtr;
93 fromPtr = fromRestore->tc_restoreArray_val;
94 for (i = 0; i < fromRestore->tc_restoreArray_len; i++) {
95 toPtr->flags = fromPtr->flags;
96 toPtr->position = fromPtr->position;
97 strcpy(toPtr->tapeName, fromPtr->tapeName);
98 toPtr->dbDumpId = fromPtr->dbDumpId;
99 toPtr->initialDumpId = fromPtr->initialDumpId;
100 toPtr->origVid = fromPtr->origVid;
101 toPtr->vid = fromPtr->vid;
102 toPtr->partition = fromPtr->partition;
103 toPtr->dumpLevel = fromPtr->dumpLevel;
104 toPtr->hostAddr = fromPtr->hostAddr;
105 strcpy(toPtr->newName, fromPtr->newName);
106 strcpy(toPtr->oldName, fromPtr->oldName);
115 CopyTapeSetDesc(struct tc_tapeSet *toPtr, struct tc_tapeSet *fromPtr)
118 toPtr->id = fromPtr->id;
119 toPtr->maxTapes = fromPtr->maxTapes;
120 toPtr->a = fromPtr->a;
121 toPtr->b = fromPtr->b;
122 strcpy(toPtr->tapeServer, fromPtr->tapeServer);
123 strcpy(toPtr->format, fromPtr->format);
125 toPtr->expDate = fromPtr->expDate;
126 toPtr->expType = fromPtr->expType;
130 /* -------------------------
131 * butc - interface routines - alphabetic order
132 * -------------------------
136 STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
138 #ifdef AFS_PTHREAD_ENV
140 pthread_attr_t tattr;
145 struct labelTapeIf *ptr;
146 statusP statusPtr = NULL;
149 extern statusP createStatusNode();
150 extern afs_int32 allocTaskId();
154 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
157 if (callPermitted(acid) == 0)
158 return (TC_NOTPERMITTED);
160 ptr = (struct labelTapeIf *)malloc(sizeof(*ptr));
162 ERROR_EXIT(TC_NOMEMORY);
163 memcpy(&ptr->label, label, sizeof(ptr->label));
165 /* set up the status node */
166 *taskId = allocTaskId(); /* for bucoord */
167 ptr->taskId = *taskId;
169 statusPtr = createStatusNode();
171 ERROR_EXIT(TC_INTERNALERROR);
174 statusPtr->taskId = *taskId;
175 statusPtr->lastPolled = time(0);
176 statusPtr->flags &= ~STARTING; /* ok to examine */
177 strncpy(statusPtr->taskName, "Labeltape", sizeof(statusPtr->taskName));
180 /* create the LWP to do the real work behind the scenes */
181 #ifdef AFS_PTHREAD_ENV
182 code = pthread_attr_init(&tattr);
186 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
191 code = pthread_create(&pid, &tattr, Labeller, ptr);
192 AFS_SIGSET_RESTORE();
195 LWP_CreateProcess(Labeller, 32768, 1, (void *)ptr, "labeller process",
202 deleteStatusNode(statusPtr);
211 * Tape coordinator server routine to do a dump
215 STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
217 struct dumpNode *newNode = 0;
218 statusP statusPtr = 0;
219 #ifdef AFS_PTHREAD_ENV
221 pthread_attr_t tattr;
228 extern statusP createStatusNode();
230 if (callPermitted(rxCallId) == 0)
231 return (TC_NOTPERMITTED);
233 /* should be verifying parameter validity */
236 /* this creates a node in list, alots an id for it and prepares it for locking */
237 CreateNode(&newNode);
239 /*set up the parameters in the node, to be used by LWP */
240 strcpy(newNode->dumpSetName, tcdiPtr->dumpName);
242 newNode->dumpName = (char *)malloc(strlen(tcdiPtr->dumpPath) + 1);
243 strcpy(newNode->dumpName, tcdiPtr->dumpPath);
245 newNode->volumeSetName =
246 (char *)malloc(strlen(tcdiPtr->volumeSetName) + 1);
247 strcpy(newNode->volumeSetName, tcdiPtr->volumeSetName);
249 CopyTapeSetDesc(&(newNode->tapeSetDesc), &tcdiPtr->tapeSet);
251 newNode->dumps = (struct tc_dumpDesc *)
252 malloc(sizeof(struct tc_dumpDesc) *
253 tc_dumpArrayPtr->tc_dumpArray_len);
254 newNode->arraySize = tc_dumpArrayPtr->tc_dumpArray_len;
255 CopyDumpDesc(newNode->dumps, tc_dumpArrayPtr);
257 newNode->parent = tcdiPtr->parentDumpId;
258 newNode->level = tcdiPtr->dumpLevel;
259 newNode->doAppend = tcdiPtr->doAppend;
262 newNode->doAppend = 0; /* Append flag is ignored if talking to XBSA */
265 /* create the status node */
266 statusPtr = createStatusNode();
268 ERROR_EXIT(TC_INTERNALERROR);
271 statusPtr->taskId = newNode->taskID;
272 statusPtr->lastPolled = time(0);
273 statusPtr->flags &= ~STARTING; /* ok to examine */
274 strncpy(statusPtr->taskName, "Dump", sizeof(statusPtr->taskName));
277 newNode->statusNodePtr = statusPtr;
279 /* create the LWP to do the real work behind the scenes */
280 #ifdef AFS_PTHREAD_ENV
281 code = pthread_attr_init(&tattr);
285 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
290 code = pthread_create(&pid, &tattr, Dumper, newNode);
291 AFS_SIGSET_RESTORE();
294 LWP_CreateProcess(Dumper, 32768, 1, (void *)newNode, "dumper process",
300 *taskId = newNode->taskID;
305 deleteStatusNode(statusPtr);
306 FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */
313 STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *arestores, afs_int32 *taskID)
315 struct dumpNode *newNode;
318 #ifdef AFS_PTHREAD_ENV
320 pthread_attr_t tattr;
326 extern statusP createStatusNode();
328 if (callPermitted(acid) == 0)
329 return (TC_NOTPERMITTED);
331 /* should verify parameter validity */
333 /* this creates a node in list, alots an id for it and prepares it for locking */
334 CreateNode(&newNode);
336 newNode->restores = (struct tc_restoreDesc *)
337 malloc(sizeof(struct tc_restoreDesc) *
338 arestores->tc_restoreArray_len);
339 newNode->arraySize = arestores->tc_restoreArray_len;
340 CopyRestoreDesc(newNode->restores, arestores);
341 *taskID = newNode->taskID;
343 /* should log the intent */
345 /* create the status node */
346 statusPtr = createStatusNode();
348 ERROR_EXIT(TC_INTERNALERROR);
351 statusPtr->taskId = newNode->taskID;
352 statusPtr->flags &= ~STARTING; /* ok to examine */
353 statusPtr->lastPolled = time(0);
354 strncpy(statusPtr->taskName, "Restore", sizeof(statusPtr->taskName));
357 newNode->statusNodePtr = statusPtr;
359 /* create the LWP to do the real work behind the scenes */
360 #ifdef AFS_PTHREAD_ENV
361 code = pthread_attr_init(&tattr);
365 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
370 code = pthread_create(&pid, &tattr, Restorer, newNode);
371 AFS_SIGSET_RESTORE();
374 LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode,
375 "restorer process", &pid);
381 deleteStatusNode(statusPtr);
382 FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */
389 STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
393 extern int ReadLabel();
397 return (TC_BADTASK); /* ReadLabel does not apply if XBSA */
400 if (callPermitted(acid) == 0)
401 return (TC_NOTPERMITTED);
403 code = ReadLabel(label); /* Synchronous */
408 * restore the backup database from tape
412 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
414 #ifdef AFS_PTHREAD_ENV
416 pthread_attr_t tattr;
424 extern statusP createStatusNode();
425 extern afs_int32 allocTaskId();
429 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
432 if (callPermitted(rxCall) == 0)
433 return (TC_NOTPERMITTED);
435 *taskId = allocTaskId();
437 /* create the status node */
438 statusPtr = createStatusNode();
440 ERROR_EXIT(TC_INTERNALERROR);
443 statusPtr->taskId = *taskId;
444 statusPtr->flags &= ~STARTING; /* ok to examine */
445 statusPtr->lastPolled = time(0);
446 strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
449 #ifdef AFS_PTHREAD_ENV
450 code = pthread_attr_init(&tattr);
454 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
459 code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)*taskId);
460 AFS_SIGSET_RESTORE();
463 LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)*taskId,
470 deleteStatusNode(statusPtr);
477 * restore the backup database from tape
481 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
483 #ifdef AFS_PTHREAD_ENV
485 pthread_attr_t tattr;
490 statusP statusPtr = NULL;
492 struct saveDbIf *ptr;
494 extern statusP createStatusNode();
495 extern afs_int32 allocTaskId();
499 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
502 if (callPermitted(rxCall) == 0)
503 return (TC_NOTPERMITTED);
505 *taskId = allocTaskId();
507 ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
509 ERROR_EXIT(TC_NOMEMORY);
510 ptr->archiveTime = archiveTime;
511 ptr->taskId = *taskId;
513 /* create the status node */
514 statusPtr = createStatusNode();
516 ERROR_EXIT(TC_INTERNALERROR);
519 statusPtr->taskId = *taskId;
520 statusPtr->lastPolled = time(0);
521 statusPtr->flags &= ~STARTING; /* ok to examine */
522 strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
525 ptr->statusPtr = statusPtr;
527 #ifdef AFS_PTHREAD_ENV
528 code = pthread_attr_init(&tattr);
532 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
537 code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
538 AFS_SIGSET_RESTORE();
540 code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
546 deleteStatusNode(statusPtr);
556 * read a dump (maybe more than one tape), and print out a summary
557 * of its contents. If the flag is set, add to the database.
559 * addDbFlag - if set, the information will be added to the database
563 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
565 #ifdef AFS_PTHREAD_ENV
567 pthread_attr_t tattr;
572 struct scanTapeIf *ptr;
573 statusP statusPtr = NULL;
576 extern afs_int32 allocTaskId();
577 extern statusP createStatusNode();
581 return (TC_BADTASK); /* ScanDumps does not apply if XBSA */
584 if (callPermitted(acid) == 0)
585 return (TC_NOTPERMITTED);
587 *taskId = allocTaskId();
589 ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
591 ERROR_EXIT(TC_NOMEMORY);
592 ptr->addDbFlag = addDbFlag;
593 ptr->taskId = *taskId;
595 /* create the status node */
596 statusPtr = createStatusNode();
598 ERROR_EXIT(TC_INTERNALERROR);
601 statusPtr->taskId = *taskId;
602 statusPtr->lastPolled = time(0);
603 statusPtr->flags &= ~STARTING; /* ok to examine */
604 strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName));
607 #ifdef AFS_PTHREAD_ENV
608 code = pthread_attr_init(&tattr);
612 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
617 code = pthread_create(&pid, &tattr, ScanDumps, ptr);
618 AFS_SIGSET_RESTORE();
621 LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
627 deleteStatusNode(statusPtr);
636 * return information about the tape coordinator. Currently this
637 * is just the version number of the interface
641 STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
643 if (callPermitted(acid) == 0)
644 return (TC_NOTPERMITTED);
646 tciptr->tcVersion = CUR_BUTC_VERSION;
653 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
655 struct deleteDumpIf *ptr = 0;
656 statusP statusPtr = 0;
657 afs_int32 code = TC_BADTASK; /* If not compiled -Dxbsa then fail */
659 #ifdef AFS_PTHREAD_ENV
661 pthread_attr_t tattr;
667 extern statusP createStatusNode();
668 extern afs_int32 allocTaskId();
672 return (TC_BADTASK); /* Only do if butc is started as XBSA */
676 if (callPermitted(acid) == 0)
677 return (TC_NOTPERMITTED);
679 ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
681 ERROR_EXIT(TC_NOMEMORY);
683 *taskId = allocTaskId();
684 ptr->dumpID = dumpID;
685 ptr->taskId = *taskId;
687 statusPtr = createStatusNode();
689 ERROR_EXIT(TC_INTERNALERROR);
692 statusPtr->taskId = *taskId;
693 statusPtr->lastPolled = time(0);
694 statusPtr->flags &= ~STARTING;
695 strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
698 #ifdef AFS_PTHREAD_ENV
699 code = pthread_attr_init(&tattr);
703 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
708 code = pthread_create(&pid, &tattr, DeleteDump, ptr);
709 AFS_SIGSET_RESTORE();
712 LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
719 deleteStatusNode(statusPtr);