Remove the RCSID macro
[openafs.git] / src / butc / tcprocs.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /* procedures invoked by the rpc stub */
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15
16 #include <sys/types.h>
17 #include <errno.h>
18 #ifdef AFS_NT40_ENV
19 #include <winsock2.h>
20 #else
21 #include <sys/file.h>
22 #include <netinet/in.h>
23 #endif
24 #include <rx/xdr.h>
25 #include <rx/rx.h>
26 #include <afs/afsint.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <afs/procmgmt.h>
30 #include <afs/assert.h>
31 #include <afs/prs_fs.h>
32 #include <sys/stat.h>
33 #include <afs/nfs.h>
34 #include <lwp.h>
35 #include <lock.h>
36 #include <afs/cellconfig.h>
37 #include <afs/keys.h>
38 #include <ubik.h>
39 #include <afs/tcdata.h>
40 #include "error_macros.h"
41 #include "butc_xbsa.h"
42 #include "butc_prototypes.h"
43     
44 static CopyDumpDesc();
45 static CopyRestoreDesc();
46 static CopyTapeSetDesc();
47
48
49 int
50 callPermitted(struct rx_call *call)
51 {
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 */
55     return 1;
56 }
57
58 /* -----------------------------
59  * misc. routines
60  * -----------------------------
61  */
62
63 static int
64 CopyDumpDesc(struct tc_dumpDesc *toDump, tc_dumpArray *fromDump)
65 {
66     struct tc_dumpDesc *toPtr, *fromPtr;
67     int i;
68
69     toPtr = toDump;
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);
79         fromPtr++;
80         toPtr++;
81     }
82     return 0;
83 }
84
85
86 static int
87 CopyRestoreDesc(struct tc_restoreDesc *toRestore, tc_restoreArray *fromRestore)
88 {
89     struct tc_restoreDesc *toPtr, *fromPtr;
90     int i;
91
92     toPtr = toRestore;
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);
107         fromPtr++;
108         toPtr++;
109
110     }
111     return 0;
112 }
113
114 static int
115 CopyTapeSetDesc(struct tc_tapeSet *toPtr, struct tc_tapeSet *fromPtr)
116 {
117
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);
124
125     toPtr->expDate = fromPtr->expDate;
126     toPtr->expType = fromPtr->expType;
127     return 0;
128 }
129
130 /* -------------------------
131  * butc - interface routines - alphabetic order
132  * -------------------------
133  */
134
135 afs_int32
136 STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
137 {
138 #ifdef AFS_PTHREAD_ENV
139     pthread_t pid;
140     pthread_attr_t tattr;
141     AFS_SIGSET_DECL;
142 #else
143     PROCESS pid;
144 #endif
145     struct labelTapeIf *ptr;
146     statusP statusPtr = NULL;
147     afs_int32 code;
148
149     extern statusP createStatusNode();
150     extern afs_int32 allocTaskId();
151
152 #ifdef xbsa
153     if (CONF_XBSA)
154         return (TC_BADTASK);    /* LabelTape does not apply if XBSA */
155 #endif
156
157     if (callPermitted(acid) == 0)
158         return (TC_NOTPERMITTED);
159
160     ptr = (struct labelTapeIf *)malloc(sizeof(*ptr));
161     if (!ptr)
162         ERROR_EXIT(TC_NOMEMORY);
163     memcpy(&ptr->label, label, sizeof(ptr->label));
164
165     /* set up the status node */
166     *taskId = allocTaskId();    /* for bucoord */
167     ptr->taskId = *taskId;
168
169     statusPtr = createStatusNode();
170     if (!statusPtr)
171         ERROR_EXIT(TC_INTERNALERROR);
172
173     lock_Status();
174     statusPtr->taskId = *taskId;
175     statusPtr->lastPolled = time(0);
176     statusPtr->flags &= ~STARTING;      /* ok to examine */
177     strncpy(statusPtr->taskName, "Labeltape", sizeof(statusPtr->taskName));
178     unlock_Status();
179
180     /* create the LWP to do the real work behind the scenes */
181 #ifdef AFS_PTHREAD_ENV
182     code = pthread_attr_init(&tattr);
183     if (code)
184         ERROR_EXIT(code);
185
186     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
187     if (code)
188         ERROR_EXIT(code);
189
190     AFS_SIGSET_CLEAR();
191     code = pthread_create(&pid, &tattr, Labeller, ptr);
192     AFS_SIGSET_RESTORE();
193 #else
194     code =
195         LWP_CreateProcess(Labeller, 32768, 1, (void *)ptr, "labeller process",
196                           &pid);
197 #endif
198
199   error_exit:
200     if (code) {
201         if (statusPtr)
202             deleteStatusNode(statusPtr);
203         if (ptr)
204             free(ptr);
205     }
206
207     return (code);
208 }
209
210 /* STC_PerformDump
211  *      Tape coordinator server routine to do a dump
212  */
213
214 afs_int32
215 STC_PerformDump(struct rx_call *rxCallId, struct tc_dumpInterface *tcdiPtr, tc_dumpArray *tc_dumpArrayPtr, afs_int32 *taskId)
216 {
217     struct dumpNode *newNode = 0;
218     statusP statusPtr = 0;
219 #ifdef AFS_PTHREAD_ENV
220     pthread_t pid;
221     pthread_attr_t tattr;
222     AFS_SIGSET_DECL;
223 #else
224     PROCESS pid;
225 #endif
226     afs_int32 code = 0;
227
228     extern statusP createStatusNode();
229
230     if (callPermitted(rxCallId) == 0)
231         return (TC_NOTPERMITTED);
232
233     /* should be verifying parameter validity */
234     *taskId = 0;
235
236     /* this creates a node in list, alots an id for it and prepares it for locking */
237     CreateNode(&newNode);
238
239     /*set up the parameters in the node, to be used by LWP */
240     strcpy(newNode->dumpSetName, tcdiPtr->dumpName);
241
242     newNode->dumpName = (char *)malloc(strlen(tcdiPtr->dumpPath) + 1);
243     strcpy(newNode->dumpName, tcdiPtr->dumpPath);
244
245     newNode->volumeSetName =
246         (char *)malloc(strlen(tcdiPtr->volumeSetName) + 1);
247     strcpy(newNode->volumeSetName, tcdiPtr->volumeSetName);
248
249     CopyTapeSetDesc(&(newNode->tapeSetDesc), &tcdiPtr->tapeSet);
250
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);
256
257     newNode->parent = tcdiPtr->parentDumpId;
258     newNode->level = tcdiPtr->dumpLevel;
259     newNode->doAppend = tcdiPtr->doAppend;
260 #ifdef xbsa
261     if (CONF_XBSA)
262         newNode->doAppend = 0;  /* Append flag is ignored if talking to XBSA */
263 #endif
264
265     /* create the status node */
266     statusPtr = createStatusNode();
267     if (!statusPtr)
268         ERROR_EXIT(TC_INTERNALERROR);
269
270     lock_Status();
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));
275     unlock_Status();
276
277     newNode->statusNodePtr = statusPtr;
278
279     /* create the LWP to do the real work behind the scenes */
280 #ifdef AFS_PTHREAD_ENV
281     code = pthread_attr_init(&tattr);
282     if (code)
283         ERROR_EXIT(code);
284
285     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
286     if (code)
287         ERROR_EXIT(code);
288
289     AFS_SIGSET_CLEAR();
290     code = pthread_create(&pid, &tattr, Dumper, newNode);
291     AFS_SIGSET_RESTORE();
292 #else
293     code =
294         LWP_CreateProcess(Dumper, 32768, 1, (void *)newNode, "dumper process",
295                           &pid);
296 #endif
297     if (code)
298         ERROR_EXIT(code);
299
300     *taskId = newNode->taskID;
301
302   error_exit:
303     if (code) {
304         if (statusPtr)
305             deleteStatusNode(statusPtr);
306         FreeNode(newNode->taskID);      /*  failed to create LWP to do the dump. */
307     }
308
309     return (code);
310 }
311
312 afs_int32
313 STC_PerformRestore(struct rx_call *acid, char *dumpSetName, tc_restoreArray *arestores, afs_int32 *taskID)
314 {
315     struct dumpNode *newNode;
316     statusP statusPtr;
317     afs_int32 code = 0;
318 #ifdef AFS_PTHREAD_ENV
319     pthread_t pid;
320     pthread_attr_t tattr;
321     AFS_SIGSET_DECL;
322 #else
323     PROCESS pid;
324 #endif
325
326     extern statusP createStatusNode();
327
328     if (callPermitted(acid) == 0)
329         return (TC_NOTPERMITTED);
330
331     /* should  verify parameter validity */
332
333     /* this creates a node in list, alots an id for it and prepares it for locking */
334     CreateNode(&newNode);
335
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;
342
343     /* should log the intent */
344
345     /* create the status node */
346     statusPtr = createStatusNode();
347     if (!statusPtr)
348         ERROR_EXIT(TC_INTERNALERROR);
349
350     lock_Status();
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));
355     unlock_Status();
356
357     newNode->statusNodePtr = statusPtr;
358
359     /* create the LWP to do the real work behind the scenes */
360 #ifdef AFS_PTHREAD_ENV
361     code = pthread_attr_init(&tattr);
362     if (code)
363         ERROR_EXIT(code);
364
365     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
366     if (code)
367         ERROR_EXIT(code);
368
369     AFS_SIGSET_CLEAR();
370     code = pthread_create(&pid, &tattr, Restorer, newNode);
371     AFS_SIGSET_RESTORE();
372 #else
373     code =
374         LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode,
375                           "restorer process", &pid);
376 #endif
377
378   error_exit:
379     if (code) {
380         if (statusPtr)
381             deleteStatusNode(statusPtr);
382         FreeNode(newNode->taskID);      /*  failed to create LWP to do the dump. */
383     }
384
385     return (code);
386 }
387
388 afs_int32
389 STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
390 {
391     afs_int32 code;
392
393     extern int ReadLabel();
394
395 #ifdef xbsa
396     if (CONF_XBSA)
397         return (TC_BADTASK);    /* ReadLabel does not apply if XBSA */
398 #endif
399
400     if (callPermitted(acid) == 0)
401         return (TC_NOTPERMITTED);
402
403     code = ReadLabel(label);    /* Synchronous */
404     return code;
405 }
406
407 /* STC_RestoreDb
408  *      restore the backup database from tape
409  */
410
411 afs_int32
412 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
413 {
414 #ifdef AFS_PTHREAD_ENV
415     pthread_t pid;
416     pthread_attr_t tattr;
417     AFS_SIGSET_DECL;
418 #else
419     PROCESS pid;
420 #endif
421     statusP statusPtr;
422     afs_int32 code = 0;
423
424     extern statusP createStatusNode();
425     extern afs_int32 allocTaskId();
426
427 #ifdef xbsa
428     if (CONF_XBSA)
429         return (TC_BADTASK);    /* LabelTape does not apply if XBSA */
430 #endif
431
432     if (callPermitted(rxCall) == 0)
433         return (TC_NOTPERMITTED);
434
435     *taskId = allocTaskId();
436
437     /* create the status node */
438     statusPtr = createStatusNode();
439     if (!statusPtr)
440         ERROR_EXIT(TC_INTERNALERROR);
441
442     lock_Status();
443     statusPtr->taskId = *taskId;
444     statusPtr->flags &= ~STARTING;      /* ok to examine */
445     statusPtr->lastPolled = time(0);
446     strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
447     unlock_Status();
448
449 #ifdef AFS_PTHREAD_ENV
450     code = pthread_attr_init(&tattr);
451     if (code)
452         ERROR_EXIT(code);
453
454     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
455     if (code)
456         ERROR_EXIT(code);
457
458     AFS_SIGSET_CLEAR();
459     code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)*taskId);
460     AFS_SIGSET_RESTORE();
461 #else
462     code =
463         LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)*taskId,
464                           "Db restore", &pid);
465 #endif
466
467   error_exit:
468     if (code) {
469         if (statusPtr)
470             deleteStatusNode(statusPtr);
471     }
472
473     return (code);
474 }
475
476 /* STC_SaveDb
477  *      restore the backup database from tape
478  */
479
480 afs_int32
481 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
482 {
483 #ifdef AFS_PTHREAD_ENV
484     pthread_t pid;
485     pthread_attr_t tattr;
486     AFS_SIGSET_DECL;
487 #else
488     PROCESS pid;
489 #endif
490     statusP statusPtr = NULL;
491     afs_int32 code = 0;
492     struct saveDbIf *ptr;
493
494     extern statusP createStatusNode();
495     extern afs_int32 allocTaskId();
496
497 #ifdef xbsa
498     if (CONF_XBSA)
499         return (TC_BADTASK);    /* LabelTape does not apply if XBSA */
500 #endif
501
502     if (callPermitted(rxCall) == 0)
503         return (TC_NOTPERMITTED);
504
505     *taskId = allocTaskId();
506
507     ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
508     if (!ptr)
509         ERROR_EXIT(TC_NOMEMORY);
510     ptr->archiveTime = archiveTime;
511     ptr->taskId = *taskId;
512
513     /* create the status node */
514     statusPtr = createStatusNode();
515     if (!statusPtr)
516         ERROR_EXIT(TC_INTERNALERROR);
517
518     lock_Status();
519     statusPtr->taskId = *taskId;
520     statusPtr->lastPolled = time(0);
521     statusPtr->flags &= ~STARTING;      /* ok to examine */
522     strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
523     unlock_Status();
524
525     ptr->statusPtr = statusPtr;
526
527 #ifdef AFS_PTHREAD_ENV
528     code = pthread_attr_init(&tattr);
529     if (code)
530         ERROR_EXIT(code);
531
532     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
533     if (code)
534         ERROR_EXIT(code);
535
536     AFS_SIGSET_CLEAR();
537     code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
538     AFS_SIGSET_RESTORE();
539 #else
540     code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
541 #endif
542
543   error_exit:
544     if (code) {
545         if (statusPtr)
546             deleteStatusNode(statusPtr);
547         if (ptr)
548             free(ptr);
549     }
550
551     return (code);
552 }
553
554
555 /* STC_ScanDumps
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.
558  * entry:
559  *      addDbFlag - if set, the information will be added to the database
560  */
561
562 afs_int32
563 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
564 {
565 #ifdef AFS_PTHREAD_ENV
566     pthread_t pid;
567     pthread_attr_t tattr;
568     AFS_SIGSET_DECL;
569 #else
570     PROCESS pid;
571 #endif
572     struct scanTapeIf *ptr;
573     statusP statusPtr = NULL;
574     afs_int32 code = 0;
575
576     extern afs_int32 allocTaskId();
577     extern statusP createStatusNode();
578
579 #ifdef xbsa
580     if (CONF_XBSA)
581         return (TC_BADTASK);    /* ScanDumps does not apply if XBSA */
582 #endif
583
584     if (callPermitted(acid) == 0)
585         return (TC_NOTPERMITTED);
586
587     *taskId = allocTaskId();
588
589     ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
590     if (!ptr)
591         ERROR_EXIT(TC_NOMEMORY);
592     ptr->addDbFlag = addDbFlag;
593     ptr->taskId = *taskId;
594
595     /* create the status node */
596     statusPtr = createStatusNode();
597     if (!statusPtr)
598         ERROR_EXIT(TC_INTERNALERROR);
599
600     lock_Status();
601     statusPtr->taskId = *taskId;
602     statusPtr->lastPolled = time(0);
603     statusPtr->flags &= ~STARTING;      /* ok to examine */
604     strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName));
605     unlock_Status();
606
607 #ifdef AFS_PTHREAD_ENV
608     code = pthread_attr_init(&tattr);
609     if (code)
610         ERROR_EXIT(code);
611
612     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
613     if (code)
614         ERROR_EXIT(code);
615
616     AFS_SIGSET_CLEAR();
617     code = pthread_create(&pid, &tattr, ScanDumps, ptr);
618     AFS_SIGSET_RESTORE();
619 #else
620     code =
621         LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
622 #endif
623
624   error_exit:
625     if (code) {
626         if (statusPtr)
627             deleteStatusNode(statusPtr);
628         if (ptr)
629             free(ptr);
630     }
631
632     return code;
633 }
634
635 /* STC_TCInfo
636  *      return information about the tape coordinator. Currently this
637  *      is just the version number of the interface
638  */
639
640 afs_int32
641 STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
642 {
643     if (callPermitted(acid) == 0)
644         return (TC_NOTPERMITTED);
645
646     tciptr->tcVersion = CUR_BUTC_VERSION;
647     return (0);
648 }
649
650 /* STC_DeleteDump
651  */
652 afs_int32
653 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
654 {
655     struct deleteDumpIf *ptr = 0;
656     statusP statusPtr = 0;
657     afs_int32 code = TC_BADTASK;        /* If not compiled -Dxbsa then fail */
658 #ifdef xbsa
659 #ifdef AFS_PTHREAD_ENV
660     pthread_t pid;
661     pthread_attr_t tattr;
662     AFS_SIGSET_DECL;
663 #else
664     PROCESS pid;
665 #endif
666 #endif
667     extern statusP createStatusNode();
668     extern afs_int32 allocTaskId();
669
670     *taskId = 0;
671     if (!CONF_XBSA)
672         return (TC_BADTASK);    /* Only do if butc is started as XBSA */
673
674 #ifdef xbsa
675     code = 0;
676     if (callPermitted(acid) == 0)
677         return (TC_NOTPERMITTED);
678
679     ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
680     if (!ptr)
681         ERROR_EXIT(TC_NOMEMORY);
682
683     *taskId = allocTaskId();
684     ptr->dumpID = dumpID;
685     ptr->taskId = *taskId;
686
687     statusPtr = createStatusNode();
688     if (!statusPtr)
689         ERROR_EXIT(TC_INTERNALERROR);
690
691     lock_Status();
692     statusPtr->taskId = *taskId;
693     statusPtr->lastPolled = time(0);
694     statusPtr->flags &= ~STARTING;
695     strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
696     unlock_Status();
697
698 #ifdef AFS_PTHREAD_ENV
699     code = pthread_attr_init(&tattr);
700     if (code)
701         ERROR_EXIT(code);
702
703     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
704     if (code)
705         ERROR_EXIT(code);
706
707     AFS_SIGSET_CLEAR();
708     code = pthread_create(&pid, &tattr, DeleteDump, ptr);
709     AFS_SIGSET_RESTORE();
710 #else
711     code =
712         LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
713                           &pid);
714 #endif
715
716   error_exit:
717     if (code) {
718         if (statusPtr)
719             deleteStatusNode(statusPtr);
720         if (ptr)
721             free(ptr);
722     }
723 #endif /* xbsa */
724
725     return (code);
726 }
727