]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/smartall.c
Allow plugins to add drives to vss snapshot
[bacula/bacula] / bacula / src / lib / smartall.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29
30                          S M A R T A L L O C
31                         Smart Memory Allocator
32
33         Evolved   over   several  years,  starting  with  the  initial
34         SMARTALLOC code for AutoSketch in 1986, guided  by  the  Blind
35         Watchbreaker,  John  Walker.  Isolated in this general-purpose
36         form in  September  of  1989.   Updated  with  be  more  POSIX
37         compliant  and  to  include Web-friendly HTML documentation in
38         October  of  1998  by  the  same  culprit.    For   additional
39         information and the current version visit the Web page:
40
41                   http://www.fourmilab.ch/smartall/
42
43 */
44
45 #define _LOCKMGR_COMPLIANT
46
47 #include "bacula.h"
48 /* Use the real routines here */
49 #undef realloc
50 #undef calloc
51 #undef malloc
52 #undef free
53
54 /* We normally turn off debugging here.
55  *  If you want it, simply #ifdef all the
56  *  following off.
57  */
58 #ifdef no_debug_xxxxx
59 #undef Dmsg1
60 #undef Dmsg2
61 #undef Dmsg3
62 #undef Dmsg4
63 #define Dmsg1(l,f,a1)
64 #define Dmsg2(l,f,a1,a2)
65 #define Dmsg3(l,f,a1,a2,a3)
66 #define Dmsg4(l,f,a1,a2,a3,a4)
67 #endif
68
69
70 uint64_t sm_max_bytes = 0;
71 uint64_t sm_bytes = 0;
72 uint32_t sm_max_buffers = 0;
73 uint32_t sm_buffers = 0;
74
75 #ifdef SMARTALLOC
76
77 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
78
79 extern char my_name[];                /* daemon name */
80
81 #define EOS      '\0'              /* End of string sentinel */
82 #define sm_min(a, b) ((a) < (b) ? (a) : (b))
83
84 /*  Queue data structures  */
85
86 /*  Memory allocation control structures and storage.  */
87
88 struct abufhead {
89    struct b_queue abq;         /* Links on allocated queue */
90    uint32_t ablen;             /* Buffer length in bytes */
91    const char *abfname;        /* File name pointer */
92    uint32_t ablineno;          /* Line number of allocation */
93    bool abin_use;              /* set when malloced and cleared when free */
94 };
95
96 static struct b_queue abqueue = {    /* Allocated buffer queue */
97    &abqueue, &abqueue
98 };
99
100
101 static bool bufimode = false;   /* Buffers not tracked when True */
102
103 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
104
105
106 /*  SMALLOC  --  Allocate buffer, enqueing on the orphaned buffer
107                  tracking list.  */
108
109 static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
110 {
111    char *buf;
112
113    /* Note:  Unix  MALLOC  actually  permits  a zero length to be
114       passed and allocates a valid block with  zero  user  bytes.
115       Such  a  block  can  later  be expanded with realloc().  We
116       disallow this based on the belief that it's better to  make
117       a  special case and allocate one byte in the rare case this
118       is desired than to miss all the erroneous occurrences where
119       buffer length calculation code results in a zero.  */
120
121    ASSERT(nbytes > 0);
122
123    nbytes += HEAD_SIZE + 1;
124    if ((buf = (char *)malloc(nbytes)) != NULL) {
125       struct abufhead *head = (struct abufhead *)buf;
126       P(mutex);
127       /* Enqueue buffer on allocated list */
128       qinsert(&abqueue, (struct b_queue *) buf);
129       head->ablen = nbytes;
130       head->abfname = bufimode ? NULL : fname;
131       head->ablineno = (uint32_t)lineno;
132       head->abin_use = true;
133       /* Emplace end-clobber detector at end of buffer */
134       buf[nbytes - 1] = (uint8_t)((((intptr_t) buf) & 0xFF) ^ 0xC5);
135       buf += HEAD_SIZE;  /* Increment to user data start */
136       if (++sm_buffers > sm_max_buffers) {
137          sm_max_buffers = sm_buffers;
138       }
139       sm_bytes += nbytes;
140       if (sm_bytes > sm_max_bytes) {
141          sm_max_bytes = sm_bytes;
142       }
143       V(mutex);
144    } else {
145       Emsg0(M_ABORT, 0, _("Out of memory\n"));
146    }
147    Dmsg4(1150, "smalloc %d at %p from %s:%d\n", nbytes, buf, fname, lineno);
148 #if    SMALLOC_SANITY_CHECK > 0
149    if (sm_bytes > SMALLOC_SANITY_CHECK) {
150       Emsg0(M_ABORT, 0, _("Too much memory used."));
151    }
152 #endif
153    return (void *)buf;
154 }
155
156 /*  SM_NEW_OWNER -- Update the File and line number for a buffer
157                     This is to accomodate mem_pool. */
158
159 void sm_new_owner(const char *fname, int lineno, char *buf)
160 {
161    buf -= HEAD_SIZE;  /* Decrement to header */
162    ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
163    ((struct abufhead *)buf)->ablineno = (uint32_t) lineno;
164    ((struct abufhead *)buf)->abin_use = true;
165    return;
166 }
167
168 /*  SM_FREE  --  Update free pool availability.  FREE is never called
169                  except  through  this interface or by actuallyfree().
170                  free(x)  is  defined  to  generate  a  call  to  this
171                  routine.  */
172
173 void sm_free(const char *file, int line, void *fp)
174 {
175    char *cp = (char *) fp;
176    struct b_queue *qp;
177    uint32_t lineno = line;
178
179    if (cp == NULL) {
180       Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, lineno);
181    }
182
183    cp -= HEAD_SIZE;
184    qp = (struct b_queue *)cp;
185    struct abufhead *head = (struct abufhead *)cp;
186
187    P(mutex);
188    Dmsg4(1150, "sm_free %d at %p from %s:%d\n",
189          head->ablen, fp,
190          head->abfname, head->ablineno);
191
192    if (!head->abin_use) {
193       V(mutex);
194       Emsg2(M_ABORT, 0, _("double free from %s:%d\n"), file, lineno);
195    }
196    head->abin_use = false;
197
198    /* The following assertions will catch virtually every release
199       of an address which isn't an allocated buffer. */
200    if (qp->qnext->qprev != qp) {
201       V(mutex);
202       Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, lineno);
203    }
204    if (qp->qprev->qnext != qp) {
205       V(mutex);
206       Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, lineno);
207    }
208
209    /* The following assertion detects storing off the  end  of  the
210       allocated  space in the buffer by comparing the end of buffer
211       checksum with the address of the buffer.  */
212
213    if (((unsigned char *)cp)[head->ablen - 1] != ((((intptr_t) cp) & 0xFF) ^ 0xC5)) {
214       V(mutex);
215       Dmsg4(0, "Overrun buffer: len=%d addr=%p allocated: %s:%d\n",
216          head->ablen, fp,
217          head->abfname, head->ablineno);
218       Emsg2(M_ABORT, 0, _("Buffer overrun called from %s:%d\n"), file, line);
219    }
220    if (sm_buffers > 0) {
221       sm_buffers--;
222       sm_bytes -= head->ablen;
223    }
224
225    qdchain(qp);
226    V(mutex);
227
228    /* Now we wipe the contents of  the  just-released  buffer  with
229       "designer  garbage"  (Duff  Kurland's  phrase) of alternating
230       bits.  This is intended to ruin the day for any miscreant who
231       attempts to access data through a pointer into storage that's
232       been previously released.
233
234       Modified, kes May, 2007 to not zap the header. This allows us
235       to check the in_use bit and detect doubly freed buffers.
236    */
237
238    memset(cp+HEAD_SIZE, 0xAA, (int)(head->ablen - HEAD_SIZE));
239
240    free(cp);
241 }
242
243 /*  SM_MALLOC  --  Allocate buffer.  NULL is returned if no memory
244                    was available.  */
245
246 void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
247 {
248    void *buf;
249
250    if ((buf = smalloc(fname, lineno, nbytes)) != NULL) {
251
252       /* To catch sloppy code that assumes  buffers  obtained  from
253          malloc()  are  zeroed,  we  preset  the buffer contents to
254          "designer garbage" consisting of alternating bits.  */
255
256       memset(buf, 0x55, (int) nbytes);
257    } else {
258       Emsg0(M_ABORT, 0, _("Out of memory\n"));
259    }
260    return buf;
261 }
262
263 /*  SM_CALLOC  --  Allocate an array and clear it to zero.  */
264
265 void *sm_calloc(const char *fname, int lineno,
266                 unsigned int nelem, unsigned int elsize)
267 {
268    void *buf;
269
270    if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) {
271       memset(buf, 0, (int) (nelem * elsize));
272    } else {
273       Emsg0(M_ABORT, 0, _("Out of memory\n"));
274    }
275    return buf;
276 }
277
278 /*  SM_REALLOC  --  Adjust the size of a  previously  allocated  buffer.
279                     Note  that  the trick of "resurrecting" a previously
280                     freed buffer with realloc() is NOT supported by this
281                     function.   Further, because of the need to maintain
282                     our control storage, SM_REALLOC must always allocate
283                     a  new  block  and  copy  the data in the old block.
284                     This may result in programs which make heavy use  of
285                     realloc() running much slower than normally.  */
286
287 void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
288 {
289    unsigned osize;
290    void *buf;
291    char *cp = (char *) ptr;
292
293    Dmsg4(1400, "sm_realloc %s:%d %p %d\n", fname, (uint32_t)lineno, ptr, size);
294    if (size <= 0) {
295       e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
296    }
297
298    /*  If  the  old  block  pointer  is  NULL, treat realloc() as a
299       malloc().  SVID is silent  on  this,  but  many  C  libraries
300       permit this.  */
301    if (ptr == NULL) {
302       return sm_malloc(fname, lineno, size);
303    }
304
305    /* If the old and new sizes are the same, be a nice guy and just
306       return the buffer passed in.  */
307    cp -= HEAD_SIZE;
308    struct abufhead *head = (struct abufhead *)cp;
309    osize = head->ablen - (HEAD_SIZE + 1);
310    if (size == osize) {
311       return ptr;
312    }
313
314    /* Sizes differ.  Allocate a new buffer of the  requested  size.
315       If  we  can't  obtain  such a buffer, act as defined in SVID:
316       return NULL from  realloc()  and  leave  the  buffer  in  PTR
317       intact.  */
318
319 // sm_buffers--;
320 // sm_bytes -= head->ablen;
321
322    if ((buf = smalloc(fname, lineno, size)) != NULL) {
323       memcpy(buf, ptr, (int)sm_min(size, osize));
324       /* If the new buffer is larger than the old, fill the balance
325          of it with "designer garbage". */
326       if (size > osize) {
327          memset(((char *) buf) + osize, 0x55, (int) (size - osize));
328       }
329
330       /* All done.  Free and dechain the original buffer. */
331       sm_free(fname, lineno, ptr);
332    }
333    Dmsg4(4150, _("sm_realloc %d at %p from %s:%d\n"), size, buf, fname, (uint32_t)lineno);
334    return buf;
335 }
336
337 /*  ACTUALLYMALLOC  --  Call the system malloc() function to obtain
338                         storage which will eventually be released
339                         by system or library routines not compiled
340                         using SMARTALLOC.  */
341
342 void *actuallymalloc(unsigned int size)
343 {
344    return malloc(size);
345 }
346
347 /*  ACTUALLYCALLOC  --  Call the system calloc() function to obtain
348                         storage which will eventually be released
349                         by system or library routines not compiled
350                         using SMARTALLOC.  */
351
352 void *actuallycalloc(unsigned int nelem, unsigned int elsize)
353 {
354    return calloc(nelem, elsize);
355 }
356
357 /*  ACTUALLYREALLOC  --  Call the system realloc() function to obtain
358                          storage which will eventually be released
359                          by system or library routines not compiled
360                          using SMARTALLOC.  */
361
362 void *actuallyrealloc(void *ptr, unsigned int size)
363 {
364    Dmsg2(1400, "Actuallyrealloc %p %d\n", ptr, size);
365    return realloc(ptr, size);
366 }
367
368 /*  ACTUALLYFREE  --  Interface to system free() function to release
369                       buffers allocated by low-level routines. */
370
371 void actuallyfree(void *cp)
372 {
373    free(cp);
374 }
375
376 /*  SM_DUMP  --  Print orphaned buffers (and dump them if BUFDUMP is
377  *               True).
378  */
379 void sm_dump(bool bufdump, bool in_use) 
380 {
381    struct abufhead *ap;
382
383    P(mutex);
384
385    ap = (struct abufhead *)abqueue.qnext;
386
387    while (ap != (struct abufhead *) &abqueue) {
388
389       if ((ap == NULL) ||
390           (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
391           (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
392          Pmsg1(0, _(
393             "\nOrphaned buffers exist.  Dump terminated following\n"
394             "  discovery of bad links in chain of orphaned buffers.\n"
395             "  Buffer address with bad links: %p\n"), ap);
396          break;
397       }
398
399       if (ap->abfname != NULL) {
400          char errmsg[500];
401          uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
402          char *cp = ((char *)ap) + HEAD_SIZE;
403
404          Pmsg6(0, "%s buffer: %s %d bytes at %p from %s:%d\n", 
405             in_use?"In use":"Orphaned",
406             my_name, memsize, cp, ap->abfname, ap->ablineno);
407          if (bufdump) {
408             char buf[20];
409             unsigned llen = 0;
410
411             errmsg[0] = EOS;
412             while (memsize) {
413                if (llen >= 16) {
414                   bstrncat(errmsg, "\n", sizeof(errmsg));
415                   llen = 0;
416                   Pmsg1(0, "%s", errmsg);
417                   errmsg[0] = EOS;
418                }
419                bsnprintf(buf, sizeof(buf), " %02X",
420                   (*cp++) & 0xFF);
421                bstrncat(errmsg, buf, sizeof(errmsg));
422                llen++;
423                memsize--;
424             }
425             Pmsg1(0, "%s\n", errmsg);
426          }
427       }
428       ap = (struct abufhead *) ap->abq.qnext;
429    }
430    V(mutex);
431 }
432
433 #undef sm_check
434 /*  SM_CHECK --  Check the buffers and dump if any damage exists. */
435 void sm_check(const char *fname, int lineno, bool bufdump)
436 {
437    if (!sm_check_rtn(fname, lineno, bufdump)) {
438       Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
439             fname, (uint32_t)lineno);
440    }
441 }
442
443 #undef sm_check_rtn
444 /*  SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */
445 int sm_check_rtn(const char *fname, int lineno, bool bufdump)
446 {
447    struct abufhead *ap;
448    int bad, badbuf = 0;
449
450    P(mutex);
451    ap = (struct abufhead *) abqueue.qnext;
452    while (ap != (struct abufhead *)&abqueue) {
453       bad = 0;
454       if (ap != NULL) {
455          if (ap->abq.qnext->qprev != (struct b_queue *)ap) {
456             bad = 0x1;
457          }
458          if (ap->abq.qprev->qnext != (struct b_queue *)ap) {
459             bad |= 0x2;
460          }
461          if (((unsigned char *) ap)[((struct abufhead *)ap)->ablen - 1] !=
462               ((((intptr_t) ap) & 0xFF) ^ 0xC5)) {
463             bad |= 0x4;
464          }
465       } else {
466          bad = 0x8;
467       }
468       badbuf |= bad;
469       if (bad) {
470          Pmsg2(0, 
471             _("\nDamaged buffers found at %s:%d\n"), fname, (uint32_t)lineno);
472
473          if (bad & 0x1) {
474             Pmsg0(0,  _("  discovery of bad prev link.\n"));
475          }
476          if (bad & 0x2) {
477             Pmsg0(0, _("  discovery of bad next link.\n"));
478          }
479          if (bad & 0x4) {
480             Pmsg0(0, _("  discovery of data overrun.\n"));
481          }
482          if (bad & 0x8) {
483             Pmsg0(0, _("  NULL pointer.\n"));
484          }
485
486          if (!ap) {
487             goto get_out;
488          }
489          Pmsg1(0, _("  Buffer address: %p\n"), ap);
490
491          if (ap->abfname != NULL) {
492             uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
493             char errmsg[80];
494
495             Pmsg4(0, 
496               _("Damaged buffer:  %6u bytes allocated at line %d of %s %s\n"),
497                memsize, ap->ablineno, my_name, ap->abfname
498             );
499             if (bufdump) {
500                unsigned llen = 0;
501                char *cp = ((char *) ap) + HEAD_SIZE;
502
503                errmsg[0] = EOS;
504                while (memsize) {
505                   if (llen >= 16) {
506                      strcat(errmsg, "\n");
507                      llen = 0;
508                      Pmsg1(0, "%s", errmsg);
509                      errmsg[0] = EOS;
510                   }
511                   if (*cp < 0x20) {
512                      sprintf(errmsg + strlen(errmsg), " %02X",
513                         (*cp++) & 0xFF);
514                   } else {
515                      sprintf(errmsg + strlen(errmsg), " %c ",
516                         (*cp++) & 0xFF);
517                   }
518                   llen++;
519                   memsize--;
520                }
521                Pmsg1(0, "%s\n", errmsg);
522             }
523          }
524       }
525       ap = (struct abufhead *)ap->abq.qnext;
526    }
527 get_out:
528    V(mutex);
529    return badbuf ? 0 : 1;
530 }
531
532
533 /*  SM_STATIC  --  Orphaned buffer detection can be disabled  (for  such
534                    items  as buffers allocated during initialisation) by
535                    calling   sm_static(1).    Normal   orphaned   buffer
536                    detection  can be re-enabled with sm_static(0).  Note
537                    that all the other safeguards still apply to  buffers
538                    allocated  when  sm_static(1)  mode is in effect.  */
539
540 void sm_static(bool mode)
541 {
542    bufimode = mode;
543 }
544
545 /*
546  * Here we overload C++'s global new and delete operators
547  *  so that the memory is allocated through smartalloc.
548  */
549
550 #ifdef xxx
551 void * operator new(size_t size)
552 {
553 // Dmsg1(000, "new called %d\n", size);
554    return sm_malloc(__FILE__, __LINE__, size);
555 }
556
557 void operator delete(void *buf)
558 {
559 // Dmsg1(000, "free called %p\n", buf);
560    sm_free(__FILE__, __LINE__, buf);
561 }
562 #endif
563
564 #endif