Changeset 745 for trunk/server/source3/lib/util_tdb.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/lib/util_tdb.c
r414 r745 21 21 22 22 #include "includes.h" 23 #include "system/filesys.h" 24 #include "util_tdb.h" 25 23 26 #undef malloc 24 27 #undef realloc … … 35 38 ****************************************************************/ 36 39 37 static void gotalarm_sig( void)40 static void gotalarm_sig(int signum) 38 41 { 39 42 gotalarm = 1; … … 51 54 52 55 if (timeout) { 53 CatchSignal(SIGALRM, SIGNAL_CASTgotalarm_sig);56 CatchSignal(SIGALRM, gotalarm_sig); 54 57 tdb_setalarm_sigptr(tdb, &gotalarm); 55 58 alarm(timeout); … … 64 67 alarm(0); 65 68 tdb_setalarm_sigptr(tdb, NULL); 66 CatchSignal(SIGALRM, SIG NAL_CAST SIG_IGN);69 CatchSignal(SIGALRM, SIG_IGN); 67 70 if (gotalarm && (ret == -1)) { 68 71 DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n", … … 482 485 } 483 486 484 /*485 Log tdb messages via DEBUG().486 */487 static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,488 const char *format, ...) PRINTF_ATTRIBUTE(3,4);489 490 static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,491 const char *format, ...)492 {493 va_list ap;494 char *ptr = NULL;495 int debuglevel = 0;496 int ret;497 498 switch (level) {499 case TDB_DEBUG_FATAL:500 debuglevel = 0;501 break;502 case TDB_DEBUG_ERROR:503 debuglevel = 1;504 break;505 case TDB_DEBUG_WARNING:506 debuglevel = 2;507 break;508 case TDB_DEBUG_TRACE:509 debuglevel = 5;510 break;511 default:512 debuglevel = 0;513 }514 515 va_start(ap, format);516 ret = vasprintf(&ptr, format, ap);517 va_end(ap);518 519 if (ret != -1) {520 const char *name = tdb_name(tdb);521 DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr));522 free(ptr);523 }524 }525 526 static struct tdb_wrap *tdb_list;527 528 /* destroy the last connection to a tdb */529 static int tdb_wrap_destructor(struct tdb_wrap *w)530 {531 tdb_close(w->tdb);532 DLIST_REMOVE(tdb_list, w);533 return 0;534 }535 536 /*537 wrapped connection to a tdb database538 to close just talloc_free() the tdb_wrap pointer539 */540 struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,541 const char *name, int hash_size, int tdb_flags,542 int open_flags, mode_t mode)543 {544 struct tdb_wrap *w;545 struct tdb_logging_context log_ctx;546 log_ctx.log_fn = tdb_wrap_log;547 548 if (!lp_use_mmap())549 tdb_flags |= TDB_NOMMAP;550 551 for (w=tdb_list;w;w=w->next) {552 if (strcmp(name, w->name) == 0) {553 /*554 * Yes, talloc_reference is exactly what we want555 * here. Otherwise we would have to implement our own556 * reference counting.557 */558 return talloc_reference(mem_ctx, w);559 }560 }561 562 w = talloc(mem_ctx, struct tdb_wrap);563 if (w == NULL) {564 return NULL;565 }566 567 if (!(w->name = talloc_strdup(w, name))) {568 talloc_free(w);569 return NULL;570 }571 572 if ((hash_size == 0) && (name != NULL)) {573 const char *base = strrchr_m(name, '/');574 if (base != NULL) {575 base += 1;576 }577 else {578 base = name;579 }580 hash_size = lp_parm_int(-1, "tdb_hashsize", base, 0);581 }582 583 w->tdb = tdb_open_ex(name, hash_size, tdb_flags,584 open_flags, mode, &log_ctx, NULL);585 if (w->tdb == NULL) {586 talloc_free(w);587 return NULL;588 }589 590 talloc_set_destructor(w, tdb_wrap_destructor);591 592 DLIST_ADD(tdb_list, w);593 594 return w;595 }596 597 487 NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err) 598 488 { 599 struct { enum TDB_ERROR err; NTSTATUS status; } map[] = 600 { { TDB_SUCCESS, NT_STATUS_OK }, 601 { TDB_ERR_CORRUPT, NT_STATUS_INTERNAL_DB_CORRUPTION }, 602 { TDB_ERR_IO, NT_STATUS_UNEXPECTED_IO_ERROR }, 603 { TDB_ERR_OOM, NT_STATUS_NO_MEMORY }, 604 { TDB_ERR_EXISTS, NT_STATUS_OBJECT_NAME_COLLISION }, 605 606 /* 607 * TDB_ERR_LOCK is very broad, we could for example 608 * distinguish between fcntl locks and invalid lock 609 * sequences. So NT_STATUS_FILE_LOCK_CONFLICT is a 610 * compromise. 611 */ 612 { TDB_ERR_LOCK, NT_STATUS_FILE_LOCK_CONFLICT }, 613 /* 614 * The next two ones in the enum are not actually used 615 */ 616 { TDB_ERR_NOLOCK, NT_STATUS_FILE_LOCK_CONFLICT }, 617 { TDB_ERR_LOCK_TIMEOUT, NT_STATUS_FILE_LOCK_CONFLICT }, 618 { TDB_ERR_NOEXIST, NT_STATUS_NOT_FOUND }, 619 { TDB_ERR_EINVAL, NT_STATUS_INVALID_PARAMETER }, 620 { TDB_ERR_RDONLY, NT_STATUS_ACCESS_DENIED } 621 }; 622 623 int i; 624 625 for (i=0; i < sizeof(map) / sizeof(map[0]); i++) { 626 if (err == map[i].err) { 627 return map[i].status; 628 } 629 } 630 631 return NT_STATUS_INTERNAL_ERROR; 489 NTSTATUS result = NT_STATUS_INTERNAL_ERROR; 490 491 switch (err) { 492 case TDB_SUCCESS: 493 result = NT_STATUS_OK; 494 break; 495 case TDB_ERR_CORRUPT: 496 result = NT_STATUS_INTERNAL_DB_CORRUPTION; 497 break; 498 case TDB_ERR_IO: 499 result = NT_STATUS_UNEXPECTED_IO_ERROR; 500 break; 501 case TDB_ERR_OOM: 502 result = NT_STATUS_NO_MEMORY; 503 break; 504 case TDB_ERR_EXISTS: 505 result = NT_STATUS_OBJECT_NAME_COLLISION; 506 break; 507 508 case TDB_ERR_LOCK: 509 /* 510 * TDB_ERR_LOCK is very broad, we could for example 511 * distinguish between fcntl locks and invalid lock 512 * sequences. So NT_STATUS_FILE_LOCK_CONFLICT is a 513 * compromise. 514 */ 515 result = NT_STATUS_FILE_LOCK_CONFLICT; 516 break; 517 518 case TDB_ERR_NOLOCK: 519 case TDB_ERR_LOCK_TIMEOUT: 520 /* 521 * These two ones in the enum are not actually used 522 */ 523 result = NT_STATUS_FILE_LOCK_CONFLICT; 524 break; 525 case TDB_ERR_NOEXIST: 526 result = NT_STATUS_NOT_FOUND; 527 break; 528 case TDB_ERR_EINVAL: 529 result = NT_STATUS_INVALID_PARAMETER; 530 break; 531 case TDB_ERR_RDONLY: 532 result = NT_STATUS_ACCESS_DENIED; 533 break; 534 case TDB_ERR_NESTING: 535 result = NT_STATUS_INTERNAL_ERROR; 536 break; 537 }; 538 return result; 632 539 } 633 540
Note:
See TracChangeset
for help on using the changeset viewer.