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