death to trailing whitespace
[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 HAVE_STDINT_H
19 # include <stdint.h>
20 #endif
21 #ifdef AFS_NT40_ENV
22 #include <winsock2.h>
23 #else
24 #include <sys/file.h>
25 #include <netinet/in.h>
26 #endif
27 #include <rx/xdr.h>
28 #include <rx/rx.h>
29 #include <afs/afsint.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <afs/procmgmt.h>
33 #include <afs/assert.h>
34 #include <afs/prs_fs.h>
35 #include <sys/stat.h>
36 #include <afs/nfs.h>
37 #include <lwp.h>
38 #include <lock.h>
39 #include <afs/cellconfig.h>
40 #include <afs/keys.h>
41 #include <ubik.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"
49
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 *);
53
54 int
55 callPermitted(struct rx_call *call)
56 {
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 */
60     return 1;
61 }
62
63 /* -----------------------------
64  * misc. routines
65  * -----------------------------
66  */
67
68 static int
69 CopyDumpDesc(struct tc_dumpDesc *toDump, tc_dumpArray *fromDump)
70 {
71     struct tc_dumpDesc *toPtr, *fromPtr;
72     int i;
73
74     toPtr = toDump;
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);
84         fromPtr++;
85         toPtr++;
86     }
87     return 0;
88 }
89
90
91 static int
92 CopyRestoreDesc(struct tc_restoreDesc *toRestore, tc_restoreArray *fromRestore)
93 {
94     struct tc_restoreDesc *toPtr, *fromPtr;
95     int i;
96
97     toPtr = toRestore;
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);
112         fromPtr++;
113         toPtr++;
114
115     }
116     return 0;
117 }
118
119 static int
120 CopyTapeSetDesc(struct tc_tapeSet *toPtr, struct tc_tapeSet *fromPtr)
121 {
122
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);
129
130     toPtr->expDate = fromPtr->expDate;
131     toPtr->expType = fromPtr->expType;
132     return 0;
133 }
134
135 /* -------------------------
136  * butc - interface routines - alphabetic order
137  * -------------------------
138  */
139
140 afs_int32
141 STC_LabelTape(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
142 {
143 #ifdef AFS_PTHREAD_ENV
144     pthread_t pid;
145     pthread_attr_t tattr;
146     AFS_SIGSET_DECL;
147 #else
148     PROCESS pid;
149 #endif
150     struct labelTapeIf *ptr;
151     statusP statusPtr = NULL;
152     afs_int32 code;
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     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     if (callPermitted(acid) == 0)
327         return (TC_NOTPERMITTED);
328
329     /* should  verify parameter validity */
330
331     /* this creates a node in list, alots an id for it and prepares it for locking */
332     CreateNode(&newNode);
333
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;
340
341     /* should log the intent */
342
343     /* create the status node */
344     statusPtr = createStatusNode();
345     if (!statusPtr)
346         ERROR_EXIT(TC_INTERNALERROR);
347
348     lock_Status();
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));
353     unlock_Status();
354
355     newNode->statusNodePtr = statusPtr;
356
357     /* create the LWP to do the real work behind the scenes */
358 #ifdef AFS_PTHREAD_ENV
359     code = pthread_attr_init(&tattr);
360     if (code)
361         ERROR_EXIT(code);
362
363     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
364     if (code)
365         ERROR_EXIT(code);
366
367     AFS_SIGSET_CLEAR();
368     code = pthread_create(&pid, &tattr, Restorer, newNode);
369     AFS_SIGSET_RESTORE();
370 #else
371     code =
372         LWP_CreateProcess(Restorer, 65368, 1, (void *)newNode,
373                           "restorer process", &pid);
374 #endif
375
376   error_exit:
377     if (code) {
378         if (statusPtr)
379             deleteStatusNode(statusPtr);
380         FreeNode(newNode->taskID);      /*  failed to create LWP to do the dump. */
381     }
382
383     return (code);
384 }
385
386 afs_int32
387 STC_ReadLabel(struct rx_call *acid, struct tc_tapeLabel *label, afs_uint32 *taskId)
388 {
389     afs_int32 code;
390
391 #ifdef xbsa
392     if (CONF_XBSA)
393         return (TC_BADTASK);    /* ReadLabel does not apply if XBSA */
394 #endif
395
396     if (callPermitted(acid) == 0)
397         return (TC_NOTPERMITTED);
398
399     code = ReadLabel(label);    /* Synchronous */
400     return code;
401 }
402
403 /* STC_RestoreDb
404  *      restore the backup database from tape
405  */
406
407 afs_int32
408 STC_RestoreDb(struct rx_call *rxCall, afs_uint32 *taskId)
409 {
410 #ifdef AFS_PTHREAD_ENV
411     pthread_t pid;
412     pthread_attr_t tattr;
413     AFS_SIGSET_DECL;
414 #else
415     PROCESS pid;
416 #endif
417     statusP statusPtr;
418     afs_int32 code = 0;
419
420 #ifdef xbsa
421     if (CONF_XBSA)
422         return (TC_BADTASK);    /* LabelTape does not apply if XBSA */
423 #endif
424
425     if (callPermitted(rxCall) == 0)
426         return (TC_NOTPERMITTED);
427
428     *taskId = allocTaskId();
429
430     /* create the status node */
431     statusPtr = createStatusNode();
432     if (!statusPtr)
433         ERROR_EXIT(TC_INTERNALERROR);
434
435     lock_Status();
436     statusPtr->taskId = *taskId;
437     statusPtr->flags &= ~STARTING;      /* ok to examine */
438     statusPtr->lastPolled = time(0);
439     strncpy(statusPtr->taskName, "RestoreDb", sizeof(statusPtr->taskName));
440     unlock_Status();
441
442 #ifdef AFS_PTHREAD_ENV
443     code = pthread_attr_init(&tattr);
444     if (code)
445         ERROR_EXIT(code);
446
447     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
448     if (code)
449         ERROR_EXIT(code);
450
451     AFS_SIGSET_CLEAR();
452     code = pthread_create(&pid, &tattr, restoreDbFromTape, (void *)(intptr_t)*taskId);
453     AFS_SIGSET_RESTORE();
454 #else
455     code =
456         LWP_CreateProcess(restoreDbFromTape, 32768, 1, (void *)(intptr_t)*taskId,
457                           "Db restore", &pid);
458 #endif
459
460   error_exit:
461     if (code) {
462         if (statusPtr)
463             deleteStatusNode(statusPtr);
464     }
465
466     return (code);
467 }
468
469 /* STC_SaveDb
470  *      restore the backup database from tape
471  */
472
473 afs_int32
474 STC_SaveDb(struct rx_call *rxCall, Date archiveTime, afs_uint32 *taskId)
475 {
476 #ifdef AFS_PTHREAD_ENV
477     pthread_t pid;
478     pthread_attr_t tattr;
479     AFS_SIGSET_DECL;
480 #else
481     PROCESS pid;
482 #endif
483     statusP statusPtr = NULL;
484     afs_int32 code = 0;
485     struct saveDbIf *ptr;
486
487 #ifdef xbsa
488     if (CONF_XBSA)
489         return (TC_BADTASK);    /* LabelTape does not apply if XBSA */
490 #endif
491
492     if (callPermitted(rxCall) == 0)
493         return (TC_NOTPERMITTED);
494
495     *taskId = allocTaskId();
496
497     ptr = (struct saveDbIf *)malloc(sizeof(struct saveDbIf));
498     if (!ptr)
499         ERROR_EXIT(TC_NOMEMORY);
500     ptr->archiveTime = archiveTime;
501     ptr->taskId = *taskId;
502
503     /* create the status node */
504     statusPtr = createStatusNode();
505     if (!statusPtr)
506         ERROR_EXIT(TC_INTERNALERROR);
507
508     lock_Status();
509     statusPtr->taskId = *taskId;
510     statusPtr->lastPolled = time(0);
511     statusPtr->flags &= ~STARTING;      /* ok to examine */
512     strncpy(statusPtr->taskName, "SaveDb", sizeof(statusPtr->taskName));
513     unlock_Status();
514
515     ptr->statusPtr = statusPtr;
516
517 #ifdef AFS_PTHREAD_ENV
518     code = pthread_attr_init(&tattr);
519     if (code)
520         ERROR_EXIT(code);
521
522     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
523     if (code)
524         ERROR_EXIT(code);
525
526     AFS_SIGSET_CLEAR();
527     code = pthread_create(&pid, &tattr, saveDbToTape, ptr);
528     AFS_SIGSET_RESTORE();
529 #else
530     code = LWP_CreateProcess(saveDbToTape, 32768, 1, ptr, "Db save", &pid);
531 #endif
532
533   error_exit:
534     if (code) {
535         if (statusPtr)
536             deleteStatusNode(statusPtr);
537         if (ptr)
538             free(ptr);
539     }
540
541     return (code);
542 }
543
544
545 /* STC_ScanDumps
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.
548  * entry:
549  *      addDbFlag - if set, the information will be added to the database
550  */
551
552 afs_int32
553 STC_ScanDumps(struct rx_call *acid, afs_int32 addDbFlag, afs_uint32 *taskId)
554 {
555 #ifdef AFS_PTHREAD_ENV
556     pthread_t pid;
557     pthread_attr_t tattr;
558     AFS_SIGSET_DECL;
559 #else
560     PROCESS pid;
561 #endif
562     struct scanTapeIf *ptr;
563     statusP statusPtr = NULL;
564     afs_int32 code = 0;
565
566 #ifdef xbsa
567     if (CONF_XBSA)
568         return (TC_BADTASK);    /* ScanDumps does not apply if XBSA */
569 #endif
570
571     if (callPermitted(acid) == 0)
572         return (TC_NOTPERMITTED);
573
574     *taskId = allocTaskId();
575
576     ptr = (struct scanTapeIf *)malloc(sizeof(*ptr));
577     if (!ptr)
578         ERROR_EXIT(TC_NOMEMORY);
579     ptr->addDbFlag = addDbFlag;
580     ptr->taskId = *taskId;
581
582     /* create the status node */
583     statusPtr = createStatusNode();
584     if (!statusPtr)
585         ERROR_EXIT(TC_INTERNALERROR);
586
587     lock_Status();
588     statusPtr->taskId = *taskId;
589     statusPtr->lastPolled = time(0);
590     statusPtr->flags &= ~STARTING;      /* ok to examine */
591     strncpy(statusPtr->taskName, "Scantape", sizeof(statusPtr->taskName));
592     unlock_Status();
593
594 #ifdef AFS_PTHREAD_ENV
595     code = pthread_attr_init(&tattr);
596     if (code)
597         ERROR_EXIT(code);
598
599     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
600     if (code)
601         ERROR_EXIT(code);
602
603     AFS_SIGSET_CLEAR();
604     code = pthread_create(&pid, &tattr, ScanDumps, ptr);
605     AFS_SIGSET_RESTORE();
606 #else
607     code =
608         LWP_CreateProcess(ScanDumps, 32768, 1, ptr, "scandump process", &pid);
609 #endif
610
611   error_exit:
612     if (code) {
613         if (statusPtr)
614             deleteStatusNode(statusPtr);
615         if (ptr)
616             free(ptr);
617     }
618
619     return code;
620 }
621
622 /* STC_TCInfo
623  *      return information about the tape coordinator. Currently this
624  *      is just the version number of the interface
625  */
626
627 afs_int32
628 STC_TCInfo(struct rx_call *acid, struct tc_tcInfo *tciptr)
629 {
630     if (callPermitted(acid) == 0)
631         return (TC_NOTPERMITTED);
632
633     tciptr->tcVersion = CUR_BUTC_VERSION;
634     return (0);
635 }
636
637 /* STC_DeleteDump
638  */
639 afs_int32
640 STC_DeleteDump(struct rx_call *acid, afs_uint32 dumpID, afs_uint32 *taskId)
641 {
642     afs_int32 code = TC_BADTASK;        /* If not compiled -Dxbsa then fail */
643 #ifdef xbsa
644     struct deleteDumpIf *ptr = 0;
645     statusP statusPtr = 0;
646 #ifdef AFS_PTHREAD_ENV
647     pthread_t pid;
648     pthread_attr_t tattr;
649     AFS_SIGSET_DECL;
650 #else
651     PROCESS pid;
652 #endif
653 #endif
654
655     *taskId = 0;
656     if (!CONF_XBSA)
657         return (TC_BADTASK);    /* Only do if butc is started as XBSA */
658
659 #ifdef xbsa
660     code = 0;
661     if (callPermitted(acid) == 0)
662         return (TC_NOTPERMITTED);
663
664     ptr = (struct deleteDumpIf *)malloc(sizeof(*ptr));
665     if (!ptr)
666         ERROR_EXIT(TC_NOMEMORY);
667
668     *taskId = allocTaskId();
669     ptr->dumpID = dumpID;
670     ptr->taskId = *taskId;
671
672     statusPtr = createStatusNode();
673     if (!statusPtr)
674         ERROR_EXIT(TC_INTERNALERROR);
675
676     lock_Status();
677     statusPtr->taskId = *taskId;
678     statusPtr->lastPolled = time(0);
679     statusPtr->flags &= ~STARTING;
680     strncpy(statusPtr->taskName, "DeleteDump", sizeof(statusPtr->taskName));
681     unlock_Status();
682
683 #ifdef AFS_PTHREAD_ENV
684     code = pthread_attr_init(&tattr);
685     if (code)
686         ERROR_EXIT(code);
687
688     code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
689     if (code)
690         ERROR_EXIT(code);
691
692     AFS_SIGSET_CLEAR();
693     code = pthread_create(&pid, &tattr, DeleteDump, ptr);
694     AFS_SIGSET_RESTORE();
695 #else
696     code =
697         LWP_CreateProcess(DeleteDump, 32768, 1, ptr, "deletedump process",
698                           &pid);
699 #endif
700
701   error_exit:
702     if (code) {
703         if (statusPtr)
704             deleteStatusNode(statusPtr);
705         if (ptr)
706             free(ptr);
707     }
708 #endif /* xbsa */
709
710     return (code);
711 }
712