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>
18 #include <sys/types.h>
24 #include <netinet/in.h>
28 #include <afs/afsint.h>
31 #include <afs/procmgmt.h>
32 #include <afs/assert.h>
33 #include <afs/prs_fs.h>
38 #include <afs/cellconfig.h>
41 #include <afs/tcdata.h>
42 #include "error_macros.h"
43 #include "butc_xbsa.h"
44 #include "butc_prototypes.h"
46 static CopyDumpDesc();
47 static CopyRestoreDesc();
48 static CopyTapeSetDesc();
52 callPermitted(struct rx_call *call)
54 /* before this code can be used, the rx connection, on the bucoord side, must */
55 /* be changed so that it will set up for token passing instead of using a */
56 /* simple rx connection that, below, returns a value of 0 from rx_SecurityClassOf */
60 /* -----------------------------
62 * -----------------------------
66 CopyDumpDesc(struct tc_dumpDesc *toDump, tc_dumpArray *fromDump)
68 struct tc_dumpDesc *toPtr, *fromPtr;
72 fromPtr = fromDump->tc_dumpArray_val;
73 for (i = 0; i < fromDump->tc_dumpArray_len; i++) {
74 toPtr->vid = fromPtr->vid;
75 toPtr->vtype = fromPtr->vtype;
76 toPtr->partition = fromPtr->partition;
77 toPtr->date = fromPtr->date;
78 toPtr->cloneDate = fromPtr->cloneDate;
79 toPtr->hostAddr = fromPtr->hostAddr;
80 strcpy(toPtr->name, fromPtr->name);
89 CopyRestoreDesc(struct tc_restoreDesc *toRestore, tc_restoreArray *fromRestore)
91 struct tc_restoreDesc *toPtr, *fromPtr;
95 fromPtr = fromRestore->tc_restoreArray_val;
96 for (i = 0; i < fromRestore->tc_restoreArray_len; i++) {
97 toPtr->flags = fromPtr->flags;
98 toPtr->position = fromPtr->position;
99 strcpy(toPtr->tapeName, fromPtr->tapeName);
100 toPtr->dbDumpId = fromPtr->dbDumpId;
101 toPtr->initialDumpId = fromPtr->initialDumpId;
102 toPtr->origVid = fromPtr->origVid;
103 toPtr->vid = fromPtr->vid;
104 toPtr->partition = fromPtr->partition;
105 toPtr->dumpLevel = fromPtr->dumpLevel;
106 toPtr->hostAddr = fromPtr->hostAddr;
107 strcpy(toPtr->newName, fromPtr->newName);
108 strcpy(toPtr->oldName, fromPtr->oldName);
117 CopyTapeSetDesc(struct tc_tapeSet *toPtr, struct tc_tapeSet *fromPtr)
120 toPtr->id = fromPtr->id;
121 toPtr->maxTapes = fromPtr->maxTapes;
122 toPtr->a = fromPtr->a;
123 toPtr->b = fromPtr->b;
124 strcpy(toPtr->tapeServer, fromPtr->tapeServer);
125 strcpy(toPtr->format, fromPtr->format);
127 toPtr->expDate = fromPtr->expDate;
128 toPtr->expType = fromPtr->expType;
132 /* -------------------------
133 * butc - interface routines - alphabetic order
134 * -------------------------
138 STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
140 #ifdef AFS_PTHREAD_ENV
142 pthread_attr_t tattr;
147 struct labelTapeIf *ptr;
148 statusP statusPtr = NULL;
151 extern statusP createStatusNode();
152 extern afs_int32 allocTaskId();
156 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
159 if (callPermitted(acid) == 0)
160 return (TC_NOTPERMITTED);
162 ptr = (struct labelTapeIf *)malloc(sizeof(*ptr));
164 ERROR_EXIT(TC_NOMEMORY);
165 memcpy(&ptr->label, label, sizeof(ptr->label));
167 /* set up the status node */
168 *taskId = allocTaskId(); /* for bucoord */
169 ptr->taskId = *taskId;
171 statusPtr = createStatusNode();
173 ERROR_EXIT(TC_INTERNALERROR);
176 statusPtr->taskId = *taskId;
177 statusPtr->lastPolled = time(0);
178 statusPtr->flags &= ~STARTING; /* ok to examine */
179 strncpy(statusPtr->taskName, "Labeltape", sizeof(statusPtr->taskName));
182 /* create the LWP to do the real work behind the scenes */
183 #ifdef AFS_PTHREAD_ENV
184 code = pthread_attr_init(&tattr);
188 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
193 code = pthread_create(&pid, &tattr, Labeller, ptr);
194 AFS_SIGSET_RESTORE();
197 LWP_CreateProcess(Labeller, 32768, 1, (void *)ptr, "labeller process",
204 deleteStatusNode(statusPtr);
213 * Tape coordinator server routine to do a dump
217 STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
219 struct dumpNode *newNode = 0;
220 statusP statusPtr = 0;
221 #ifdef AFS_PTHREAD_ENV
223 pthread_attr_t tattr;
230 extern statusP createStatusNode();
232 if (callPermitted(rxCallId) == 0)
233 return (TC_NOTPERMITTED);
235 /* should be verifying parameter validity */
238 /* this creates a node in list, alots an id for it and prepares it for locking */
239 CreateNode(&newNode);
241 /*set up the parameters in the node, to be used by LWP */
242 strcpy(newNode->dumpSetName, tcdiPtr->dumpName);
244 newNode->dumpName = (char *)malloc(strlen(tcdiPtr->dumpPath) + 1);
245 strcpy(newNode->dumpName, tcdiPtr->dumpPath);
247 newNode->volumeSetName =
248 (char *)malloc(strlen(tcdiPtr->volumeSetName) + 1);
249 strcpy(newNode->volumeSetName, tcdiPtr->volumeSetName);
251 CopyTapeSetDesc(&(newNode->tapeSetDesc), &tcdiPtr->tapeSet);
253 newNode->dumps = (struct tc_dumpDesc *)
254 malloc(sizeof(struct tc_dumpDesc) *
255 tc_dumpArrayPtr->tc_dumpArray_len);
256 newNode->arraySize = tc_dumpArrayPtr->tc_dumpArray_len;
257 CopyDumpDesc(newNode->dumps, tc_dumpArrayPtr);
259 newNode->parent = tcdiPtr->parentDumpId;
260 newNode->level = tcdiPtr->dumpLevel;
261 newNode->doAppend = tcdiPtr->doAppend;
264 newNode->doAppend = 0; /* Append flag is ignored if talking to XBSA */
267 /* create the status node */
268 statusPtr = createStatusNode();
270 ERROR_EXIT(TC_INTERNALERROR);
273 statusPtr->taskId = newNode->taskID;
274 statusPtr->lastPolled = time(0);
275 statusPtr->flags &= ~STARTING; /* ok to examine */
276 strncpy(statusPtr->taskName, "Dump", sizeof(statusPtr->taskName));
279 newNode->statusNodePtr = statusPtr;
281 /* create the LWP to do the real work behind the scenes */
282 #ifdef AFS_PTHREAD_ENV
283 code = pthread_attr_init(&tattr);
287 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
292 code = pthread_create(&pid, &tattr, Dumper, newNode);
293 AFS_SIGSET_RESTORE();
296 LWP_CreateProcess(Dumper, 32768, 1, (void *)newNode, "dumper process",
302 *taskId = newNode->taskID;
307 deleteStatusNode(statusPtr);
308 FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */
315 STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *arestores, afs_int32 *taskID)
317 struct dumpNode *newNode;
320 #ifdef AFS_PTHREAD_ENV
322 pthread_attr_t tattr;
328 extern statusP createStatusNode();
330 if (callPermitted(acid) == 0)
331 return (TC_NOTPERMITTED);
333 /* should verify parameter validity */
335 /* this creates a node in list, alots an id for it and prepares it for locking */
336 CreateNode(&newNode);
338 newNode->restores = (struct tc_restoreDesc *)
339 malloc(sizeof(struct tc_restoreDesc) *
340 arestores->tc_restoreArray_len);
341 newNode->arraySize = arestores->tc_restoreArray_len;
342 CopyRestoreDesc(newNode->restores, arestores);
343 *taskID = newNode->taskID;
345 /* should log the intent */
347 /* create the status node */
348 statusPtr = createStatusNode();
350 ERROR_EXIT(TC_INTERNALERROR);
353 statusPtr->taskId = newNode->taskID;
354 statusPtr->flags &= ~STARTING; /* ok to examine */
355 statusPtr->lastPolled = time(0);
356 strncpy(statusPtr->taskName, "Restore", sizeof(statusPtr->taskName));
359 newNode->statusNodePtr = statusPtr;
361 /* create the LWP to do the real work behind the scenes */
362 #ifdef AFS_PTHREAD_ENV
363 code = pthread_attr_init(&tattr);
367 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
372 code = pthread_create(&pid, &tattr, Restorer, newNode);
373 AFS_SIGSET_RESTORE();
376 LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode,
377 "restorer process", &pid);
383 deleteStatusNode(statusPtr);
384 FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */
391 STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
395 extern int ReadLabel();
399 return (TC_BADTASK); /* ReadLabel does not apply if XBSA */
402 if (callPermitted(acid) == 0)
403 return (TC_NOTPERMITTED);
405 code = ReadLabel(label); /* Synchronous */
410 * restore the backup database from tape
414 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
416 #ifdef AFS_PTHREAD_ENV
418 pthread_attr_t tattr;
426 extern statusP createStatusNode();
427 extern afs_int32 allocTaskId();
431 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
434 if (callPermitted(rxCall) == 0)
435 return (TC_NOTPERMITTED);
437 *taskId = allocTaskId();
439 /* create the status node */
440 statusPtr = createStatusNode();
442 ERROR_EXIT(TC_INTERNALERROR);
445 statusPtr->taskId = *taskId;
446 statusPtr->flags &= ~STARTING; /* ok to examine */
447 statusPtr->lastPolled = time(0);
448 strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
451 #ifdef AFS_PTHREAD_ENV
452 code = pthread_attr_init(&tattr);
456 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
461 code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)*taskId);
462 AFS_SIGSET_RESTORE();
465 LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)*taskId,
472 deleteStatusNode(statusPtr);
479 * restore the backup database from tape
483 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
485 #ifdef AFS_PTHREAD_ENV
487 pthread_attr_t tattr;
492 statusP statusPtr = NULL;
494 struct saveDbIf *ptr;
496 extern statusP createStatusNode();
497 extern afs_int32 allocTaskId();
501 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
504 if (callPermitted(rxCall) == 0)
505 return (TC_NOTPERMITTED);
507 *taskId = allocTaskId();
509 ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
511 ERROR_EXIT(TC_NOMEMORY);
512 ptr->archiveTime = archiveTime;
513 ptr->taskId = *taskId;
515 /* create the status node */
516 statusPtr = createStatusNode();
518 ERROR_EXIT(TC_INTERNALERROR);
521 statusPtr->taskId = *taskId;
522 statusPtr->lastPolled = time(0);
523 statusPtr->flags &= ~STARTING; /* ok to examine */
524 strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
527 ptr->statusPtr = statusPtr;
529 #ifdef AFS_PTHREAD_ENV
530 code = pthread_attr_init(&tattr);
534 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
539 code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
540 AFS_SIGSET_RESTORE();
542 code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
548 deleteStatusNode(statusPtr);
558 * read a dump (maybe more than one tape), and print out a summary
559 * of its contents. If the flag is set, add to the database.
561 * addDbFlag - if set, the information will be added to the database
565 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
567 #ifdef AFS_PTHREAD_ENV
569 pthread_attr_t tattr;
574 struct scanTapeIf *ptr;
578 extern afs_int32 allocTaskId();
579 extern statusP createStatusNode();
583 return (TC_BADTASK); /* ScanDumps does not apply if XBSA */
586 if (callPermitted(acid) == 0)
587 return (TC_NOTPERMITTED);
589 *taskId = allocTaskId();
591 ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
593 ERROR_EXIT(TC_NOMEMORY);
594 ptr->addDbFlag = addDbFlag;
595 ptr->taskId = *taskId;
597 /* create the status node */
598 statusPtr = createStatusNode();
600 ERROR_EXIT(TC_INTERNALERROR);
603 statusPtr->taskId = *taskId;
604 statusPtr->lastPolled = time(0);
605 statusPtr->flags &= ~STARTING; /* ok to examine */
606 strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName));
609 #ifdef AFS_PTHREAD_ENV
610 code = pthread_attr_init(&tattr);
614 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
619 code = pthread_create(&pid, &tattr, ScanDumps, ptr);
620 AFS_SIGSET_RESTORE();
623 LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
629 deleteStatusNode(statusPtr);
638 * return information about the tape coordinator. Currently this
639 * is just the version number of the interface
643 STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
645 if (callPermitted(acid) == 0)
646 return (TC_NOTPERMITTED);
648 tciptr->tcVersion = CUR_BUTC_VERSION;
655 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
657 struct deleteDumpIf *ptr = 0;
658 statusP statusPtr = 0;
659 afs_int32 code = TC_BADTASK; /* If not compiled -Dxbsa then fail */
661 #ifdef AFS_PTHREAD_ENV
663 pthread_attr_t tattr;
669 extern statusP createStatusNode();
670 extern afs_int32 allocTaskId();
674 return (TC_BADTASK); /* Only do if butc is started as XBSA */
678 if (callPermitted(acid) == 0)
679 return (TC_NOTPERMITTED);
681 ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
683 ERROR_EXIT(TC_NOMEMORY);
685 *taskId = allocTaskId();
686 ptr->dumpID = dumpID;
687 ptr->taskId = *taskId;
689 statusPtr = createStatusNode();
691 ERROR_EXIT(TC_INTERNALERROR);
694 statusPtr->taskId = *taskId;
695 statusPtr->lastPolled = time(0);
696 statusPtr->flags &= ~STARTING;
697 strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
700 #ifdef AFS_PTHREAD_ENV
701 code = pthread_attr_init(&tattr);
705 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
710 code = pthread_create(&pid, &tattr, DeleteDump, ptr);
711 AFS_SIGSET_RESTORE();
714 LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
721 deleteStatusNode(statusPtr);