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