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>
18 #include <sys/types.h>
27 #include <netinet/in.h>
31 #include <afs/afsint.h>
34 #include <afs/procmgmt.h>
35 #include <afs/afs_assert.h>
36 #include <afs/prs_fs.h>
41 #include <afs/cellconfig.h>
44 #include <afs/tcdata.h>
45 #include <afs/budb_client.h>
46 #include <afs/bucoord_prototypes.h>
47 #include "error_macros.h"
48 #include "butc_xbsa.h"
49 #include "butc_prototypes.h"
50 #include "butc_internal.h"
52 static int CopyDumpDesc(struct tc_dumpDesc *, tc_dumpArray *);
53 static int CopyRestoreDesc(struct tc_restoreDesc *, tc_restoreArray *);
54 static int CopyTapeSetDesc(struct tc_tapeSet *, struct tc_tapeSet *);
57 callPermitted(struct rx_call *call)
59 /* before this code can be used, the rx connection, on the bucoord side, must */
60 /* be changed so that it will set up for token passing instead of using a */
61 /* simple rx connection that, below, returns a value of 0 from rx_SecurityClassOf */
65 /* -----------------------------
67 * -----------------------------
71 CopyDumpDesc(struct tc_dumpDesc *toDump, tc_dumpArray *fromDump)
73 struct tc_dumpDesc *toPtr, *fromPtr;
77 fromPtr = fromDump->tc_dumpArray_val;
78 for (i = 0; i < fromDump->tc_dumpArray_len; i++) {
79 toPtr->vid = fromPtr->vid;
80 toPtr->vtype = fromPtr->vtype;
81 toPtr->partition = fromPtr->partition;
82 toPtr->date = fromPtr->date;
83 toPtr->cloneDate = fromPtr->cloneDate;
84 toPtr->hostAddr = fromPtr->hostAddr;
85 strcpy(toPtr->name, fromPtr->name);
94 CopyRestoreDesc(struct tc_restoreDesc *toRestore, tc_restoreArray *fromRestore)
96 struct tc_restoreDesc *toPtr, *fromPtr;
100 fromPtr = fromRestore->tc_restoreArray_val;
101 for (i = 0; i < fromRestore->tc_restoreArray_len; i++) {
102 toPtr->flags = fromPtr->flags;
103 toPtr->position = fromPtr->position;
104 strcpy(toPtr->tapeName, fromPtr->tapeName);
105 toPtr->dbDumpId = fromPtr->dbDumpId;
106 toPtr->initialDumpId = fromPtr->initialDumpId;
107 toPtr->origVid = fromPtr->origVid;
108 toPtr->vid = fromPtr->vid;
109 toPtr->partition = fromPtr->partition;
110 toPtr->dumpLevel = fromPtr->dumpLevel;
111 toPtr->hostAddr = fromPtr->hostAddr;
112 strcpy(toPtr->newName, fromPtr->newName);
113 strcpy(toPtr->oldName, fromPtr->oldName);
122 CopyTapeSetDesc(struct tc_tapeSet *toPtr, struct tc_tapeSet *fromPtr)
125 toPtr->id = fromPtr->id;
126 toPtr->maxTapes = fromPtr->maxTapes;
127 toPtr->a = fromPtr->a;
128 toPtr->b = fromPtr->b;
129 strcpy(toPtr->tapeServer, fromPtr->tapeServer);
130 strcpy(toPtr->format, fromPtr->format);
132 toPtr->expDate = fromPtr->expDate;
133 toPtr->expType = fromPtr->expType;
137 /* -------------------------
138 * butc - interface routines - alphabetic order
139 * -------------------------
143 STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
145 #ifdef AFS_PTHREAD_ENV
147 pthread_attr_t tattr;
152 struct labelTapeIf *ptr;
153 statusP statusPtr = NULL;
158 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
161 if (callPermitted(acid) == 0)
162 return (TC_NOTPERMITTED);
164 ptr = (struct labelTapeIf *)malloc(sizeof(*ptr));
166 ERROR_EXIT(TC_NOMEMORY);
167 memcpy(&ptr->label, label, sizeof(ptr->label));
169 /* set up the status node */
170 *taskId = allocTaskId(); /* for bucoord */
171 ptr->taskId = *taskId;
173 statusPtr = createStatusNode();
175 ERROR_EXIT(TC_INTERNALERROR);
178 statusPtr->taskId = *taskId;
179 statusPtr->lastPolled = time(0);
180 statusPtr->flags &= ~STARTING; /* ok to examine */
181 strncpy(statusPtr->taskName, "Labeltape", sizeof(statusPtr->taskName));
184 /* create the LWP to do the real work behind the scenes */
185 #ifdef AFS_PTHREAD_ENV
186 code = pthread_attr_init(&tattr);
190 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
195 code = pthread_create(&pid, &tattr, Labeller, ptr);
196 AFS_SIGSET_RESTORE();
199 LWP_CreateProcess(Labeller, 32768, 1, (void *)ptr, "labeller process",
206 deleteStatusNode(statusPtr);
215 * Tape coordinator server routine to do a dump
219 STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
221 struct dumpNode *newNode = 0;
222 statusP statusPtr = 0;
223 #ifdef AFS_PTHREAD_ENV
225 pthread_attr_t tattr;
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 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)
395 return (TC_BADTASK); /* ReadLabel does not apply if XBSA */
398 if (callPermitted(acid) == 0)
399 return (TC_NOTPERMITTED);
401 code = ReadLabel(label); /* Synchronous */
406 * restore the backup database from tape
410 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
412 #ifdef AFS_PTHREAD_ENV
414 pthread_attr_t tattr;
424 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
427 if (callPermitted(rxCall) == 0)
428 return (TC_NOTPERMITTED);
430 *taskId = allocTaskId();
432 /* create the status node */
433 statusPtr = createStatusNode();
435 ERROR_EXIT(TC_INTERNALERROR);
438 statusPtr->taskId = *taskId;
439 statusPtr->flags &= ~STARTING; /* ok to examine */
440 statusPtr->lastPolled = time(0);
441 strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
444 #ifdef AFS_PTHREAD_ENV
445 code = pthread_attr_init(&tattr);
449 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
454 code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)(intptr_t)*taskId);
455 AFS_SIGSET_RESTORE();
458 LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)(intptr_t)*taskId,
465 deleteStatusNode(statusPtr);
472 * restore the backup database from tape
476 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
478 #ifdef AFS_PTHREAD_ENV
480 pthread_attr_t tattr;
485 statusP statusPtr = NULL;
487 struct saveDbIf *ptr;
491 return (TC_BADTASK); /* LabelTape does not apply if XBSA */
494 if (callPermitted(rxCall) == 0)
495 return (TC_NOTPERMITTED);
497 *taskId = allocTaskId();
499 ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
501 ERROR_EXIT(TC_NOMEMORY);
502 ptr->archiveTime = archiveTime;
503 ptr->taskId = *taskId;
505 /* create the status node */
506 statusPtr = createStatusNode();
508 ERROR_EXIT(TC_INTERNALERROR);
511 statusPtr->taskId = *taskId;
512 statusPtr->lastPolled = time(0);
513 statusPtr->flags &= ~STARTING; /* ok to examine */
514 strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
517 ptr->statusPtr = statusPtr;
519 #ifdef AFS_PTHREAD_ENV
520 code = pthread_attr_init(&tattr);
524 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
529 code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
530 AFS_SIGSET_RESTORE();
532 code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
538 deleteStatusNode(statusPtr);
548 * read a dump (maybe more than one tape), and print out a summary
549 * of its contents. If the flag is set, add to the database.
551 * addDbFlag - if set, the information will be added to the database
555 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
557 #ifdef AFS_PTHREAD_ENV
559 pthread_attr_t tattr;
564 struct scanTapeIf *ptr;
565 statusP statusPtr = NULL;
570 return (TC_BADTASK); /* ScanDumps does not apply if XBSA */
573 if (callPermitted(acid) == 0)
574 return (TC_NOTPERMITTED);
576 *taskId = allocTaskId();
578 ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
580 ERROR_EXIT(TC_NOMEMORY);
581 ptr->addDbFlag = addDbFlag;
582 ptr->taskId = *taskId;
584 /* create the status node */
585 statusPtr = createStatusNode();
587 ERROR_EXIT(TC_INTERNALERROR);
590 statusPtr->taskId = *taskId;
591 statusPtr->lastPolled = time(0);
592 statusPtr->flags &= ~STARTING; /* ok to examine */
593 strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName));
596 #ifdef AFS_PTHREAD_ENV
597 code = pthread_attr_init(&tattr);
601 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
606 code = pthread_create(&pid, &tattr, ScanDumps, ptr);
607 AFS_SIGSET_RESTORE();
610 LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
616 deleteStatusNode(statusPtr);
625 * return information about the tape coordinator. Currently this
626 * is just the version number of the interface
630 STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
632 if (callPermitted(acid) == 0)
633 return (TC_NOTPERMITTED);
635 tciptr->tcVersion = CUR_BUTC_VERSION;
642 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
644 afs_int32 code = TC_BADTASK; /* If not compiled -Dxbsa then fail */
646 struct deleteDumpIf *ptr = 0;
647 statusP statusPtr = 0;
648 #ifdef AFS_PTHREAD_ENV
650 pthread_attr_t tattr;
659 return (TC_BADTASK); /* Only do if butc is started as XBSA */
663 if (callPermitted(acid) == 0)
664 return (TC_NOTPERMITTED);
666 ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
668 ERROR_EXIT(TC_NOMEMORY);
670 *taskId = allocTaskId();
671 ptr->dumpID = dumpID;
672 ptr->taskId = *taskId;
674 statusPtr = createStatusNode();
676 ERROR_EXIT(TC_INTERNALERROR);
679 statusPtr->taskId = *taskId;
680 statusPtr->lastPolled = time(0);
681 statusPtr->flags &= ~STARTING;
682 strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
685 #ifdef AFS_PTHREAD_ENV
686 code = pthread_attr_init(&tattr);
690 code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
695 code = pthread_create(&pid, &tattr, DeleteDump, ptr);
696 AFS_SIGSET_RESTORE();
699 LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
706 deleteStatusNode(statusPtr);