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 <afs/budb_client.h>
41 #include <afs/bucoord_prototypes.h>
42 #include "error_macros.h"
43 #include "butc_xbsa.h"
44 #include "butc_prototypes.h"
45 #include "butc_internal.h"
47 static int CopyDumpDesc(struct tc_dumpDesc *, tc_dumpArray *);
48 static int CopyRestoreDesc(struct tc_restoreDesc *, tc_restoreArray *);
49 static int CopyTapeSetDesc(struct tc_tapeSet *, struct tc_tapeSet *);
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;
153 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
156 if (callPermitted(acid) == 0)
157 return (TC_NOTPERMITTED);
159 ptr = (struct labelTapeIf *)malloc(sizeof(*ptr));
161 ERROR_EXIT(TC_NOMEMORY);
162 memcpy(&ptr->label, label, sizeof(ptr->label));
164 /* set up the status node */
165 *taskId = allocTaskId(); /* for bucoord */
166 ptr->taskId = *taskId;
168 statusPtr = createStatusNode();
170 ERROR_EXIT(TC_INTERNALERROR);
173 statusPtr->taskId = *taskId;
174 statusPtr->lastPolled = time(0);
175 statusPtr->flags &= ~STARTING; /* ok to examine */
176 strncpy(statusPtr->taskName, "Labeltape", sizeof(statusPtr->taskName));
179 /* create the LWP to do the real work behind the scenes */
180 #ifdef AFS_PTHREAD_ENV
181 code = pthread_attr_init(&tattr);
185 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
190 code = pthread_create(&pid, &tattr, Labeller, ptr);
191 AFS_SIGSET_RESTORE();
194 LWP_CreateProcess(Labeller, 32768, 1, (void *)ptr, "labeller process",
201 deleteStatusNode(statusPtr);
210 * Tape coordinator server routine to do a dump
214 STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
216 struct dumpNode *newNode = 0;
217 statusP statusPtr = 0;
218 #ifdef AFS_PTHREAD_ENV
220 pthread_attr_t tattr;
227 if (callPermitted(rxCallId) == 0)
228 return (TC_NOTPERMITTED);
230 /* should be verifying parameter validity */
233 /* this creates a node in list, alots an id for it and prepares it for locking */
234 CreateNode(&newNode);
236 /*set up the parameters in the node, to be used by LWP */
237 strcpy(newNode->dumpSetName, tcdiPtr->dumpName);
239 newNode->dumpName = (char *)malloc(strlen(tcdiPtr->dumpPath) + 1);
240 strcpy(newNode->dumpName, tcdiPtr->dumpPath);
242 newNode->volumeSetName =
243 (char *)malloc(strlen(tcdiPtr->volumeSetName) + 1);
244 strcpy(newNode->volumeSetName, tcdiPtr->volumeSetName);
246 CopyTapeSetDesc(&(newNode->tapeSetDesc), &tcdiPtr->tapeSet);
248 newNode->dumps = (struct tc_dumpDesc *)
249 malloc(sizeof(struct tc_dumpDesc) *
250 tc_dumpArrayPtr->tc_dumpArray_len);
251 newNode->arraySize = tc_dumpArrayPtr->tc_dumpArray_len;
252 CopyDumpDesc(newNode->dumps, tc_dumpArrayPtr);
254 newNode->parent = tcdiPtr->parentDumpId;
255 newNode->level = tcdiPtr->dumpLevel;
256 newNode->doAppend = tcdiPtr->doAppend;
259 newNode->doAppend = 0; /* Append flag is ignored if talking to XBSA */
262 /* create the status node */
263 statusPtr = createStatusNode();
265 ERROR_EXIT(TC_INTERNALERROR);
268 statusPtr->taskId = newNode->taskID;
269 statusPtr->lastPolled = time(0);
270 statusPtr->flags &= ~STARTING; /* ok to examine */
271 strncpy(statusPtr->taskName, "Dump", sizeof(statusPtr->taskName));
274 newNode->statusNodePtr = statusPtr;
276 /* create the LWP to do the real work behind the scenes */
277 #ifdef AFS_PTHREAD_ENV
278 code = pthread_attr_init(&tattr);
282 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
287 code = pthread_create(&pid, &tattr, Dumper, newNode);
288 AFS_SIGSET_RESTORE();
291 LWP_CreateProcess(Dumper, 32768, 1, (void *)newNode, "dumper process",
297 *taskId = newNode->taskID;
302 deleteStatusNode(statusPtr);
303 FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */
310 STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *arestores, afs_int32 *taskID)
312 struct dumpNode *newNode;
315 #ifdef AFS_PTHREAD_ENV
317 pthread_attr_t tattr;
323 if (callPermitted(acid) == 0)
324 return (TC_NOTPERMITTED);
326 /* should verify parameter validity */
328 /* this creates a node in list, alots an id for it and prepares it for locking */
329 CreateNode(&newNode);
331 newNode->restores = (struct tc_restoreDesc *)
332 malloc(sizeof(struct tc_restoreDesc) *
333 arestores->tc_restoreArray_len);
334 newNode->arraySize = arestores->tc_restoreArray_len;
335 CopyRestoreDesc(newNode->restores, arestores);
336 *taskID = newNode->taskID;
338 /* should log the intent */
340 /* create the status node */
341 statusPtr = createStatusNode();
343 ERROR_EXIT(TC_INTERNALERROR);
346 statusPtr->taskId = newNode->taskID;
347 statusPtr->flags &= ~STARTING; /* ok to examine */
348 statusPtr->lastPolled = time(0);
349 strncpy(statusPtr->taskName, "Restore", sizeof(statusPtr->taskName));
352 newNode->statusNodePtr = statusPtr;
354 /* create the LWP to do the real work behind the scenes */
355 #ifdef AFS_PTHREAD_ENV
356 code = pthread_attr_init(&tattr);
360 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
365 code = pthread_create(&pid, &tattr, Restorer, newNode);
366 AFS_SIGSET_RESTORE();
369 LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode,
370 "restorer process", &pid);
376 deleteStatusNode(statusPtr);
377 FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */
384 STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
390 return (TC_BADTASK); /* ReadLabel does not apply if XBSA */
393 if (callPermitted(acid) == 0)
394 return (TC_NOTPERMITTED);
396 code = ReadLabel(label); /* Synchronous */
401 * restore the backup database from tape
405 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
407 #ifdef AFS_PTHREAD_ENV
409 pthread_attr_t tattr;
419 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
422 if (callPermitted(rxCall) == 0)
423 return (TC_NOTPERMITTED);
425 *taskId = allocTaskId();
427 /* create the status node */
428 statusPtr = createStatusNode();
430 ERROR_EXIT(TC_INTERNALERROR);
433 statusPtr->taskId = *taskId;
434 statusPtr->flags &= ~STARTING; /* ok to examine */
435 statusPtr->lastPolled = time(0);
436 strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
439 #ifdef AFS_PTHREAD_ENV
440 code = pthread_attr_init(&tattr);
444 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
449 code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)(intptr_t)*taskId);
450 AFS_SIGSET_RESTORE();
453 LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)(intptr_t)*taskId,
460 deleteStatusNode(statusPtr);
467 * restore the backup database from tape
471 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
473 #ifdef AFS_PTHREAD_ENV
475 pthread_attr_t tattr;
480 statusP statusPtr = NULL;
482 struct saveDbIf *ptr;
486 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
489 if (callPermitted(rxCall) == 0)
490 return (TC_NOTPERMITTED);
492 *taskId = allocTaskId();
494 ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
496 ERROR_EXIT(TC_NOMEMORY);
497 ptr->archiveTime = archiveTime;
498 ptr->taskId = *taskId;
500 /* create the status node */
501 statusPtr = createStatusNode();
503 ERROR_EXIT(TC_INTERNALERROR);
506 statusPtr->taskId = *taskId;
507 statusPtr->lastPolled = time(0);
508 statusPtr->flags &= ~STARTING; /* ok to examine */
509 strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
512 ptr->statusPtr = statusPtr;
514 #ifdef AFS_PTHREAD_ENV
515 code = pthread_attr_init(&tattr);
519 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
524 code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
525 AFS_SIGSET_RESTORE();
527 code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
533 deleteStatusNode(statusPtr);
543 * read a dump (maybe more than one tape), and print out a summary
544 * of its contents. If the flag is set, add to the database.
546 * addDbFlag - if set, the information will be added to the database
550 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
552 #ifdef AFS_PTHREAD_ENV
554 pthread_attr_t tattr;
559 struct scanTapeIf *ptr;
560 statusP statusPtr = NULL;
565 return (TC_BADTASK); /* ScanDumps does not apply if XBSA */
568 if (callPermitted(acid) == 0)
569 return (TC_NOTPERMITTED);
571 *taskId = allocTaskId();
573 ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
575 ERROR_EXIT(TC_NOMEMORY);
576 ptr->addDbFlag = addDbFlag;
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, "Scantape", sizeof(statusPtr->taskName));
591 #ifdef AFS_PTHREAD_ENV
592 code = pthread_attr_init(&tattr);
596 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
601 code = pthread_create(&pid, &tattr, ScanDumps, ptr);
602 AFS_SIGSET_RESTORE();
605 LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
611 deleteStatusNode(statusPtr);
620 * return information about the tape coordinator. Currently this
621 * is just the version number of the interface
625 STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
627 if (callPermitted(acid) == 0)
628 return (TC_NOTPERMITTED);
630 tciptr->tcVersion = CUR_BUTC_VERSION;
637 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
639 afs_int32 code = TC_BADTASK; /* If not compiled -Dxbsa then fail */
641 struct deleteDumpIf *ptr = 0;
642 statusP statusPtr = 0;
643 #ifdef AFS_PTHREAD_ENV
645 pthread_attr_t tattr;
654 return (TC_BADTASK); /* Only do if butc is started as XBSA */
658 if (callPermitted(acid) == 0)
659 return (TC_NOTPERMITTED);
661 ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
663 ERROR_EXIT(TC_NOMEMORY);
665 *taskId = allocTaskId();
666 ptr->dumpID = dumpID;
667 ptr->taskId = *taskId;
669 statusPtr = createStatusNode();
671 ERROR_EXIT(TC_INTERNALERROR);
674 statusPtr->taskId = *taskId;
675 statusPtr->lastPolled = time(0);
676 statusPtr->flags &= ~STARTING;
677 strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
680 #ifdef AFS_PTHREAD_ENV
681 code = pthread_attr_init(&tattr);
685 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
690 code = pthread_create(&pid, &tattr, DeleteDump, ptr);
691 AFS_SIGSET_RESTORE();
694 LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
701 deleteStatusNode(statusPtr);