Bug Summary

File:bucoord/dump.c
Location:line 82, column 24
Description:Call to 'malloc' has an allocation size of 0 bytes

Annotated Source Code

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/*
11 * ALL RIGHTS RESERVED
12 */
13
14#include <afsconfig.h>
15#include <afs/param.h>
16
17#include <roken.h>
18
19#include <afs/cmd.h>
20#include <lwp.h>
21#include <rx/rx.h>
22#include <afs/bubasics.h>
23#include <afs/butc.h>
24#include <afs/com_err.h>
25#include <lock.h> /* for checking TC_ABORTFAILED. PA */
26#include <afs/tcdata.h> /* for checking TC_ABORTFAILED. PA */
27#include <afs/butc.h>
28
29#include "bc.h"
30#include "error_macros.h"
31#include "bucoord_internal.h"
32#include "bucoord_prototypes.h"
33
34struct bc_dumpTask bc_dumpTasks[BC_MAXSIMDUMPS64];
35
36extern char *whoami;
37
38extern afs_int32 lastTaskCode;
39
40#define HOSTADDR(sockaddr)(sockaddr)->sin_addr.s_addr (sockaddr)->sin_addr.s_addr
41
42/* bc_Dumper
43 * called (indirectly) to make a dump
44 * entry:
45 * aindex - index into dumpTask array, contains all the information
46 * relevant to the dump
47 */
48int
49bc_Dumper(int aindex)
50{
51 struct rx_connection *tconn;
52 struct bc_volumeDump *tde;
53 afs_int32 count, port;
54 struct tc_dumpDesc *volDesc = 0;
55 struct tc_dumpArray volArray;
56 char *baseNamePtr;
57 statusP statusPtr;
58
59 struct tc_dumpInterface dumpInterface;
60 struct tc_dumpInterface *tcdiPtr = &dumpInterface;
61 struct bc_dumpTask *dumpTaskPtr;
62
63 afs_int32 code = 0;
64
65 dumpTaskPtr = &bc_dumpTasks[aindex];
66
67 if (!dumpTaskPtr->portOffset || (dumpTaskPtr->portCount == 0))
1
Taking true branch
68 port = 0;
69 else
70 port = dumpTaskPtr->portOffset[0];
71
72 code = ConnectButc(dumpTaskPtr->config, port, &tconn);
73 if (code)
2
Taking false branch
74 return (code);
75
76 /* count number of volumes to be dumped and
77 * build array of volumes to be sent to backup system
78 */
79 for (count = 0, tde = dumpTaskPtr->volumes; tde;
3
Loop condition is false. Execution continues on line 82
80 tde = tde->next, count++);
81 volDesc =
82 (struct tc_dumpDesc *)malloc(count * sizeof(struct tc_dumpDesc));
4
Call to 'malloc' has an allocation size of 0 bytes
83 if (!volDesc) {
84 afs_com_err(whoami, BC_NOMEM(156288003L), NULL((void *)0));
85 ERROR(BC_NOMEM)do { code = (156288003L); goto error_exit; } while (0);
86 }
87
88 for (count = 0, tde = dumpTaskPtr->volumes; tde; tde = tde->next, count++) {
89 strcpy(volDesc[count].name, tde->name);
90 volDesc[count].vid = tde->vid;
91 volDesc[count].vtype = tde->volType;
92 volDesc[count].partition = tde->partition;
93 volDesc[count].hostAddr = HOSTADDR(&tde->server)(&tde->server)->sin_addr.s_addr; /* the internet address */
94 volDesc[count].date = tde->date;
95 volDesc[count].cloneDate = tde->cloneDate; /* Not yet known */
96 }
97
98 volArray.tc_dumpArray_len = count; /* element count */
99 volArray.tc_dumpArray_val = volDesc; /* and data */
100
101 baseNamePtr = tailCompPtr(dumpTaskPtr->dumpName);
102
103 /* setup the interface structure */
104 memset(tcdiPtr, 0, sizeof(*tcdiPtr));
105
106 /* general */
107 strcpy(tcdiPtr->dumpPath, dumpTaskPtr->dumpName);
108 strcpy(tcdiPtr->volumeSetName, dumpTaskPtr->volSetName);
109
110 /* tapeset */
111 strcpy(tcdiPtr->tapeSet.format, dumpTaskPtr->volSetName);
112 strcat(tcdiPtr->tapeSet.format, ".");
113 strcat(tcdiPtr->tapeSet.format, baseNamePtr);
114 strcat(tcdiPtr->tapeSet.format, ".%d");
115 tcdiPtr->tapeSet.a = 1;
116 tcdiPtr->tapeSet.b = 1;
117 tcdiPtr->tapeSet.maxTapes = 1000000000;
118 tcdiPtr->tapeSet.expDate = dumpTaskPtr->expDate; /* PA */
119 tcdiPtr->tapeSet.expType = dumpTaskPtr->expType;
120
121 /* construct dump set name */
122 strcpy(tcdiPtr->dumpName, dumpTaskPtr->volSetName);
123 strcat(tcdiPtr->dumpName, ".");
124 strcat(tcdiPtr->dumpName, baseNamePtr);
125
126 tcdiPtr->parentDumpId = dumpTaskPtr->parentDumpID;
127 tcdiPtr->dumpLevel = dumpTaskPtr->dumpLevel;
128 tcdiPtr->doAppend = dumpTaskPtr->doAppend;
129
130 /* start the dump on the tape coordinator */
131 printf("Starting dump\n");
132 code = TC_PerformDump(tconn, tcdiPtr, &volArray, &dumpTaskPtr->dumpID);
133 if (code) {
134 afs_com_err(whoami, code, "; Failed to start dump");
135 ERROR(code)do { code = code; goto error_exit; } while (0);
136 }
137
138 afs_com_err(whoami, 0, "Task %u: Dump (%s)", dumpTaskPtr->dumpID,
139 tcdiPtr->dumpName);
140
141 /* create status monitor block */
142 statusPtr = createStatusNode();
143 lock_Status();
144 statusPtr->taskId = dumpTaskPtr->dumpID;
145 statusPtr->port = port;
146 statusPtr->jobNumber = bc_jobNumber();
147 statusPtr->volsTotal = volArray.tc_dumpArray_len;
148 statusPtr->flags &= ~STARTING0x1;
149 sprintf(statusPtr->taskName, "Dump (%s.%s)", dumpTaskPtr->volSetName,
150 baseNamePtr);
151 unlock_Status();
152
153 error_exit:
154 /* locally allocated resources */
155 if (volDesc)
156 free(volDesc);
157
158 if (tconn)
159 rx_DestroyConnection(tconn);
160
161 return (code);
162}
163
164/* freeDumpTaskVolumeList
165 * free the list of volumes used for dumps
166 */
167
168void
169freeDumpTaskVolumeList(struct bc_volumeDump *vdptr)
170{
171 struct bc_volumeDump *nextVdPtr;
172
173 while (vdptr != 0) {
174 nextVdPtr = vdptr->next;
175
176 if (vdptr->name)
177 free(vdptr->name);
178 free(vdptr);
179
180 vdptr = nextVdPtr;
181 }
182}
183
184/* bc_DmpRstStart
185 * The other half of the dump/restore create process call. In bc_StartDmpRst,
186 * we allocated a dumpTask entry. Here we do the task and then free the entry.
187 */
188void *
189bc_DmpRstStart(void *param)
190{
191 afs_int32 aindex = (intptr_t)param;
192 struct bc_dumpTask *tdump;
193 afs_int32 code;
194
195 tdump = &bc_dumpTasks[aindex];
196
197 code = (tdump->callProc) (aindex);
198 if (code)
199 lastTaskCode = code;
200
201 /* Cleanup allocated data structures */
202 freeDumpTaskVolumeList(tdump->volumes);
203 tdump->dumpID = 0;
204 if (tdump->dumpName)
205 free(tdump->dumpName);
206 if (tdump->newExt)
207 free(tdump->newExt);
208 if (tdump->volSetName)
209 free(tdump->volSetName);
210 if (tdump->portOffset)
211 free(tdump->portOffset);
212 tdump->flags &= ~BC_DI_INUSE1;
213
214 return (void *)(intptr_t)code;
215}
216
217/* bc_StartDmpRst
218 * function to start dump running. Packages the relevant information
219 * (from params) into any free dumpTask structure (globally allocated),
220 * and then invokes bc_DmpRstStart to do the work, passing it a single
221 * parameter, the index into the dumpTask array.
222 *
223 * entry:
224 * aconfig - normally is bc_globalConfig
225 * aproc - bc_Dumper for doing dumps
226 * bc_Restorer for doing restores
227 */
228
229int
230bc_StartDmpRst(struct bc_config *aconfig, char *adname, char *avname,
231 struct bc_volumeDump *avolsToDump,
232 struct sockaddr_in *adestServer,
233 afs_int32 adestPartition, afs_int32 afromDate, char *anewExt,
234 int aoldFlag, afs_int32 aparent, afs_int32 alevel,
235 int (*aproc) (int), afs_int32 *ports, afs_int32 portCount,
236 struct bc_dumpSchedule *dsptr, int append, int dontExecute)
237{
238 int i;
239 afs_int32 code;
240 PROCESS junk;
241
242 for (i = 0; i < BC_MAXSIMDUMPS64; i++)
243 if (!(bc_dumpTasks[i].flags & BC_DI_INUSE1))
244 break;
245
246 if (i >= BC_MAXSIMDUMPS64) {
247 afs_com_err(whoami, BC_NOTLOCKED(156288013L),
248 "All of the dump/restore slots are in use, try again later");
249 return (BC_NOTLOCKED(156288013L));
250 }
251
252 memset(&bc_dumpTasks[i], 0, sizeof(struct bc_dumpTask));
253 bc_dumpTasks[i].callProc = aproc;
254 bc_dumpTasks[i].config = aconfig;
255 bc_dumpTasks[i].volumes = avolsToDump;
256 bc_dumpTasks[i].flags = BC_DI_INUSE1;
257 bc_dumpTasks[i].dumpName = bc_CopyString(adname);
258 bc_dumpTasks[i].volSetName = bc_CopyString(avname);
259 bc_dumpTasks[i].newExt = bc_CopyString(anewExt);
260 bc_dumpTasks[i].dumpLevel = alevel;
261 bc_dumpTasks[i].parentDumpID = aparent;
262 bc_dumpTasks[i].oldFlag = aoldFlag;
263 bc_dumpTasks[i].fromDate = afromDate;
264 bc_dumpTasks[i].destPartition = adestPartition;
265 bc_dumpTasks[i].portOffset = ports;
266 bc_dumpTasks[i].portCount = portCount;
267 bc_dumpTasks[i].doAppend = append;
268 bc_dumpTasks[i].dontExecute = dontExecute;
269
270 if (dsptr) {
271 /* This should be specified for dumps, but will be 0 for restores */
272 bc_dumpTasks[i].expDate = dsptr->expDate;
273 bc_dumpTasks[i].expType = dsptr->expType;
274 }
275 if (adestServer)
276 memcpy(&bc_dumpTasks[i].destServer, adestServer,
277 sizeof(struct sockaddr_in));
278 else
279 memset(&bc_dumpTasks[i].destServer, 0, sizeof(struct sockaddr_in));
280
281 code =
282 LWP_CreateProcess(bc_DmpRstStart, 20480, LWP_NORMAL_PRIORITY(4 -2),
283 (void *)(intptr_t)i, "helper", &junk);
284 if (code) {
285 bc_HandleMisc(code);
286 afs_com_err(whoami, code, "; Can't start thread");
287
288 /* Cleanup allocated data structures */
289 freeDumpTaskVolumeList(bc_dumpTasks[i].volumes);
290 bc_dumpTasks[i].dumpID = 0;
291 if (bc_dumpTasks[i].dumpName)
292 free(bc_dumpTasks[i].dumpName);
293 if (bc_dumpTasks[i].newExt)
294 free(bc_dumpTasks[i].newExt);
295 if (bc_dumpTasks[i].volSetName)
296 free(bc_dumpTasks[i].volSetName);
297 if (bc_dumpTasks[i].portOffset)
298 free(bc_dumpTasks[i].portOffset);
299 bc_dumpTasks[i].flags &= ~BC_DI_INUSE1;
300 return (code);
301 }
302
303 return 0;
304}
305
306#ifdef notdef
307/* bc_FindDumpSlot
308 * Returns the dump slot of the dump with dumpID
309 * entry:
310 * dumpID - id to look for
311 * port - portoffset for tape coordinator
312 * exit:
313 * 0-n - i.e. 0 or positive number, is the dump slot
314 * -1 - failed to find dumpID
315 */
316
317afs_int32
318bc_FindDumpSlot(afs_int32 dumpID, afs_int32 port)
319{
320 int i;
321
322 for (i = 0; i < BC_MAXSIMDUMPS64; i++) {
323 if ((bc_dumpTasks[i].flags & BC_DI_INUSE1)
324 && (bc_dumpTasks[i].dumpID == dumpID)
325 && ((afs_int32) bc_dumpTasks[i].portOffset == port)) {
326 return (i);
327 }
328 }
329 return (-1);
330}
331#endif
332
333/* bc_LabelTape
334 * opens a connection to the tape coordinator and requests that it
335 * label a tape
336 */
337
338int
339bc_LabelTape(char *afsname, char *pname, afs_int32 size,
340 struct bc_config *config, afs_int32 port)
341{
342 struct rx_connection *tconn;
343 afs_int32 code = 0;
344 struct tc_tapeLabel label;
345 statusP statusPtr;
346 afs_uint32 taskId;
347
348 code = ConnectButc(config, port, &tconn);
349 if (code)
350 return (code);
351
352 memset(&label, 0, sizeof(label));
353 if (afsname)
354 strcpy(label.afsname, afsname);
355 if (pname)
356 strcpy(label.pname, (strcmp(pname, "") ? pname : "<NULL>"));
357 label.size = size;
358
359 code = TC_LabelTape(tconn, &label, &taskId);
360 if (code) {
361 afs_com_err(whoami, code, "; Failed to start labeltape");
362 return (code);
363 }
364
365 /* create status monitor block */
366 statusPtr = createStatusNode();
367 lock_Status();
368 statusPtr->taskId = taskId;
369 statusPtr->port = port;
370 statusPtr->jobNumber = bc_jobNumber();
371 /* statusPtr->flags |= SILENT; *//* don't report termination */
372 statusPtr->flags &= ~STARTING0x1; /* ok to examine */
373
374 sprintf(statusPtr->taskName, "Labeltape (%s)",
375 (pname ? pname : (afsname ? afsname : "<NULL>")));
376 unlock_Status();
377
378 return 0;
379}
380
381/* bc_ReadLabel
382 * open a connection to the tape coordinator and read the label on
383 * a tape
384 */
385
386int
387bc_ReadLabel(struct bc_config *config, afs_int32 port)
388{
389 struct rx_connection *tconn;
390 struct tc_tapeLabel label;
391 afs_uint32 taskId;
392 afs_int32 code = 0;
393 char *tname = 0;
394
395 code = ConnectButc(config, port, &tconn);
396 if (code)
397 return (code);
398
399 memset(&label, 0, sizeof(label));
400 code = TC_ReadLabel(tconn, &label, &taskId);
401 if (code) {
402 if (code == BUTM_NOLABEL(156568851L)) {
403 printf("Tape read was unlabelled\n");
404 return 0;
405 }
406 afs_com_err(whoami, code, "; Failed to start readlabel");
407 return (code);
408 }
409
410 if (strcmp(label.pname, ""))
411 tname = label.pname;
412 else if (strcmp(label.afsname, ""))
413 tname = label.afsname;
414
415 if (!tname) {
416 printf("Tape read was labelled : <NULL> size : %u\n", label.size);
417 } else if (!label.tapeId) {
418 printf("Tape read was labelled : %s size : %lu Kbytes\n", tname,
419 (long unsigned int) label.size);
420 } else {
421 printf("Tape read was labelled : %s (%lu) size : %lu Kbytes\n", tname,
422 (long unsigned int) label.tapeId, (long unsigned int) label.size);
423 }
424
425 return 0;
426}
427
428int
429bc_ScanDumps(struct bc_config *config, afs_int32 dbAddFlag, afs_int32 port)
430{
431 struct rx_connection *tconn;
432 statusP statusPtr;
433 afs_uint32 taskId;
434 afs_int32 code = 0;
435
436 code = ConnectButc(config, port, &tconn);
437 if (code)
438 return (code);
439
440 code = TC_ScanDumps(tconn, dbAddFlag, &taskId);
441 if (code) {
442 afs_com_err(whoami, code, "; Failed to start scantape");
443 return (code);
444 }
445
446 /* create status monitor block */
447 statusPtr = createStatusNode();
448 lock_Status();
449 statusPtr->taskId = taskId;
450 statusPtr->port = port;
451 statusPtr->jobNumber = bc_jobNumber();
452 statusPtr->flags &= ~STARTING0x1; /* ok to examine */
453 sprintf(statusPtr->taskName, "Scantape");
454 unlock_Status();
455
456 return (0);
457}
458
459/*************/
460/* utilities */
461/*************/
462
463/* get a connection to the tape controller */
464afs_int32
465bc_GetConn(struct bc_config *aconfig, afs_int32 aport,
466 struct rx_connection **tconn)
467{
468 afs_uint32 host;
469 unsigned short port;
470 static struct rx_securityClass *rxsc;
471 struct bc_hostEntry *te;
472
473 *tconn = (struct rx_connection *)0;
474
475 /* use non-secure connections to butc */
476 if (!rxsc)
477 rxsc = rxnull_NewClientSecurityObject();
478 if (!rxsc || !aconfig)
479 return (-1);
480
481 for (te = aconfig->tapeHosts; te; te = te->next) {
482 if (te->portOffset == aport) {
483 /* found the right port */
484 host = te->addr.sin_addr.s_addr;
485 if (!host)
486 return (BC_NOHOSTENTRY(156288015L)); /* gethostbyname in bc_ParseHosts failed */
487
488 port = htons(BC_TAPEPORT + aport)(__builtin_constant_p(7025 + aport) ? (__uint16_t)(((__uint16_t
)(7025 + aport)) << 8 | ((__uint16_t)(7025 + aport)) >>
8) : __bswap16_var(7025 + aport))
;
489
490 /* servers is 1; sec index is 0 */
491 *tconn = rx_NewConnection(host, port, 1, rxsc, 0);
492 return ((*tconn ? 0 : -1));
493 }
494 }
495 return (BC_NOHOSTENTRY(156288015L));
496}
497
498/* CheckTCVersion
499 * make sure we are talking to a compatible butc process.
500 * exit:
501 * 0 - ok
502 * -1 - not compatible
503 */
504
505int
506CheckTCVersion(struct rx_connection *tconn)
507{
508 struct tc_tcInfo tci;
509 afs_int32 code;
510
511 code = TC_TCInfo(tconn, &tci);
512 if (code)
513 return (code);
514
515 if (tci.tcVersion != CUR_BUTC_VERSION3)
516 return (BC_VERSIONFAIL(156288012L));
517
518 return 0;
519}
520
521int
522ConnectButc(struct bc_config *config, afs_int32 port,
523 struct rx_connection **tconn)
524{
525 afs_int32 code;
526
527 code = bc_GetConn(config, port, tconn);
528 if (code) {
529 afs_com_err(whoami, code,
530 "; Can't connect to tape coordinator at port %d", port);
531 return (code);
532 }
533
534 code = CheckTCVersion(*tconn);
535 if (code) {
536 rx_DestroyConnection(*tconn);
537
538 if (code == BC_VERSIONFAIL(156288012L))
539 afs_com_err(whoami, code,
540 "; Backup and butc are not the same version");
541 else
542 afs_com_err(whoami, code,
543 "; Can't access tape coordinator at port %d", port);
544
545 return (code);
546 }
547
548 return (0);
549}