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>
25 #include <netinet/in.h>
29 #include <afs/afsint.h>
32 #include <afs/procmgmt.h>
33 #include <afs/assert.h>
34 #include <afs/prs_fs.h>
39 #include <afs/cellconfig.h>
42 #include <afs/tcdata.h>
43 #include <afs/budb_client.h>
44 #include <afs/bucoord_prototypes.h>
45 #include "error_macros.h"
46 #include "butc_xbsa.h"
47 #include "butc_prototypes.h"
48 #include "butc_internal.h"
50 static int CopyDumpDesc(struct tc_dumpDesc *, tc_dumpArray *);
51 static int CopyRestoreDesc(struct tc_restoreDesc *, tc_restoreArray *);
52 static int CopyTapeSetDesc(struct tc_tapeSet *, struct tc_tapeSet *);
55 callPermitted(struct rx_call *call)
57 /* before this code can be used, the rx connection, on the bucoord side, must */
58 /* be changed so that it will set up for token passing instead of using a */
59 /* simple rx connection that, below, returns a value of 0 from rx_SecurityClassOf */
63 /* -----------------------------
65 * -----------------------------
69 CopyDumpDesc(struct tc_dumpDesc *toDump, tc_dumpArray *fromDump)
71 struct tc_dumpDesc *toPtr, *fromPtr;
75 fromPtr = fromDump->tc_dumpArray_val;
76 for (i = 0; i < fromDump->tc_dumpArray_len; i++) {
77 toPtr->vid = fromPtr->vid;
78 toPtr->vtype = fromPtr->vtype;
79 toPtr->partition = fromPtr->partition;
80 toPtr->date = fromPtr->date;
81 toPtr->cloneDate = fromPtr->cloneDate;
82 toPtr->hostAddr = fromPtr->hostAddr;
83 strcpy(toPtr->name, fromPtr->name);
92 CopyRestoreDesc(struct tc_restoreDesc *toRestore, tc_restoreArray *fromRestore)
94 struct tc_restoreDesc *toPtr, *fromPtr;
98 fromPtr = fromRestore->tc_restoreArray_val;
99 for (i = 0; i < fromRestore->tc_restoreArray_len; i++) {
100 toPtr->flags = fromPtr->flags;
101 toPtr->position = fromPtr->position;
102 strcpy(toPtr->tapeName, fromPtr->tapeName);
103 toPtr->dbDumpId = fromPtr->dbDumpId;
104 toPtr->initialDumpId = fromPtr->initialDumpId;
105 toPtr->origVid = fromPtr->origVid;
106 toPtr->vid = fromPtr->vid;
107 toPtr->partition = fromPtr->partition;
108 toPtr->dumpLevel = fromPtr->dumpLevel;
109 toPtr->hostAddr = fromPtr->hostAddr;
110 strcpy(toPtr->newName, fromPtr->newName);
111 strcpy(toPtr->oldName, fromPtr->oldName);
120 CopyTapeSetDesc(struct tc_tapeSet *toPtr, struct tc_tapeSet *fromPtr)
123 toPtr->id = fromPtr->id;
124 toPtr->maxTapes = fromPtr->maxTapes;
125 toPtr->a = fromPtr->a;
126 toPtr->b = fromPtr->b;
127 strcpy(toPtr->tapeServer, fromPtr->tapeServer);
128 strcpy(toPtr->format, fromPtr->format);
130 toPtr->expDate = fromPtr->expDate;
131 toPtr->expType = fromPtr->expType;
135 /* -------------------------
136 * butc - interface routines - alphabetic order
137 * -------------------------
141 STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
143 #ifdef AFS_PTHREAD_ENV
145 pthread_attr_t tattr;
150 struct labelTapeIf *ptr;
151 statusP statusPtr = NULL;
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 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 if (callPermitted(acid) == 0)
327 return (TC_NOTPERMITTED);
329 /* should verify parameter validity */
331 /* this creates a node in list, alots an id for it and prepares it for locking */
332 CreateNode(&newNode);
334 newNode->restores = (struct tc_restoreDesc *)
335 malloc(sizeof(struct tc_restoreDesc) *
336 arestores->tc_restoreArray_len);
337 newNode->arraySize = arestores->tc_restoreArray_len;
338 CopyRestoreDesc(newNode->restores, arestores);
339 *taskID = newNode->taskID;
341 /* should log the intent */
343 /* create the status node */
344 statusPtr = createStatusNode();
346 ERROR_EXIT(TC_INTERNALERROR);
349 statusPtr->taskId = newNode->taskID;
350 statusPtr->flags &= ~STARTING; /* ok to examine */
351 statusPtr->lastPolled = time(0);
352 strncpy(statusPtr->taskName, "Restore", sizeof(statusPtr->taskName));
355 newNode->statusNodePtr = statusPtr;
357 /* create the LWP to do the real work behind the scenes */
358 #ifdef AFS_PTHREAD_ENV
359 code = pthread_attr_init(&tattr);
363 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
368 code = pthread_create(&pid, &tattr, Restorer, newNode);
369 AFS_SIGSET_RESTORE();
372 LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode,
373 "restorer process", &pid);
379 deleteStatusNode(statusPtr);
380 FreeNode(newNode->taskID); /* failed to create LWP to do the dump. */
387 STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
393 return (TC_BADTASK); /* ReadLabel does not apply if XBSA */
396 if (callPermitted(acid) == 0)
397 return (TC_NOTPERMITTED);
399 code = ReadLabel(label); /* Synchronous */
404 * restore the backup database from tape
408 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
410 #ifdef AFS_PTHREAD_ENV
412 pthread_attr_t tattr;
422 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
425 if (callPermitted(rxCall) == 0)
426 return (TC_NOTPERMITTED);
428 *taskId = allocTaskId();
430 /* create the status node */
431 statusPtr = createStatusNode();
433 ERROR_EXIT(TC_INTERNALERROR);
436 statusPtr->taskId = *taskId;
437 statusPtr->flags &= ~STARTING; /* ok to examine */
438 statusPtr->lastPolled = time(0);
439 strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
442 #ifdef AFS_PTHREAD_ENV
443 code = pthread_attr_init(&tattr);
447 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
452 code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)(intptr_t)*taskId);
453 AFS_SIGSET_RESTORE();
456 LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)(intptr_t)*taskId,
463 deleteStatusNode(statusPtr);
470 * restore the backup database from tape
474 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
476 #ifdef AFS_PTHREAD_ENV
478 pthread_attr_t tattr;
483 statusP statusPtr = NULL;
485 struct saveDbIf *ptr;
489 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
492 if (callPermitted(rxCall) == 0)
493 return (TC_NOTPERMITTED);
495 *taskId = allocTaskId();
497 ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
499 ERROR_EXIT(TC_NOMEMORY);
500 ptr->archiveTime = archiveTime;
501 ptr->taskId = *taskId;
503 /* create the status node */
504 statusPtr = createStatusNode();
506 ERROR_EXIT(TC_INTERNALERROR);
509 statusPtr->taskId = *taskId;
510 statusPtr->lastPolled = time(0);
511 statusPtr->flags &= ~STARTING; /* ok to examine */
512 strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
515 ptr->statusPtr = statusPtr;
517 #ifdef AFS_PTHREAD_ENV
518 code = pthread_attr_init(&tattr);
522 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
527 code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
528 AFS_SIGSET_RESTORE();
530 code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
536 deleteStatusNode(statusPtr);
546 * read a dump (maybe more than one tape), and print out a summary
547 * of its contents. If the flag is set, add to the database.
549 * addDbFlag - if set, the information will be added to the database
553 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
555 #ifdef AFS_PTHREAD_ENV
557 pthread_attr_t tattr;
562 struct scanTapeIf *ptr;
563 statusP statusPtr = NULL;
568 return (TC_BADTASK); /* ScanDumps does not apply if XBSA */
571 if (callPermitted(acid) == 0)
572 return (TC_NOTPERMITTED);
574 *taskId = allocTaskId();
576 ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
578 ERROR_EXIT(TC_NOMEMORY);
579 ptr->addDbFlag = addDbFlag;
580 ptr->taskId = *taskId;
582 /* create the status node */
583 statusPtr = createStatusNode();
585 ERROR_EXIT(TC_INTERNALERROR);
588 statusPtr->taskId = *taskId;
589 statusPtr->lastPolled = time(0);
590 statusPtr->flags &= ~STARTING; /* ok to examine */
591 strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName));
594 #ifdef AFS_PTHREAD_ENV
595 code = pthread_attr_init(&tattr);
599 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
604 code = pthread_create(&pid, &tattr, ScanDumps, ptr);
605 AFS_SIGSET_RESTORE();
608 LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
614 deleteStatusNode(statusPtr);
623 * return information about the tape coordinator. Currently this
624 * is just the version number of the interface
628 STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
630 if (callPermitted(acid) == 0)
631 return (TC_NOTPERMITTED);
633 tciptr->tcVersion = CUR_BUTC_VERSION;
640 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
642 afs_int32 code = TC_BADTASK; /* If not compiled -Dxbsa then fail */
644 struct deleteDumpIf *ptr = 0;
645 statusP statusPtr = 0;
646 #ifdef AFS_PTHREAD_ENV
648 pthread_attr_t tattr;
657 return (TC_BADTASK); /* Only do if butc is started as XBSA */
661 if (callPermitted(acid) == 0)
662 return (TC_NOTPERMITTED);
664 ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
666 ERROR_EXIT(TC_NOMEMORY);
668 *taskId = allocTaskId();
669 ptr->dumpID = dumpID;
670 ptr->taskId = *taskId;
672 statusPtr = createStatusNode();
674 ERROR_EXIT(TC_INTERNALERROR);
677 statusPtr->taskId = *taskId;
678 statusPtr->lastPolled = time(0);
679 statusPtr->flags &= ~STARTING;
680 strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
683 #ifdef AFS_PTHREAD_ENV
684 code = pthread_attr_init(&tattr);
688 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
693 code = pthread_create(&pid, &tattr, DeleteDump, ptr);
694 AFS_SIGSET_RESTORE();
697 LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
704 deleteStatusNode(statusPtr);