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