diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-04-26 08:09:34 +1000 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2012-04-26 08:09:34 +1000 |
commit | 4426f9a5317d7eda10a43e6cf76f154c17e81f64 (patch) | |
tree | d6aa0ecdf87fe7e58a3754f86b5e7e9f2962f750 /ctdb/lib | |
parent | db411aaada39593c80f92e46be31d3473bf4639f (diff) | |
parent | 8f643897bbd33ea0c120dc06586434b8a2592b1f (diff) | |
download | samba-4426f9a5317d7eda10a43e6cf76f154c17e81f64.tar.gz samba-4426f9a5317d7eda10a43e6cf76f154c17e81f64.tar.xz samba-4426f9a5317d7eda10a43e6cf76f154c17e81f64.zip |
Merge remote branch 'amitay/tdb-sync'
(This used to be ctdb commit 8052ee0a6bda3fa88501d77b2d53315be2b75ec1)
Diffstat (limited to 'ctdb/lib')
44 files changed, 1547 insertions, 4858 deletions
diff --git a/ctdb/lib/tdb/ABI/tdb-1.2.6.sigs b/ctdb/lib/tdb/ABI/tdb-1.2.10.sigs index 1e01f3ba24b..61f6c19ee36 100644 --- a/ctdb/lib/tdb/ABI/tdb-1.2.6.sigs +++ b/ctdb/lib/tdb/ABI/tdb-1.2.10.sigs @@ -25,6 +25,7 @@ tdb_get_seqnum: int (struct tdb_context *) tdb_hash_size: int (struct tdb_context *) tdb_increment_seqnum_nonblock: void (struct tdb_context *) tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) tdb_lockall: int (struct tdb_context *) tdb_lockall_mark: int (struct tdb_context *) tdb_lockall_nonblock: int (struct tdb_context *) @@ -48,13 +49,17 @@ tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_c tdb_set_max_dead: void (struct tdb_context *, int) tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) tdb_transaction_cancel: int (struct tdb_context *) tdb_transaction_commit: int (struct tdb_context *) tdb_transaction_prepare_commit: int (struct tdb_context *) tdb_transaction_start: int (struct tdb_context *) tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) tdb_unlockall: int (struct tdb_context *) tdb_unlockall_read: int (struct tdb_context *) tdb_validate_freelist: int (struct tdb_context *, int *) diff --git a/ctdb/lib/tdb/Makefile.in b/ctdb/lib/tdb/Makefile.in deleted file mode 100644 index 93bfe37f4f2..00000000000 --- a/ctdb/lib/tdb/Makefile.in +++ /dev/null @@ -1,74 +0,0 @@ -#!gmake -# -# Makefile for tdb directory -# - -CC = @CC@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -includedir = @includedir@ -libdir = @libdir@ -VPATH = @srcdir@:@libreplacedir@ -srcdir = @srcdir@ -builddir = @builddir@ -sharedbuilddir = @sharedbuilddir@ -INSTALLCMD = @INSTALL@ -CPPFLAGS = @CPPFLAGS@ -I$(srcdir)/include -Iinclude -CFLAGS = $(CPPFLAGS) @CFLAGS@ -LDFLAGS = @LDFLAGS@ -EXEEXT = @EXEEXT@ -SHLD = @SHLD@ -SHLD_FLAGS = @SHLD_FLAGS@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PICFLAG = @PICFLAG@ -SHLIBEXT = @SHLIBEXT@ -PYTHON = @PYTHON@ -PYTHON_CONFIG = @PYTHON_CONFIG@ -PYTHON_BUILD_TARGET = @PYTHON_BUILD_TARGET@ -PYTHON_INSTALL_TARGET = @PYTHON_INSTALL_TARGET@ -PYTHON_CHECK_TARGET = @PYTHON_CHECK_TARGET@ -LIB_PATH_VAR = @LIB_PATH_VAR@ -tdbdir = @tdbdir@ - -TDB_OBJ = @TDB_OBJ@ @LIBREPLACEOBJ@ - -SONAMEFLAG = @SONAMEFLAG@ -VERSIONSCRIPT = @VERSIONSCRIPT@ -EXPORTSFILE = @EXPORTSFILE@ - -default: all - -include $(tdbdir)/tdb.mk -include $(tdbdir)/rules.mk - -all:: showflags dirs $(PROGS) $(TDB_SOLIB) libtdb.a $(PYTHON_BUILD_TARGET) - -install:: all -$(TDB_SOLIB): $(TDB_OBJ) - $(SHLD) $(SHLD_FLAGS) -o $@ $(TDB_OBJ) $(VERSIONSCRIPT) $(EXPORTSFILE) $(SONAMEFLAG)$(TDB_SONAME) - -shared-build: all - ${INSTALLCMD} -d $(sharedbuilddir)/lib - ${INSTALLCMD} -m 644 libtdb.a $(sharedbuilddir)/lib - ${INSTALLCMD} -m 755 $(TDB_SOLIB) $(sharedbuilddir)/lib - ln -sf $(TDB_SOLIB) $(sharedbuilddir)/lib/$(TDB_SONAME) - ln -sf $(TDB_SOLIB) $(sharedbuilddir)/lib/libtdb.so - ${INSTALLCMD} -d $(sharedbuilddir)/include - ${INSTALLCMD} -m 644 $(srcdir)/include/tdb.h $(sharedbuilddir)/include - -check: test - -test:: $(PYTHON_CHECK_TARGET) -installcheck:: test install - -clean:: - rm -f *.o *.a */*.o - rm -fr abi - -distclean:: clean - rm -f config.log config.status include/config.h config.cache - rm -f Makefile - -realdistclean:: distclean - rm -f configure include/config.h.in diff --git a/ctdb/lib/tdb/aclocal.m4 b/ctdb/lib/tdb/aclocal.m4 deleted file mode 100644 index 5605e476bab..00000000000 --- a/ctdb/lib/tdb/aclocal.m4 +++ /dev/null @@ -1 +0,0 @@ -m4_include(libreplace.m4) diff --git a/ctdb/lib/tdb/autogen.sh b/ctdb/lib/tdb/autogen.sh deleted file mode 100755 index bf84eeee19a..00000000000 --- a/ctdb/lib/tdb/autogen.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -rm -rf autom4te.cache -rm -f configure config.h.in - -IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace" -autoconf $IPATHS || exit 1 -autoheader $IPATHS || exit 1 - -rm -rf autom4te.cache - -echo "Now run ./configure and then make." -exit 0 - diff --git a/ctdb/lib/tdb/build_macros.m4 b/ctdb/lib/tdb/build_macros.m4 deleted file mode 100644 index c036668cd14..00000000000 --- a/ctdb/lib/tdb/build_macros.m4 +++ /dev/null @@ -1,14 +0,0 @@ -AC_DEFUN(BUILD_WITH_SHARED_BUILD_DIR, - [ AC_ARG_WITH([shared-build-dir], - [AC_HELP_STRING([--with-shared-build-dir=DIR], - [temporary build directory where libraries are installed [$srcdir/sharedbuild]])]) - - sharedbuilddir="$srcdir/sharedbuild" - if test x"$with_shared_build_dir" != x; then - sharedbuilddir=$with_shared_build_dir - CFLAGS="$CFLAGS -I$with_shared_build_dir/include" - LDFLAGS="$LDFLAGS -L$with_shared_build_dir/lib" - fi - AC_SUBST(sharedbuilddir) - ]) - diff --git a/ctdb/lib/tdb/common/check.c b/ctdb/lib/tdb/common/check.c index 58c9c26540d..313f55cbb05 100644 --- a/ctdb/lib/tdb/common/check.c +++ b/ctdb/lib/tdb/common/check.c @@ -92,7 +92,7 @@ static bool tdb_check_record(struct tdb_context *tdb, off, rec->next)); goto corrupt; } - if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0)) + if (tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 0)) goto corrupt; /* Check rec_len: similar to rec->next, implies next record. */ @@ -110,7 +110,7 @@ static bool tdb_check_record(struct tdb_context *tdb, goto corrupt; } /* OOB allows "right at the end" access, so this works for last rec. */ - if (tdb->methods->tdb_oob(tdb, off+sizeof(*rec)+rec->rec_len, 0)) + if (tdb->methods->tdb_oob(tdb, off, sizeof(*rec)+rec->rec_len, 0)) goto corrupt; /* Check tailer. */ @@ -308,7 +308,7 @@ static bool tdb_check_free_record(struct tdb_context *tdb, } /* Slow, but should be very rare. */ -static size_t dead_space(struct tdb_context *tdb, tdb_off_t off) +size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off) { size_t len; @@ -322,7 +322,7 @@ static size_t dead_space(struct tdb_context *tdb, tdb_off_t off) return len; } -int tdb_check(struct tdb_context *tdb, +_PUBLIC_ int tdb_check(struct tdb_context *tdb, int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { @@ -345,7 +345,7 @@ int tdb_check(struct tdb_context *tdb, } /* Make sure we know true size of the underlying file. */ - tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); + tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); /* Header must be OK: also gets us the recovery ptr, if any. */ if (!tdb_check_header(tdb, &recovery_start)) @@ -406,7 +406,7 @@ int tdb_check(struct tdb_context *tdb, found_recovery = true; break; } - dead = dead_space(tdb, off); + dead = tdb_dead_space(tdb, off); if (dead < sizeof(rec)) goto corrupt; diff --git a/ctdb/lib/tdb/common/dump.c b/ctdb/lib/tdb/common/dump.c index 9f770f81a52..67de04e37c6 100644 --- a/ctdb/lib/tdb/common/dump.c +++ b/ctdb/lib/tdb/common/dump.c @@ -80,7 +80,7 @@ static int tdb_dump_chain(struct tdb_context *tdb, int i) return tdb_unlock(tdb, i, F_WRLCK); } -void tdb_dump_all(struct tdb_context *tdb) +_PUBLIC_ void tdb_dump_all(struct tdb_context *tdb) { int i; for (i=0;i<tdb->header.hash_size;i++) { @@ -90,7 +90,7 @@ void tdb_dump_all(struct tdb_context *tdb) tdb_dump_chain(tdb, -1); } -int tdb_printfreelist(struct tdb_context *tdb) +_PUBLIC_ int tdb_printfreelist(struct tdb_context *tdb) { int ret; long total_free = 0; diff --git a/ctdb/lib/tdb/common/error.c b/ctdb/lib/tdb/common/error.c index 9197918ddea..2aaaa8134e4 100644 --- a/ctdb/lib/tdb/common/error.c +++ b/ctdb/lib/tdb/common/error.c @@ -27,7 +27,7 @@ #include "tdb_private.h" -enum TDB_ERROR tdb_error(struct tdb_context *tdb) +_PUBLIC_ enum TDB_ERROR tdb_error(struct tdb_context *tdb) { return tdb->ecode; } @@ -46,7 +46,7 @@ static struct tdb_errname { {TDB_ERR_RDONLY, "write not permitted"} }; /* Error string for the last tdb error */ -const char *tdb_errorstr(struct tdb_context *tdb) +_PUBLIC_ const char *tdb_errorstr(struct tdb_context *tdb) { uint32_t i; for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) diff --git a/ctdb/lib/tdb/common/freelist.c b/ctdb/lib/tdb/common/freelist.c index 79e3c344b8b..6358f64a04a 100644 --- a/ctdb/lib/tdb/common/freelist.c +++ b/ctdb/lib/tdb/common/freelist.c @@ -56,7 +56,7 @@ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record rec->magic, off)); return -1; } - if (tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) + if (tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 0) != 0) return -1; return 0; } @@ -367,7 +367,7 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct tdb_rec /* return the size of the freelist - used to decide if we should repack */ -int tdb_freelist_size(struct tdb_context *tdb) +_PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) { tdb_off_t ptr; int count=0; diff --git a/ctdb/lib/tdb/common/freelistcheck.c b/ctdb/lib/tdb/common/freelistcheck.c index 8d1ebabe04e..ab6e78f02db 100644 --- a/ctdb/lib/tdb/common/freelistcheck.c +++ b/ctdb/lib/tdb/common/freelistcheck.c @@ -43,7 +43,7 @@ static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) return tdb_store(mem_tdb, key, data, TDB_INSERT); } -int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) +_PUBLIC_ int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) { struct tdb_context *mem_tdb = NULL; struct tdb_record rec; diff --git a/ctdb/lib/tdb/common/hash.c b/ctdb/lib/tdb/common/hash.c index a29ba4a7a58..1eed7221d2a 100644 --- a/ctdb/lib/tdb/common/hash.c +++ b/ctdb/lib/tdb/common/hash.c @@ -22,8 +22,6 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#define VALGRIND - #include "tdb_private.h" /* This is based on the hash algorithm from gdbm */ @@ -216,9 +214,7 @@ static uint32_t hashlittle( const void *key, size_t length ) u.ptr = key; if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ -#ifdef VALGRIND const uint8_t *k8; -#endif /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ while (length > 12) @@ -232,36 +228,6 @@ static uint32_t hashlittle( const void *key, size_t length ) } /*----------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=k[1]&0xffffff; a+=k[0]; break; - case 6 : b+=k[1]&0xffff; a+=k[0]; break; - case 5 : b+=k[1]&0xff; a+=k[0]; break; - case 4 : a+=k[0]; break; - case 3 : a+=k[0]&0xffffff; break; - case 2 : a+=k[0]&0xffff; break; - case 1 : a+=k[0]&0xff; break; - case 0 : return c; /* zero length strings require no mixing */ - } - -#else /* make valgrind happy */ - k8 = (const uint8_t *)k; switch(length) { @@ -279,9 +245,6 @@ static uint32_t hashlittle( const void *key, size_t length ) case 1 : a+=k8[0]; break; case 0 : return c; } - -#endif /* !valgrind */ - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ const uint8_t *k8; @@ -376,7 +339,7 @@ static uint32_t hashlittle( const void *key, size_t length ) return c; } -unsigned int tdb_jenkins_hash(TDB_DATA *key) +_PUBLIC_ unsigned int tdb_jenkins_hash(TDB_DATA *key) { return hashlittle(key->dptr, key->dsize); } diff --git a/ctdb/lib/tdb/common/io.c b/ctdb/lib/tdb/common/io.c index 058ca6c6b51..3131f4fa0af 100644 --- a/ctdb/lib/tdb/common/io.c +++ b/ctdb/lib/tdb/common/io.c @@ -31,19 +31,29 @@ /* check for an out of bounds access - if it is out of bounds then see if the database has been expanded by someone else and expand if necessary - note that "len" is the minimum length needed for the db */ -static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, int probe) +static int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, + int probe) { struct stat st; - if (len <= tdb->map_size) + if (len + off < len) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob off %d len %d wrap\n", + (int)off, (int)len)); + } + return -1; + } + + if (off + len <= tdb->map_size) return 0; if (tdb->flags & TDB_INTERNAL) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond internal malloc size %d\n", - (int)len, (int)tdb->map_size)); + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond internal malloc size %u\n", + (int)(off + len), (int)tdb->map_size)); } return -1; } @@ -53,24 +63,32 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t len, int probe) return -1; } - if (st.st_size < (size_t)len) { + if (st.st_size < (size_t)off + len) { if (!probe) { /* Ensure ecode is set for log fn. */ tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %d beyond eof at %d\n", - (int)len, (int)st.st_size)); + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond eof at %u\n", + (int)(off + len), (int)st.st_size)); } return -1; } + /* Beware >4G files! */ + if ((tdb_off_t)st.st_size != st.st_size) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_oob len %llu too large!\n", + (long long)st.st_size)); + return -1; + } + /* Unmap, update size, remap */ if (tdb_munmap(tdb) == -1) { tdb->ecode = TDB_ERR_IO; return -1; } tdb->map_size = st.st_size; - tdb_mmap(tdb); - return 0; + return tdb_mmap(tdb); } /* write a lump of data at a specified offset */ @@ -86,12 +104,16 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, return -1; } - if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) + if (tdb->methods->tdb_oob(tdb, off, len, 0) != 0) return -1; if (tdb->map_ptr) { memcpy(off + (char *)tdb->map_ptr, buf, len); } else { +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#else ssize_t written = pwrite(tdb->fd, buf, len, off); if ((written != (ssize_t)len) && (written != -1)) { /* try once more */ @@ -116,6 +138,7 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, len, off)); return -1; } +#endif } return 0; } @@ -134,13 +157,17 @@ void *tdb_convert(void *buf, uint32_t size) static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { - if (tdb->methods->tdb_oob(tdb, off + len, 0) != 0) { + if (tdb->methods->tdb_oob(tdb, off, len, 0) != 0) { return -1; } if (tdb->map_ptr) { memcpy(buf, off + (char *)tdb->map_ptr, len); } else { +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#else ssize_t ret = pread(tdb->fd, buf, len, off); if (ret != (ssize_t)len) { /* Ensure ecode is set for log fn. */ @@ -151,6 +178,7 @@ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, (int)tdb->map_size)); return -1; } +#endif } if (cv) { tdb_convert(buf, len); @@ -203,13 +231,23 @@ int tdb_munmap(struct tdb_context *tdb) return 0; } -void tdb_mmap(struct tdb_context *tdb) +/* If mmap isn't coherent, *everyone* must always mmap. */ +static bool should_mmap(const struct tdb_context *tdb) +{ +#ifdef HAVE_INCOHERENT_MMAP + return true; +#else + return !(tdb->flags & TDB_NOMMAP); +#endif +} + +int tdb_mmap(struct tdb_context *tdb) { if (tdb->flags & TDB_INTERNAL) - return; + return 0; #ifdef HAVE_MMAP - if (!(tdb->flags & TDB_NOMMAP)) { + if (should_mmap(tdb)) { tdb->map_ptr = mmap(NULL, tdb->map_size, PROT_READ|(tdb->read_only? 0:PROT_WRITE), MAP_SHARED|MAP_FILE, tdb->fd, 0); @@ -222,6 +260,10 @@ void tdb_mmap(struct tdb_context *tdb) tdb->map_ptr = NULL; TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", tdb->map_size, strerror(errno))); +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#endif } } else { tdb->map_ptr = NULL; @@ -229,6 +271,7 @@ void tdb_mmap(struct tdb_context *tdb) #else tdb->map_ptr = NULL; #endif + return 0; } /* expand a file. we prefer to use ftruncate, as that is what posix @@ -294,12 +337,39 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad } +/* You need 'size', this tells you how much you should expand by. */ +tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size) +{ + tdb_off_t new_size, top_size; + + /* limit size in order to avoid using up huge amounts of memory for + * in memory tdbs if an oddball huge record creeps in */ + if (size > 100 * 1024) { + top_size = map_size + size * 2; + } else { + top_size = map_size + size * 100; + } + + /* always make room for at least top_size more records, and at + least 25% more space. if the DB is smaller than 100MiB, + otherwise grow it by 10% only. */ + if (map_size > 100 * 1024 * 1024) { + new_size = map_size * 1.10; + } else { + new_size = map_size * 1.25; + } + + /* Round the database up to a multiple of the page size */ + new_size = MAX(top_size, new_size); + return TDB_ALIGN(new_size, page_size) - map_size; +} + /* expand the database at least size bytes by expanding the underlying file and doing the mmap again if necessary */ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) { struct tdb_record rec; - tdb_off_t offset, new_size; + tdb_off_t offset; if (tdb_lock(tdb, -1, F_WRLCK) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); @@ -307,22 +377,9 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) } /* must know about any previous expansions by another process */ - tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - - /* always make room for at least 100 more records, and at - least 25% more space. Round the database up to a multiple - of the page size */ - new_size = MAX(tdb->map_size + size*100, tdb->map_size * 1.25); - size = TDB_ALIGN(new_size, tdb->page_size) - tdb->map_size; - - if (!(tdb->flags & TDB_INTERNAL)) - tdb_munmap(tdb); + tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); - /* - * We must ensure the file is unmapped before doing this - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ + size = tdb_expand_adjust(tdb->map_size, size, tdb->page_size); /* expand the file itself */ if (!(tdb->flags & TDB_INTERNAL)) { @@ -330,33 +387,30 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) goto fail; } - tdb->map_size += size; + /* form a new freelist record */ + offset = tdb->map_size; + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = size - sizeof(rec); if (tdb->flags & TDB_INTERNAL) { char *new_map_ptr = (char *)realloc(tdb->map_ptr, - tdb->map_size); + tdb->map_size + size); if (!new_map_ptr) { - tdb->map_size -= size; goto fail; } tdb->map_ptr = new_map_ptr; + tdb->map_size += size; } else { - /* - * We must ensure the file is remapped before adding the space - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* We're ok if the mmap fails as we'll fallback to read/write */ - tdb_mmap(tdb); + /* Explicitly remap: if we're in a transaction, this won't + * happen automatically! */ + tdb_munmap(tdb); + tdb->map_size += size; + if (tdb_mmap(tdb) != 0) { + goto fail; + } } - /* form a new freelist record */ - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = size - sizeof(rec); - /* link it into the free list */ - offset = tdb->map_size - size; if (tdb_free(tdb, offset, &rec) == -1) goto fail; @@ -419,7 +473,7 @@ int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, * Optimize by avoiding the malloc/memcpy/free, point the * parser directly at the mmap area. */ - if (tdb->methods->tdb_oob(tdb, offset+len, 0) != 0) { + if (tdb->methods->tdb_oob(tdb, offset, len, 0) != 0) { return -1; } data.dptr = offset + (unsigned char *)tdb->map_ptr; @@ -446,7 +500,7 @@ int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *r TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); return -1; } - return tdb->methods->tdb_oob(tdb, rec->next+sizeof(*rec), 0); + return tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 0); } int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) diff --git a/ctdb/lib/tdb/common/lock.c b/ctdb/lib/tdb/common/lock.c index f0da8818d19..88a52e9dfa4 100644 --- a/ctdb/lib/tdb/common/lock.c +++ b/ctdb/lib/tdb/common/lock.c @@ -27,7 +27,7 @@ #include "tdb_private.h" -void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) +_PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) { tdb->interrupt_sig_ptr = ptr; } @@ -380,7 +380,7 @@ int tdb_lock(struct tdb_context *tdb, int list, int ltype) } /* lock a list in the database. list -1 is the alloc list. non-blocking lock */ -int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) +_PUBLIC_ int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) { return tdb_lock_list(tdb, list, ltype, TDB_LOCK_NOWAIT); } @@ -445,7 +445,7 @@ int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, return ret; } -int tdb_unlock(struct tdb_context *tdb, int list, int ltype) +_PUBLIC_ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) { /* a global lock allows us to avoid per chain locks */ if (tdb->allrecord_lock.count && @@ -644,28 +644,28 @@ int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock) } /* lock entire database with write lock */ -int tdb_lockall(struct tdb_context *tdb) +_PUBLIC_ int tdb_lockall(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall"); return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); } /* lock entire database with write lock - mark only */ -int tdb_lockall_mark(struct tdb_context *tdb) +_PUBLIC_ int tdb_lockall_mark(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_mark"); return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY, false); } /* unlock entire database with write lock - unmark only */ -int tdb_lockall_unmark(struct tdb_context *tdb) +_PUBLIC_ int tdb_lockall_unmark(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_unmark"); return tdb_allrecord_unlock(tdb, F_WRLCK, true); } /* lock entire database with write lock - nonblocking varient */ -int tdb_lockall_nonblock(struct tdb_context *tdb) +_PUBLIC_ int tdb_lockall_nonblock(struct tdb_context *tdb) { int ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret); @@ -673,21 +673,21 @@ int tdb_lockall_nonblock(struct tdb_context *tdb) } /* unlock entire database with write lock */ -int tdb_unlockall(struct tdb_context *tdb) +_PUBLIC_ int tdb_unlockall(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_unlockall"); return tdb_allrecord_unlock(tdb, F_WRLCK, false); } /* lock entire database with read lock */ -int tdb_lockall_read(struct tdb_context *tdb) +_PUBLIC_ int tdb_lockall_read(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_lockall_read"); return tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); } /* lock entire database with read lock - nonblock varient */ -int tdb_lockall_read_nonblock(struct tdb_context *tdb) +_PUBLIC_ int tdb_lockall_read_nonblock(struct tdb_context *tdb) { int ret = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_NOWAIT, false); tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret); @@ -695,7 +695,7 @@ int tdb_lockall_read_nonblock(struct tdb_context *tdb) } /* unlock entire database with read lock */ -int tdb_unlockall_read(struct tdb_context *tdb) +_PUBLIC_ int tdb_unlockall_read(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_unlockall_read"); return tdb_allrecord_unlock(tdb, F_RDLCK, false); @@ -703,7 +703,7 @@ int tdb_unlockall_read(struct tdb_context *tdb) /* lock/unlock one hash chain. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ -int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); tdb_trace_1rec(tdb, "tdb_chainlock", key); @@ -713,7 +713,7 @@ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) /* lock/unlock one hash chain, non-blocking. This is meant to be used to reduce contention - it cannot guarantee how many records will be locked */ -int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret); @@ -721,7 +721,7 @@ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) } /* mark a chain as locked without actually locking it. Warning! use with great caution! */ -int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) { int ret = tdb_nest_lock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), F_WRLCK, TDB_LOCK_MARK_ONLY); @@ -730,20 +730,20 @@ int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) } /* unmark a chain as locked without actually locking it. Warning! use with great caution! */ -int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key); return tdb_nest_unlock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), F_WRLCK, true); } -int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainunlock", key); return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } -int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) { int ret; ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); @@ -751,14 +751,12 @@ int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) return ret; } -int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) { tdb_trace_1rec(tdb, "tdb_chainunlock_read", key); return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); } - - /* record lock stops delete underneath */ int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) { @@ -862,22 +860,16 @@ void tdb_release_transaction_locks(struct tdb_context *tdb) } } -int tdb_transaction_write_lock_mark(struct tdb_context *tdb) -{ - return tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY); -} +/* Following functions are added specifically to support CTDB. */ -int tdb_transaction_write_lock(struct tdb_context *tdb) +/* Don't do actual fcntl locking, just mark tdb locked */ +_PUBLIC_ int tdb_transaction_write_lock_mark(struct tdb_context *tdb) { - return tdb_transaction_lock(tdb, F_WRLCK, 0); -} - -int tdb_transaction_write_unlock(struct tdb_context *tdb) -{ - return tdb_transaction_unlock(tdb, F_WRLCK); + return tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY); } -int tdb_transaction_write_lock_unmark(struct tdb_context *tdb) +/* Don't do actual fcntl unlocking, just mark tdb unlocked */ +_PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb) { return tdb_nest_unlock(tdb, TRANSACTION_LOCK, F_WRLCK, true); } diff --git a/ctdb/lib/tdb/common/open.c b/ctdb/lib/tdb/common/open.c index 66539c3f6c5..8836f8442ee 100644 --- a/ctdb/lib/tdb/common/open.c +++ b/ctdb/lib/tdb/common/open.c @@ -129,7 +129,7 @@ static int tdb_already_open(dev_t device, try to call tdb_error or tdb_errname, just do strerror(errno). @param name may be NULL for internal databases. */ -struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, +_PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); @@ -162,7 +162,7 @@ static bool check_header_hash(struct tdb_context *tdb, return check_header_hash(tdb, false, m1, m2); } -struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, +_PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn) @@ -197,6 +197,32 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->log.log_private = NULL; } + if (name == NULL && (tdb_flags & TDB_INTERNAL)) { + name = "__TDB_INTERNAL__"; + } + + if (name == NULL) { + tdb->name = discard_const_p(char, "__NULL__"); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n")); + tdb->name = NULL; + errno = EINVAL; + goto fail; + } + + /* now make a copy of the name, as the caller memory might went away */ + if (!(tdb->name = (char *)strdup(name))) { + /* + * set the name as the given string, so that tdb_name() will + * work in case of an error. + */ + tdb->name = discard_const_p(char, name); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n", + name)); + tdb->name = NULL; + errno = ENOMEM; + goto fail; + } + if (hash_fn) { tdb->hash_fn = hash_fn; hash_alg = "the user defined"; @@ -359,12 +385,17 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, goto fail; } - if (!(tdb->name = (char *)strdup(name))) { - errno = ENOMEM; + /* Beware truncation! */ + tdb->map_size = st.st_size; + if (tdb->map_size != st.st_size) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "len %llu too large!\n", (long long)st.st_size)); + errno = EIO; goto fail; } - tdb->map_size = st.st_size; tdb->device = st.st_dev; tdb->inode = st.st_ino; tdb_mmap(tdb); @@ -436,11 +467,11 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, else tdb_munmap(tdb); } - SAFE_FREE(tdb->name); if (tdb->fd != -1) if (close(tdb->fd) != 0) TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); SAFE_FREE(tdb->lockrecs); + SAFE_FREE(tdb->name); SAFE_FREE(tdb); errno = save_errno; return NULL; @@ -451,7 +482,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, * Set the maximum number of dead records per hash chain */ -void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) +_PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) { tdb->max_dead_records = max_dead; } @@ -461,7 +492,7 @@ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) * * @returns -1 for error; 0 for success. **/ -int tdb_close(struct tdb_context *tdb) +_PUBLIC_ int tdb_close(struct tdb_context *tdb) { struct tdb_context **i; int ret = 0; @@ -502,13 +533,13 @@ int tdb_close(struct tdb_context *tdb) } /* register a loging function */ -void tdb_set_logging_function(struct tdb_context *tdb, - const struct tdb_logging_context *log_ctx) +_PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb, + const struct tdb_logging_context *log_ctx) { tdb->log = *log_ctx; } -void *tdb_get_logging_private(struct tdb_context *tdb) +_PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb) { return tdb->log.log_private; } @@ -556,7 +587,9 @@ static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); goto fail; } - tdb_mmap(tdb); + if (tdb_mmap(tdb) != 0) { + goto fail; + } #endif /* fake pread or pwrite */ /* We may still think we hold the active lock. */ @@ -577,13 +610,13 @@ fail: /* reopen a tdb - this can be used after a fork to ensure that we have an independent seek pointer from our parent and to re-establish locks */ -int tdb_reopen(struct tdb_context *tdb) +_PUBLIC_ int tdb_reopen(struct tdb_context *tdb) { return tdb_reopen_internal(tdb, tdb->flags & TDB_CLEAR_IF_FIRST); } /* reopen all tdb's */ -int tdb_reopen_all(int parent_longlived) +_PUBLIC_ int tdb_reopen_all(int parent_longlived) { struct tdb_context *tdb; diff --git a/ctdb/lib/tdb/common/summary.c b/ctdb/lib/tdb/common/summary.c new file mode 100644 index 00000000000..171a1a20554 --- /dev/null +++ b/ctdb/lib/tdb/common/summary.c @@ -0,0 +1,201 @@ + /* + Trivial Database: human-readable summary code + Copyright (C) Rusty Russell 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ +#include "tdb_private.h" + +#define SUMMARY_FORMAT \ + "Size of file/data: %u/%zu\n" \ + "Number of records: %zu\n" \ + "Smallest/average/largest keys: %zu/%zu/%zu\n" \ + "Smallest/average/largest data: %zu/%zu/%zu\n" \ + "Smallest/average/largest padding: %zu/%zu/%zu\n" \ + "Number of dead records: %zu\n" \ + "Smallest/average/largest dead records: %zu/%zu/%zu\n" \ + "Number of free records: %zu\n" \ + "Smallest/average/largest free records: %zu/%zu/%zu\n" \ + "Number of hash chains: %zu\n" \ + "Smallest/average/largest hash chains: %zu/%zu/%zu\n" \ + "Number of uncoalesced records: %zu\n" \ + "Smallest/average/largest uncoalesced runs: %zu/%zu/%zu\n" \ + "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: %.0f/%.0f/%.0f/%.0f/%.0f/%.0f/%.0f\n" + +/* We don't use tally module, to keep upstream happy. */ +struct tally { + size_t min, max, total; + size_t num; +}; + +static void tally_init(struct tally *tally) +{ + tally->total = 0; + tally->num = 0; + tally->min = tally->max = 0; +} + +static void tally_add(struct tally *tally, size_t len) +{ + if (tally->num == 0) + tally->max = tally->min = len; + else if (len > tally->max) + tally->max = len; + else if (len < tally->min) + tally->min = len; + tally->num++; + tally->total += len; +} + +static size_t tally_mean(const struct tally *tally) +{ + if (!tally->num) + return 0; + return tally->total / tally->num; +} + +static size_t get_hash_length(struct tdb_context *tdb, unsigned int i) +{ + tdb_off_t rec_ptr; + size_t count = 0; + + if (tdb_ofs_read(tdb, TDB_HASH_TOP(i), &rec_ptr) == -1) + return 0; + + /* keep looking until we find the right record */ + while (rec_ptr) { + struct tdb_record r; + ++count; + if (tdb_rec_read(tdb, rec_ptr, &r) == -1) + return 0; + rec_ptr = r.next; + } + return count; +} + +_PUBLIC_ char *tdb_summary(struct tdb_context *tdb) +{ + tdb_off_t off, rec_off; + struct tally freet, keys, data, dead, extra, hash, uncoal; + struct tdb_record rec; + char *ret = NULL; + bool locked; + size_t len, unc = 0; + struct tdb_record recovery; + + /* Read-only databases use no locking at all: it's best-effort. + * We may have a write lock already, so skip that case too. */ + if (tdb->read_only || tdb->allrecord_lock.count != 0) { + locked = false; + } else { + if (tdb_lockall_read(tdb) == -1) + return NULL; + locked = true; + } + + if (tdb_recovery_area(tdb, tdb->methods, &rec_off, &recovery) != 0) { + goto unlock; + } + + tally_init(&freet); + tally_init(&keys); + tally_init(&data); + tally_init(&dead); + tally_init(&extra); + tally_init(&hash); + tally_init(&uncoal); + + for (off = TDB_DATA_START(tdb->header.hash_size); + off < tdb->map_size - 1; + off += sizeof(rec) + rec.rec_len) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == -1) + goto unlock; + switch (rec.magic) { + case TDB_MAGIC: + tally_add(&keys, rec.key_len); + tally_add(&data, rec.data_len); + tally_add(&extra, rec.rec_len - (rec.key_len + + rec.data_len)); + if (unc > 1) + tally_add(&uncoal, unc - 1); + unc = 0; + break; + case TDB_FREE_MAGIC: + tally_add(&freet, rec.rec_len); + unc++; + break; + /* If we crash after ftruncate, we can get zeroes or fill. */ + case TDB_RECOVERY_INVALID_MAGIC: + case 0x42424242: + unc++; + /* If it's a valid recovery, we can trust rec_len. */ + if (off != rec_off) { + rec.rec_len = tdb_dead_space(tdb, off) + - sizeof(rec); + } + /* Fall through */ + case TDB_DEAD_MAGIC: + tally_add(&dead, rec.rec_len); + break; + default: + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Unexpected record magic 0x%x at offset %d\n", + rec.magic, off)); + goto unlock; + } + } + if (unc > 1) + tally_add(&uncoal, unc - 1); + + for (off = 0; off < tdb->header.hash_size; off++) + tally_add(&hash, get_hash_length(tdb, off)); + + /* 20 is max length of a %zu. */ + len = strlen(SUMMARY_FORMAT) + 35*20 + 1; + ret = (char *)malloc(len); + if (!ret) + goto unlock; + + snprintf(ret, len, SUMMARY_FORMAT, + tdb->map_size, keys.total+data.total, + keys.num, + keys.min, tally_mean(&keys), keys.max, + data.min, tally_mean(&data), data.max, + extra.min, tally_mean(&extra), extra.max, + dead.num, + dead.min, tally_mean(&dead), dead.max, + freet.num, + freet.min, tally_mean(&freet), freet.max, + hash.num, + hash.min, tally_mean(&hash), hash.max, + uncoal.total, + uncoal.min, tally_mean(&uncoal), uncoal.max, + keys.total * 100.0 / tdb->map_size, + data.total * 100.0 / tdb->map_size, + extra.total * 100.0 / tdb->map_size, + freet.total * 100.0 / tdb->map_size, + dead.total * 100.0 / tdb->map_size, + (keys.num + freet.num + dead.num) + * (sizeof(struct tdb_record) + sizeof(uint32_t)) + * 100.0 / tdb->map_size, + tdb->header.hash_size * sizeof(tdb_off_t) + * 100.0 / tdb->map_size); + +unlock: + if (locked) { + tdb_unlockall_read(tdb); + } + return ret; +} diff --git a/ctdb/lib/tdb/common/tdb.c b/ctdb/lib/tdb/common/tdb.c index 4d8c5fc59c9..fc1f5608fa2 100644 --- a/ctdb/lib/tdb/common/tdb.c +++ b/ctdb/lib/tdb/common/tdb.c @@ -27,13 +27,13 @@ #include "tdb_private.h" -TDB_DATA tdb_null; +_PUBLIC_ TDB_DATA tdb_null; /* non-blocking increment of the tdb sequence number if the tdb has been opened using the TDB_SEQNUM flag */ -void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) +_PUBLIC_ void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) { tdb_off_t seqnum=0; @@ -124,6 +124,19 @@ tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t has static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key); +static int tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data) +{ + TDB_DATA *dbuf = (TDB_DATA *)private_data; + + if (dbuf->dsize != data.dsize) { + return -1; + } + if (memcmp(dbuf->dptr, data.dptr, data.dsize) != 0) { + return -1; + } + return 0; +} + /* update an entry in place - this only works if the new data size is <= the old data size and the key exists. on failure return -1. @@ -141,18 +154,9 @@ static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, * surprisingly common (eg. with a ldb re-index). */ if (rec.key_len == key.dsize && rec.data_len == dbuf.dsize && - rec.full_hash == hash) { - TDB_DATA data = _tdb_fetch(tdb, key); - if (data.dsize == dbuf.dsize && - memcmp(data.dptr, dbuf.dptr, data.dsize) == 0) { - if (data.dptr) { - free(data.dptr); - } - return 0; - } - if (data.dptr) { - free(data.dptr); - } + rec.full_hash == hash && + tdb_parse_record(tdb, key, tdb_update_hash_cmp, &dbuf) == 0) { + return 0; } /* must be long enough key, data and tailer */ @@ -199,7 +203,7 @@ static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key) return ret; } -TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) { TDB_DATA ret = _tdb_fetch(tdb, key); @@ -225,7 +229,7 @@ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) * Return -1 if the record was not found. */ -int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, +_PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) @@ -270,7 +274,7 @@ static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) return 1; } -int tdb_exists(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) { uint32_t hash = tdb->hash_fn(&key); int ret; @@ -429,7 +433,7 @@ static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) return ret; } -int tdb_delete(struct tdb_context *tdb, TDB_DATA key) +_PUBLIC_ int tdb_delete(struct tdb_context *tdb, TDB_DATA key) { uint32_t hash = tdb->hash_fn(&key); int ret; @@ -473,7 +477,6 @@ static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, { struct tdb_record rec; tdb_off_t rec_ptr; - char *p = NULL; int ret = -1; /* check for it existing, on insert. */ @@ -503,18 +506,6 @@ static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, if (flag != TDB_INSERT) tdb_delete_hash(tdb, key, hash); - /* Copy key+value *before* allocating free space in case malloc - fails and we are left with a dead spot in the tdb. */ - - if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - memcpy(p, key.dptr, key.dsize); - if (dbuf.dsize) - memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); - if (tdb->max_dead_records != 0) { /* * Allow for some dead records per hash chain, look if we can @@ -534,7 +525,10 @@ static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 || tdb->methods->tdb_write( tdb, rec_ptr + sizeof(rec), - p, key.dsize + dbuf.dsize) == -1) { + key.dptr, key.dsize) == -1 + || tdb->methods->tdb_write( + tdb, rec_ptr + sizeof(rec) + key.dsize, + dbuf.dptr, dbuf.dsize) == -1) { goto fail; } goto done; @@ -577,7 +571,10 @@ static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, /* write out and point the top of the hash chain at it */ if (tdb_rec_write(tdb, rec_ptr, &rec) == -1 - || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 + || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec), + key.dptr, key.dsize) == -1 + || tdb->methods->tdb_write(tdb, rec_ptr+sizeof(rec)+key.dsize, + dbuf.dptr, dbuf.dsize) == -1 || tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { /* Need to tdb_unallocate() here */ goto fail; @@ -589,8 +586,6 @@ static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, if (ret == 0) { tdb_increment_seqnum(tdb); } - - SAFE_FREE(p); return ret; } @@ -599,7 +594,7 @@ static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, return 0 on success, -1 on failure */ -int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) +_PUBLIC_ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) { uint32_t hash; int ret; @@ -622,7 +617,7 @@ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) } /* Append to an entry. Create if not exist. */ -int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) +_PUBLIC_ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) { uint32_t hash; TDB_DATA dbuf; @@ -673,7 +668,7 @@ failed: return the name of the current tdb file useful for external logging functions */ -const char *tdb_name(struct tdb_context *tdb) +_PUBLIC_ const char *tdb_name(struct tdb_context *tdb) { return tdb->name; } @@ -683,7 +678,7 @@ const char *tdb_name(struct tdb_context *tdb) useful for external routines that want to check the device/inode of the fd */ -int tdb_fd(struct tdb_context *tdb) +_PUBLIC_ int tdb_fd(struct tdb_context *tdb) { return tdb->fd; } @@ -692,7 +687,7 @@ int tdb_fd(struct tdb_context *tdb) return the current logging function useful for external tdb routines that wish to log tdb errors */ -tdb_log_func tdb_log_fn(struct tdb_context *tdb) +_PUBLIC_ tdb_log_func tdb_log_fn(struct tdb_context *tdb) { return tdb->log.log_fn; } @@ -708,7 +703,7 @@ tdb_log_func tdb_log_fn(struct tdb_context *tdb) The aim of this sequence number is to allow for a very lightweight test of a possible tdb change. */ -int tdb_get_seqnum(struct tdb_context *tdb) +_PUBLIC_ int tdb_get_seqnum(struct tdb_context *tdb) { tdb_off_t seqnum=0; @@ -716,22 +711,22 @@ int tdb_get_seqnum(struct tdb_context *tdb) return seqnum; } -int tdb_hash_size(struct tdb_context *tdb) +_PUBLIC_ int tdb_hash_size(struct tdb_context *tdb) { return tdb->header.hash_size; } -size_t tdb_map_size(struct tdb_context *tdb) +_PUBLIC_ size_t tdb_map_size(struct tdb_context *tdb) { return tdb->map_size; } -int tdb_get_flags(struct tdb_context *tdb) +_PUBLIC_ int tdb_get_flags(struct tdb_context *tdb) { return tdb->flags; } -void tdb_add_flags(struct tdb_context *tdb, unsigned flags) +_PUBLIC_ void tdb_add_flags(struct tdb_context *tdb, unsigned flags) { if ((flags & TDB_ALLOW_NESTING) && (flags & TDB_DISALLOW_NESTING)) { @@ -751,7 +746,7 @@ void tdb_add_flags(struct tdb_context *tdb, unsigned flags) tdb->flags |= flags; } -void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) +_PUBLIC_ void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) { if ((flags & TDB_ALLOW_NESTING) && (flags & TDB_DISALLOW_NESTING)) { @@ -775,7 +770,7 @@ void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) /* enable sequence number handling on an open tdb */ -void tdb_enable_seqnum(struct tdb_context *tdb) +_PUBLIC_ void tdb_enable_seqnum(struct tdb_context *tdb) { tdb->flags |= TDB_SEQNUM; } @@ -812,7 +807,7 @@ static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t le This code carefully steps around the recovery area, leaving it alone */ -int tdb_wipe_all(struct tdb_context *tdb) +_PUBLIC_ int tdb_wipe_all(struct tdb_context *tdb) { int i; tdb_off_t offset = 0; @@ -886,6 +881,8 @@ int tdb_wipe_all(struct tdb_context *tdb) } } + tdb_increment_seqnum_nonblock(tdb); + if (tdb_unlockall(tdb) != 0) { TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); goto failed; @@ -919,7 +916,7 @@ static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, /* repack a tdb */ -int tdb_repack(struct tdb_context *tdb) +_PUBLIC_ int tdb_repack(struct tdb_context *tdb) { struct tdb_context *tmp_db; struct traverse_state state; @@ -993,7 +990,7 @@ int tdb_repack(struct tdb_context *tdb) bool tdb_write_all(int fd, const void *buf, size_t count) { while (count) { - size_t ret; + ssize_t ret; ret = write(fd, buf, count); if (ret < 0) return false; @@ -1006,7 +1003,7 @@ bool tdb_write_all(int fd, const void *buf, size_t count) #ifdef TDB_TRACE static void tdb_trace_write(struct tdb_context *tdb, const char *str) { - if (!tdb_write_alltdb->tracefd, str, strlen(str)) { + if (!tdb_write_all(tdb->tracefd, str, strlen(str))) { close(tdb->tracefd); tdb->tracefd = -1; } diff --git a/ctdb/lib/tdb/common/tdb_private.h b/ctdb/lib/tdb/common/tdb_private.h index 0c621636fa2..0441fb287fd 100644 --- a/ctdb/lib/tdb/common/tdb_private.h +++ b/ctdb/lib/tdb/common/tdb_private.h @@ -1,3 +1,5 @@ +#ifndef TDB_PRIVATE_H +#define TDB_PRIVATE_H /* Unix SMB/CIFS implementation. @@ -180,7 +182,7 @@ struct tdb_methods { int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); void (*next_hash_chain)(struct tdb_context *, uint32_t *); - int (*tdb_oob)(struct tdb_context *, tdb_off_t , int ); + int (*tdb_oob)(struct tdb_context *, tdb_off_t , tdb_len_t, int ); int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); }; @@ -220,7 +222,7 @@ struct tdb_context { internal prototypes */ int tdb_munmap(struct tdb_context *tdb); -void tdb_mmap(struct tdb_context *tdb); +int tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, @@ -238,6 +240,10 @@ void tdb_release_transaction_locks(struct tdb_context *tdb); int tdb_transaction_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags lockflags); int tdb_transaction_unlock(struct tdb_context *tdb, int ltype); +int tdb_recovery_area(struct tdb_context *tdb, + const struct tdb_methods *methods, + tdb_off_t *recovery_offset, + struct tdb_record *rec); int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable); int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock); @@ -267,6 +273,7 @@ tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t has struct tdb_record *rec); void tdb_io_init(struct tdb_context *tdb); int tdb_expand(struct tdb_context *tdb, tdb_off_t size); +tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size); int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec); bool tdb_write_all(int fd, const void *buf, size_t count); @@ -274,3 +281,5 @@ int tdb_transaction_recover(struct tdb_context *tdb); void tdb_header_hash(struct tdb_context *tdb, uint32_t *magic1_hash, uint32_t *magic2_hash); unsigned int tdb_old_hash(TDB_DATA *key); +size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off); +#endif /* TDB_PRIVATE_H */ diff --git a/ctdb/lib/tdb/common/transaction.c b/ctdb/lib/tdb/common/transaction.c index 304a03fa383..c3477eb80ca 100644 --- a/ctdb/lib/tdb/common/transaction.c +++ b/ctdb/lib/tdb/common/transaction.c @@ -138,8 +138,8 @@ struct tdb_transaction { /* old file size before transaction */ tdb_len_t old_map_size; - /* we should re-pack on commit */ - bool need_repack; + /* did we expand in this transaction */ + bool expanded; }; @@ -382,9 +382,10 @@ static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain /* out of bounds check during a transaction */ -static int transaction_oob(struct tdb_context *tdb, tdb_off_t len, int probe) +static int transaction_oob(struct tdb_context *tdb, tdb_off_t off, + tdb_len_t len, int probe) { - if (len <= tdb->map_size) { + if (off + len >= off && off + len <= tdb->map_size) { return 0; } tdb->ecode = TDB_ERR_IO; @@ -403,7 +404,7 @@ static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, return -1; } - tdb->transaction->need_repack = true; + tdb->transaction->expanded = true; return 0; } @@ -507,7 +508,7 @@ static int _tdb_transaction_start(struct tdb_context *tdb, /* make sure we know about any file expansions already done by anyone else */ - tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); + tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); tdb->transaction->old_map_size = tdb->map_size; /* finally hook the io methods, replacing them with @@ -529,12 +530,12 @@ fail_allrecord_lock: return -1; } -int tdb_transaction_start(struct tdb_context *tdb) +_PUBLIC_ int tdb_transaction_start(struct tdb_context *tdb) { return _tdb_transaction_start(tdb, TDB_LOCK_WAIT); } -int tdb_transaction_start_nonblock(struct tdb_context *tdb) +_PUBLIC_ int tdb_transaction_start_nonblock(struct tdb_context *tdb) { return _tdb_transaction_start(tdb, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); } @@ -548,7 +549,11 @@ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t return 0; } +#ifdef HAVE_FDATASYNC if (fdatasync(tdb->fd) != 0) { +#else + if (fsync(tdb->fd) != 0) { +#endif tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); return -1; @@ -621,7 +626,7 @@ static int _tdb_transaction_cancel(struct tdb_context *tdb) /* cancel the current transaction */ -int tdb_transaction_cancel(struct tdb_context *tdb) +_PUBLIC_ int tdb_transaction_cancel(struct tdb_context *tdb) { tdb_trace(tdb, "tdb_transaction_cancel"); return _tdb_transaction_cancel(tdb); @@ -654,6 +659,34 @@ static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) return recovery_size; } +int tdb_recovery_area(struct tdb_context *tdb, + const struct tdb_methods *methods, + tdb_off_t *recovery_offset, + struct tdb_record *rec) +{ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, recovery_offset) == -1) { + return -1; + } + + if (*recovery_offset == 0) { + rec->rec_len = 0; + return 0; + } + + if (methods->tdb_read(tdb, *recovery_offset, rec, sizeof(*rec), + DOCONV()) == -1) { + return -1; + } + + /* ignore invalid recovery regions: can happen in crash */ + if (rec->magic != TDB_RECOVERY_MAGIC && + rec->magic != TDB_RECOVERY_INVALID_MAGIC) { + *recovery_offset = 0; + rec->rec_len = 0; + } + return 0; +} + /* allocate the recovery area, or use an existing recovery area if it is large enough @@ -665,29 +698,16 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, { struct tdb_record rec; const struct tdb_methods *methods = tdb->transaction->io_methods; - tdb_off_t recovery_head; + tdb_off_t recovery_head, new_end; - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + if (tdb_recovery_area(tdb, methods, &recovery_head, &rec) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); return -1; } - rec.rec_len = 0; - - if (recovery_head != 0) { - if (methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery record\n")); - return -1; - } - /* ignore invalid recovery regions: can happen in crash */ - if (rec.magic != TDB_RECOVERY_MAGIC && - rec.magic != TDB_RECOVERY_INVALID_MAGIC) { - recovery_head = 0; - } - } - *recovery_size = tdb_recovery_size(tdb); + /* Existing recovery area? */ if (recovery_head != 0 && *recovery_size <= rec.rec_len) { /* it fits in the existing area */ *recovery_max_size = rec.rec_len; @@ -695,35 +715,51 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, return 0; } - /* we need to free up the old recovery area, then allocate a - new one at the end of the file. Note that we cannot use - tdb_allocate() to allocate the new one as that might return - us an area that is being currently used (as of the start of - the transaction) */ - if (recovery_head != 0) { - if (tdb_free(tdb, recovery_head, &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to free previous recovery area\n")); - return -1; + /* If recovery area in middle of file, we need a new one. */ + if (recovery_head == 0 + || recovery_head + sizeof(rec) + rec.rec_len != tdb->map_size) { + /* we need to free up the old recovery area, then allocate a + new one at the end of the file. Note that we cannot use + tdb_allocate() to allocate the new one as that might return + us an area that is being currently used (as of the start of + the transaction) */ + if (recovery_head) { + if (tdb_free(tdb, recovery_head, &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_recovery_allocate: failed to" + " free previous recovery area\n")); + return -1; + } + + /* the tdb_free() call might have increased + * the recovery size */ + *recovery_size = tdb_recovery_size(tdb); } + + /* New head will be at end of file. */ + recovery_head = tdb->map_size; } - /* the tdb_free() call might have increased the recovery size */ - *recovery_size = tdb_recovery_size(tdb); + /* Now we know where it will be. */ + *recovery_offset = recovery_head; + + /* Expand by more than we need, so we don't do it often. */ + *recovery_max_size = tdb_expand_adjust(tdb->map_size, + *recovery_size, + tdb->page_size) + - sizeof(rec); - /* round up to a multiple of page size */ - *recovery_max_size = TDB_ALIGN(sizeof(rec) + *recovery_size, tdb->page_size) - sizeof(rec); - *recovery_offset = tdb->map_size; - recovery_head = *recovery_offset; + new_end = recovery_head + sizeof(rec) + *recovery_max_size; if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - (tdb->map_size - tdb->transaction->old_map_size) + - sizeof(rec) + *recovery_max_size) == -1) { + new_end - tdb->transaction->old_map_size) + == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); return -1; } /* remap the file (if using mmap) */ - methods->tdb_oob(tdb, tdb->map_size + 1, 1); + methods->tdb_oob(tdb, tdb->map_size, 1, 1); /* we have to reset the old map size so that we don't try to expand the file again in the transaction commit, which would destroy the recovery area */ @@ -782,7 +818,7 @@ static int transaction_setup_recovery(struct tdb_context *tdb, rec->data_len = recovery_size; rec->rec_len = recovery_max_size; rec->key_len = old_map_size; - CONVERT(rec); + CONVERT(*rec); /* build the recovery data into a single blob to allow us to do a single large write, which should be more efficient */ @@ -829,7 +865,9 @@ static int transaction_setup_recovery(struct tdb_context *tdb, /* and the tailer */ tailer = sizeof(*rec) + recovery_max_size; memcpy(p, &tailer, 4); - CONVERT(p); + if (DOCONV()) { + tdb_convert(p, 4); + } /* write the recovery data to the recovery area */ if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { @@ -960,7 +998,7 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) return -1; } tdb->map_size = tdb->transaction->old_map_size; - methods->tdb_oob(tdb, tdb->map_size + 1, 1); + methods->tdb_oob(tdb, tdb->map_size, 1, 1); } /* Keep the open lock until the actual commit */ @@ -971,20 +1009,42 @@ static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) /* prepare to commit the current transaction */ -int tdb_transaction_prepare_commit(struct tdb_context *tdb) -{ +_PUBLIC_ int tdb_transaction_prepare_commit(struct tdb_context *tdb) +{ tdb_trace(tdb, "tdb_transaction_prepare_commit"); return _tdb_transaction_prepare_commit(tdb); } +/* A repack is worthwhile if the largest is less than half total free. */ +static bool repack_worthwhile(struct tdb_context *tdb) +{ + tdb_off_t ptr; + struct tdb_record rec; + tdb_len_t total = 0, largest = 0; + + if (tdb_ofs_read(tdb, FREELIST_TOP, &ptr) == -1) { + return false; + } + + while (ptr != 0 && tdb_rec_free_read(tdb, ptr, &rec) == 0) { + total += rec.rec_len; + if (rec.rec_len > largest) { + largest = rec.rec_len; + } + ptr = rec.next; + } + + return total > largest * 2; +} + /* commit the current transaction */ -int tdb_transaction_commit(struct tdb_context *tdb) -{ +_PUBLIC_ int tdb_transaction_commit(struct tdb_context *tdb) +{ const struct tdb_methods *methods; int i; - bool need_repack; + bool need_repack = false; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); @@ -1052,6 +1112,11 @@ int tdb_transaction_commit(struct tdb_context *tdb) SAFE_FREE(tdb->transaction->blocks[i]); } + /* Do this before we drop lock or blocks. */ + if (tdb->transaction->expanded) { + need_repack = repack_worthwhile(tdb); + } + SAFE_FREE(tdb->transaction->blocks); tdb->transaction->num_blocks = 0; @@ -1075,8 +1140,6 @@ int tdb_transaction_commit(struct tdb_context *tdb) utime(tdb->name, NULL); #endif - need_repack = tdb->transaction->need_repack; - /* use a transaction cancel to free memory and remove the transaction locks */ _tdb_transaction_cancel(tdb); diff --git a/ctdb/lib/tdb/common/traverse.c b/ctdb/lib/tdb/common/traverse.c index d77086a79aa..517fecb4fc8 100644 --- a/ctdb/lib/tdb/common/traverse.c +++ b/ctdb/lib/tdb/common/traverse.c @@ -212,7 +212,7 @@ out: /* a write style traverse - temporarily marks the db read only */ -int tdb_traverse_read(struct tdb_context *tdb, +_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; @@ -241,7 +241,7 @@ int tdb_traverse_read(struct tdb_context *tdb, WARNING: The data buffer given to the callback fn does NOT meet the alignment restrictions malloc gives you. */ -int tdb_traverse(struct tdb_context *tdb, +_PUBLIC_ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data) { struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; @@ -267,7 +267,7 @@ int tdb_traverse(struct tdb_context *tdb, /* find the first entry in the database and return its key */ -TDB_DATA tdb_firstkey(struct tdb_context *tdb) +_PUBLIC_ TDB_DATA tdb_firstkey(struct tdb_context *tdb) { TDB_DATA key; struct tdb_record rec; @@ -298,7 +298,7 @@ TDB_DATA tdb_firstkey(struct tdb_context *tdb) } /* find the next entry in the database, returning its key */ -TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) +_PUBLIC_ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) { uint32_t oldhash; TDB_DATA key = tdb_null; diff --git a/ctdb/lib/tdb/config.guess b/ctdb/lib/tdb/config.guess deleted file mode 100755 index da833146088..00000000000 --- a/ctdb/lib/tdb/config.guess +++ /dev/null @@ -1,1561 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 -# Free Software Foundation, Inc. - -timestamp='2009-04-27' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner <per@bothner.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[456]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:[3456]*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - EM64T | authenticamd | genuineintel) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <features.h> - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -and - http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/ctdb/lib/tdb/config.mk b/ctdb/lib/tdb/config.mk deleted file mode 100644 index 22caadaba51..00000000000 --- a/ctdb/lib/tdb/config.mk +++ /dev/null @@ -1,66 +0,0 @@ -################################################ -# Start SUBSYSTEM LIBTDB -[LIBRARY::LIBTDB] -OUTPUT_TYPE = MERGED_OBJ -CFLAGS = -I$(tdbsrcdir)/include -# -# End SUBSYSTEM ldb -################################################ - -LIBTDB_OBJ_FILES = $(addprefix $(tdbsrcdir)/common/, \ - tdb.o dump.o io.o lock.o \ - open.o traverse.o freelist.o \ - error.o transaction.o check.o) - -################################################ -# Start BINARY tdbtool -[BINARY::tdbtool] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbtool -################################################ - -tdbtool_OBJ_FILES = $(tdbsrcdir)/tools/tdbtool.o - -################################################ -# Start BINARY tdbtorture -[BINARY::tdbtorture] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbtorture -################################################ - -tdbtorture_OBJ_FILES = $(tdbsrcdir)/tools/tdbtorture.o - -################################################ -# Start BINARY tdbrestore -[BINARY::tdbrestore] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbrestore -################################################ - -################################################ -# Start BINARY tdbdump -[BINARY::tdbdump] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbdump -################################################ - -tdbdump_OBJ_FILES = $(tdbsrcdir)/tools/tdbdump.o - -################################################ -# Start BINARY tdbbackup -[BINARY::tdbbackup] -INSTALLDIR = BINDIR -PRIVATE_DEPENDENCIES = \ - LIBTDB -# End BINARY tdbbackup -################################################ - -tdbbackup_OBJ_FILES = $(tdbsrcdir)/tools/tdbbackup.o diff --git a/ctdb/lib/tdb/config.sub b/ctdb/lib/tdb/config.sub deleted file mode 100755 index a39437d0158..00000000000 --- a/ctdb/lib/tdb/config.sub +++ /dev/null @@ -1,1686 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 -# Free Software Foundation, Inc. - -timestamp='2009-04-17' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nios | nios2 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tile*) - basic_machine=tile-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -kopensolaris* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/ctdb/lib/tdb/configure.ac b/ctdb/lib/tdb/configure.ac deleted file mode 100644 index fc42e00c153..00000000000 --- a/ctdb/lib/tdb/configure.ac +++ /dev/null @@ -1,44 +0,0 @@ -AC_PREREQ(2.50) -AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) -AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) -AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(tdb, 1.2.6) -AC_CONFIG_SRCDIR([common/tdb.c]) -AC_CONFIG_HEADER(include/config.h) -AC_LIBREPLACE_ALL_CHECKS -AC_LD_SONAMEFLAG -AC_LD_VERSIONSCRIPT -AC_LD_PICFLAG -AC_LD_SHLIBEXT -AC_LIBREPLACE_SHLD -AC_LIBREPLACE_SHLD_FLAGS -AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR -m4_include(libtdb.m4) -AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config]) -AC_PATH_PROGS([PYTHON], [python2.6 python2.5 python2.4 python]) - -PYTHON_BUILD_TARGET="build-python" -PYTHON_INSTALL_TARGET="install-python" -PYTHON_CHECK_TARGET="check-python" -AC_SUBST(PYTHON_BUILD_TARGET) -AC_SUBST(PYTHON_INSTALL_TARGET) -AC_SUBST(PYTHON_CHECK_TARGET) -if test -z "$PYTHON_CONFIG"; then - PYTHON_BUILD_TARGET="" - PYTHON_INSTALL_TARGET="" - PYTHON_CHECK_TARGET="" -fi - -AC_ARG_ENABLE(python, - AS_HELP_STRING([--enable-python], [Enables python binding]), - [ if test "x$enableval" = "xno" ; then - PYTHON_BUILD_TARGET="" - PYTHON_INSTALL_TARGET="" - PYTHON_CHECK_TARGET="" - fi - ]) - -m4_include(build_macros.m4) -BUILD_WITH_SHARED_BUILD_DIR - -AC_OUTPUT(Makefile tdb.pc) diff --git a/ctdb/lib/tdb/docs/mainpage.dox b/ctdb/lib/tdb/docs/mainpage.dox new file mode 100644 index 00000000000..d1307693566 --- /dev/null +++ b/ctdb/lib/tdb/docs/mainpage.dox @@ -0,0 +1,61 @@ +/** + +@mainpage + +This is a simple database API. It was inspired by the realisation that in Samba +we have several ad-hoc bits of code that essentially implement small databases +for sharing structures between parts of Samba. + +The interface is based on gdbm. gdbm couldn't be use as we needed to be able to +have multiple writers to the databases at one time. + +@section tdb_download Download + +You can download the latest releases of tdb from the +<a href="http://samba.org/ftp/tdb">tdb directory</a> on the samba public source +archive. + +You can download the latest code either via git or rsync. + +To fetch via git see the following guide: + +<a href="http://wiki.samba.org/index.php/Using_Git_for_Samba_Development">Using Git for Samba Development</a> +Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory. + +To fetch via rsync use these commands: + +<pre> + rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb . + rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace . +</pre> + +and build in tdb. It will find the replace library in the directory above +automatically. + +@section tdb_bugs Discussion and bug reports + +tdb does not currently have its own mailing list or bug tracking system. For now, +please use the +<a href="https://lists.samba.org/mailman/listinfo/samba-technical">samba-technical</a> +mailing list, and the <a href="http://bugzilla.samba.org/">Samba bugzilla</a> bug +tracking system. + + +@section tdb_compilation Compilation + +add HAVE_MMAP=1 to use mmap instead of read/write +add NOLOCK=1 to disable locking code + +@section tdb_testing Testing + +Compile tdbtest.c and link with gdbm for testing. tdbtest will perform +identical operations via tdb and gdbm then make sure the result is the +same + +Also included is tdbtool, which allows simple database manipulation +on the commandline. + +tdbtest and tdbtool are not built as part of Samba, but are included +for completeness. + +*/ diff --git a/ctdb/lib/tdb/include/tdb.h b/ctdb/lib/tdb/include/tdb.h index 536a0b37372..5eb95625dae 100644 --- a/ctdb/lib/tdb/include/tdb.h +++ b/ctdb/lib/tdb/include/tdb.h @@ -30,43 +30,68 @@ extern "C" { #endif -#include "signal.h" +#include <signal.h> -/* Samba sets hidden attribute when building libraries: we don't. */ -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif +/** + * @defgroup tdb The tdb API + * + * tdb is a Trivial database. In concept, it is very much like GDBM, and BSD's + * DB except that it allows multiple simultaneous writers and uses locking + * internally to keep writers from trampling on each other. tdb is also + * extremely small. + * + * @section tdb_interface Interface + * + * The interface is very similar to gdbm except for the following: + * + * <ul> + * <li>different open interface. The tdb_open call is more similar to a + * traditional open()</li> + * <li>no tdbm_reorganise() function</li> + * <li>no tdbm_sync() function. No operations are cached in the library + * anyway</li> + * <li>added a tdb_traverse() function for traversing the whole database</li> + * <li>added transactions support</li> + * </ul> + * + * A general rule for using tdb is that the caller frees any returned TDB_DATA + * structures. Just call free(p.dptr) to free a TDB_DATA return value called p. + * This is the same as gdbm. + * + * @{ + */ + +/** Flags to tdb_store() */ +#define TDB_REPLACE 1 /** Unused */ +#define TDB_INSERT 2 /** Don't overwrite an existing entry */ +#define TDB_MODIFY 3 /** Don't create an existing entry */ -/* flags to tdb_store() */ -#define TDB_REPLACE 1 /* Unused */ -#define TDB_INSERT 2 /* Don't overwrite an existing entry */ -#define TDB_MODIFY 3 /* Don't create an existing entry */ - -/* flags for tdb_open() */ -#define TDB_DEFAULT 0 /* just a readability place holder */ -#define TDB_CLEAR_IF_FIRST 1 -#define TDB_INTERNAL 2 /* don't store on disk */ -#define TDB_NOLOCK 4 /* don't do any locking */ -#define TDB_NOMMAP 8 /* don't use mmap */ -#define TDB_CONVERT 16 /* convert endian (internal use) */ -#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ -#define TDB_NOSYNC 64 /* don't use synchronous transactions */ -#define TDB_SEQNUM 128 /* maintain a sequence number */ -#define TDB_VOLATILE 256 /* Activate the per-hashchain freelist, default 5 */ -#define TDB_ALLOW_NESTING 512 /* Allow transactions to nest */ -#define TDB_DISALLOW_NESTING 1024 /* Disallow transactions to nest */ -#define TDB_INCOMPATIBLE_HASH 2048 /* Better hashing: can't be opened by tdb < 1.2.6. */ - -/* error codes */ +/** Flags for tdb_open() */ +#define TDB_DEFAULT 0 /** just a readability place holder */ +#define TDB_CLEAR_IF_FIRST 1 /** If this is the first open, wipe the db */ +#define TDB_INTERNAL 2 /** Don't store on disk */ +#define TDB_NOLOCK 4 /** Don't do any locking */ +#define TDB_NOMMAP 8 /** Don't use mmap */ +#define TDB_CONVERT 16 /** Convert endian (internal use) */ +#define TDB_BIGENDIAN 32 /** Header is big-endian (internal use) */ +#define TDB_NOSYNC 64 /** Don't use synchronous transactions */ +#define TDB_SEQNUM 128 /** Maintain a sequence number */ +#define TDB_VOLATILE 256 /** Activate the per-hashchain freelist, default 5 */ +#define TDB_ALLOW_NESTING 512 /** Allow transactions to nest */ +#define TDB_DISALLOW_NESTING 1024 /** Disallow transactions to nest */ +#define TDB_INCOMPATIBLE_HASH 2048 /** Better hashing: can't be opened by tdb < 1.2.6. */ + +/** The tdb error codes */ enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY, TDB_ERR_NESTING}; -/* debugging uses one of the following levels */ +/** Debugging uses one of the following levels */ enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; +/** The tdb data structure */ typedef struct TDB_DATA { unsigned char *dptr; size_t dsize; @@ -84,7 +109,7 @@ typedef struct TDB_DATA { #endif #endif -/* this is the context structure that is returned from a db open */ +/** This is the context structure that is returned from a db open. */ typedef struct tdb_context TDB_CONTEXT; typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); @@ -96,89 +121,724 @@ struct tdb_logging_context { void *log_private; }; -_PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, +/** + * @brief Open the database and creating it if necessary. + * + * @param[in] name The name of the db to open. + * + * @param[in] hash_size The hash size is advisory, use zero for a default + * value. + * + * @param[in] tdb_flags The flags to use to open the db:\n\n + * TDB_CLEAR_IF_FIRST - Clear database if we are the + * only one with it open\n + * TDB_INTERNAL - Don't use a file, instaed store the + * data in memory. The filename is + * ignored in this case.\n + * TDB_NOLOCK - Don't do any locking\n + * TDB_NOMMAP - Don't use mmap\n + * TDB_NOSYNC - Don't synchronise transactions to disk\n + * TDB_SEQNUM - Maintain a sequence number\n + * TDB_VOLATILE - activate the per-hashchain freelist, + * default 5.\n + * TDB_ALLOW_NESTING - Allow transactions to nest.\n + * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n + * + * @param[in] open_flags Flags for the open(2) function. + * + * @param[in] mode The mode for the open(2) function. + * + * @return A tdb context structure, NULL on error. + */ +struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); -_PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + +/** + * @brief Open the database and creating it if necessary. + * + * This is like tdb_open(), but allows you to pass an initial logging and + * hash function. Be careful when passing a hash function - all users of the + * database must use the same hash function or you will get data corruption. + * + * @param[in] name The name of the db to open. + * + * @param[in] hash_size The hash size is advisory, use zero for a default + * value. + * + * @param[in] tdb_flags The flags to use to open the db:\n\n + * TDB_CLEAR_IF_FIRST - Clear database if we are the + * only one with it open\n + * TDB_INTERNAL - Don't use a file, instaed store the + * data in memory. The filename is + * ignored in this case.\n + * TDB_NOLOCK - Don't do any locking\n + * TDB_NOMMAP - Don't use mmap\n + * TDB_NOSYNC - Don't synchronise transactions to disk\n + * TDB_SEQNUM - Maintain a sequence number\n + * TDB_VOLATILE - activate the per-hashchain freelist, + * default 5.\n + * TDB_ALLOW_NESTING - Allow transactions to nest.\n + * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n + * + * @param[in] open_flags Flags for the open(2) function. + * + * @param[in] mode The mode for the open(2) function. + * + * @param[in] log_ctx The logging function to use. + * + * @param[in] hash_fn The hash function you want to use. + * + * @return A tdb context structure, NULL on error. + * + * @see tdb_open() + */ +struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode, const struct tdb_logging_context *log_ctx, tdb_hash_func hash_fn); -_PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); - -_PUBLIC_ int tdb_reopen(struct tdb_context *tdb); -_PUBLIC_ int tdb_reopen_all(int parent_longlived); -_PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); -_PUBLIC_ enum TDB_ERROR tdb_error(struct tdb_context *tdb); -_PUBLIC_ const char *tdb_errorstr(struct tdb_context *tdb); -_PUBLIC_ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, + +/** + * @brief Set the maximum number of dead records per hash chain. + * + * @param[in] tdb The database handle to set the maximum. + * + * @param[in] max_dead The maximum number of dead records per hash chain. + */ +void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); + +/** + * @brief Reopen a tdb. + * + * This can be used after a fork to ensure that we have an independent seek + * pointer from our parent and to re-establish locks. + * + * @param[in] tdb The database to reopen. + * + * @return 0 on success, -1 on error. + */ +int tdb_reopen(struct tdb_context *tdb); + +/** + * @brief Reopen all tdb's + * + * If the parent is longlived (ie. a parent daemon architecture), we know it + * will keep it's active lock on a tdb opened with CLEAR_IF_FIRST. Thus for + * child processes we don't have to add an active lock. This is essential to + * improve performance on systems that keep POSIX locks as a non-scalable data + * structure in the kernel. + * + * @param[in] parent_longlived Wether the parent is longlived or not. + * + * @return 0 on success, -1 on error. + */ +int tdb_reopen_all(int parent_longlived); + +/** + * @brief Set a different tdb logging function. + * + * @param[in] tdb The tdb to set the logging function. + * + * @param[in] log_ctx The logging function to set. + */ +void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); + +/** + * @brief Get the tdb last error code. + * + * @param[in] tdb The tdb to get the error code from. + * + * @return A TDB_ERROR code. + * + * @see TDB_ERROR + */ +enum TDB_ERROR tdb_error(struct tdb_context *tdb); + +/** + * @brief Get a error string for the last tdb error + * + * @param[in] tdb The tdb to get the error code from. + * + * @return An error string. + */ +const char *tdb_errorstr(struct tdb_context *tdb); + +/** + * @brief Fetch an entry in the database given a key. + * + * The caller must free the resulting data. + * + * @param[in] tdb The tdb to fetch the key. + * + * @param[in] key The key to fetch. + * + * @return The key entry found in the database, NULL on error with + * TDB_ERROR set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); + +/** + * @brief Hand a record to a parser function without allocating it. + * + * This function is meant as a fast tdb_fetch alternative for large records + * that are frequently read. The "key" and "data" arguments point directly + * into the tdb shared memory, they are not aligned at any boundary. + * + * @warning The parser is called while tdb holds a lock on the record. DO NOT + * call other tdb routines from within the parser. Also, for good performance + * you should make the parser fast to allow parallel operations. + * + * @param[in] tdb The tdb to parse the record. + * + * @param[in] key The key to parse. + * + * @param[in] parser The parser to use to parse the data. + * + * @param[in] private_data A private data pointer which is passed to the parser + * function. + * + * @return -1 if the record was not found. If the record was found, + * the return value of "parser" is passed up to the caller. + */ +int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, int (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); -_PUBLIC_ int tdb_delete(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); -_PUBLIC_ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); -_PUBLIC_ int tdb_close(struct tdb_context *tdb); -_PUBLIC_ TDB_DATA tdb_firstkey(struct tdb_context *tdb); -_PUBLIC_ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *); -_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *); -_PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_lockall(struct tdb_context *tdb); -_PUBLIC_ int tdb_lockall_nonblock(struct tdb_context *tdb); -_PUBLIC_ int tdb_unlockall(struct tdb_context *tdb); -_PUBLIC_ int tdb_lockall_read(struct tdb_context *tdb); -_PUBLIC_ int tdb_lockall_read_nonblock(struct tdb_context *tdb); -_PUBLIC_ int tdb_unlockall_read(struct tdb_context *tdb); -_PUBLIC_ int tdb_lockall_mark(struct tdb_context *tdb); -_PUBLIC_ int tdb_lockall_unmark(struct tdb_context *tdb); -_PUBLIC_ const char *tdb_name(struct tdb_context *tdb); -_PUBLIC_ int tdb_fd(struct tdb_context *tdb); -_PUBLIC_ tdb_log_func tdb_log_fn(struct tdb_context *tdb); -_PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_start(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_start_nonblock(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_prepare_commit(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_commit(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_cancel(struct tdb_context *tdb); -_PUBLIC_ int tdb_get_seqnum(struct tdb_context *tdb); -_PUBLIC_ int tdb_hash_size(struct tdb_context *tdb); -_PUBLIC_ size_t tdb_map_size(struct tdb_context *tdb); -_PUBLIC_ int tdb_get_flags(struct tdb_context *tdb); -_PUBLIC_ void tdb_add_flags(struct tdb_context *tdb, unsigned flag); -_PUBLIC_ void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); -_PUBLIC_ void tdb_enable_seqnum(struct tdb_context *tdb); -_PUBLIC_ void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); -_PUBLIC_ unsigned int tdb_jenkins_hash(TDB_DATA *key); -_PUBLIC_ int tdb_check(struct tdb_context *tdb, - int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), + +/** + * @brief Delete an entry in the database given a key. + * + * @param[in] tdb The tdb to delete the key. + * + * @param[in] key The key to delete. + * + * @return 0 on success, -1 if the key doesn't exist. + */ +int tdb_delete(struct tdb_context *tdb, TDB_DATA key); + +/** + * @brief Store an element in the database. + * + * This replaces any existing element with the same key. + * + * @param[in] tdb The tdb to store the entry. + * + * @param[in] key The key to use to store the entry. + * + * @param[in] dbuf The data to store under the key. + * + * @param[in] flag The flags to store the key:\n\n + * TDB_INSERT: Don't overwrite an existing entry.\n + * TDB_MODIFY: Don't create a new entry\n + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); + +/** + * @brief Append data to an entry. + * + * If the entry doesn't exist, it will create a new one. + * + * @param[in] tdb The database to use. + * + * @param[in] key The key to append the data. + * + * @param[in] new_dbuf The data to append to the key. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); + +/** + * @brief Close a database. + * + * @param[in] tdb The database to close. + * + * @return 0 for success, -1 on error. + */ +int tdb_close(struct tdb_context *tdb); + +/** + * @brief Find the first entry in the database and return its key. + * + * The caller must free the returned data. + * + * @param[in] tdb The database to use. + * + * @return The first entry of the database, an empty TDB_DATA entry + * if the database is empty. + */ +TDB_DATA tdb_firstkey(struct tdb_context *tdb); + +/** + * @brief Find the next entry in the database, returning its key. + * + * The caller must free the returned data. + * + * @param[in] tdb The database to use. + * + * @param[in] key The key from which you want the next key. + * + * @return The next entry of the current key, an empty TDB_DATA + * entry if there is no entry. + */ +TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); + +/** + * @brief Traverse the entire database. + * + * While travering the function fn(tdb, key, data, state) is called on each + * element. If fn is NULL then it is not called. A non-zero return value from + * fn() indicates that the traversal should stop. Traversal callbacks may not + * start transactions. + * + * @warning The data buffer given to the callback fn does NOT meet the alignment + * restrictions malloc gives you. + * + * @param[in] tdb The database to traverse. + * + * @param[in] fn The function to call on each entry. + * + * @param[in] private_data The private data which should be passed to the + * traversing function. + * + * @return The record count traversed, -1 on error. + */ +int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); + +/** + * @brief Traverse the entire database. + * + * While traversing the database the function fn(tdb, key, data, state) is + * called on each element, but marking the database read only during the + * traversal, so any write operations will fail. This allows tdb to use read + * locks, which increases the parallelism possible during the traversal. + * + * @param[in] tdb The database to traverse. + * + * @param[in] fn The function to call on each entry. + * + * @param[in] private_data The private data which should be passed to the + * traversing function. + * + * @return The record count traversed, -1 on error. + */ +int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); + +/** + * @brief Check if an entry in the database exists. + * + * @note 1 is returned if the key is found and 0 is returned if not found this + * doesn't match the conventions in the rest of this module, but is compatible + * with gdbm. + * + * @param[in] tdb The database to check if the entry exists. + * + * @param[in] key The key to check if the entry exists. + * + * @return 1 if the key is found, 0 if not. + */ +int tdb_exists(struct tdb_context *tdb, TDB_DATA key); + +/** + * @brief Lock entire database with a write lock. + * + * @param[in] tdb The database to lock. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_lockall(struct tdb_context *tdb); + +/** + * @brief Lock entire database with a write lock. + * + * This is the non-blocking call. + * + * @param[in] tdb The database to lock. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_lockall() + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_lockall_nonblock(struct tdb_context *tdb); + +/** + * @brief Unlock entire database with write lock. + * + * @param[in] tdb The database to unlock. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_lockall() + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_unlockall(struct tdb_context *tdb); + +/** + * @brief Lock entire database with a read lock. + * + * @param[in] tdb The database to lock. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_lockall_read(struct tdb_context *tdb); + +/** + * @brief Lock entire database with a read lock. + * + * This is the non-blocking call. + * + * @param[in] tdb The database to lock. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_lockall_read() + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_lockall_read_nonblock(struct tdb_context *tdb); + +/** + * @brief Unlock entire database with read lock. + * + * @param[in] tdb The database to unlock. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_lockall_read() + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_unlockall_read(struct tdb_context *tdb); + +/** + * @brief Lock entire database with write lock - mark only. + * + * @todo Add more details. + * + * @param[in] tdb The database to mark. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_lockall_mark(struct tdb_context *tdb); + +/** + * @brief Lock entire database with write lock - unmark only. + * + * @todo Add more details. + * + * @param[in] tdb The database to mark. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_lockall_unmark(struct tdb_context *tdb); + +/** + * @brief Get the name of the current tdb file. + * + * This is useful for external logging functions. + * + * @param[in] tdb The database to get the name from. + * + * @return The name of the database. + */ +const char *tdb_name(struct tdb_context *tdb); + +/** + * @brief Get the underlying file descriptor being used by tdb. + * + * This is useful for external routines that want to check the device/inode + * of the fd. + * + * @param[in] tdb The database to get the fd from. + * + * @return The file descriptor or -1. + */ +int tdb_fd(struct tdb_context *tdb); + +/** + * @brief Get the current logging function. + * + * This is useful for external tdb routines that wish to log tdb errors. + * + * @param[in] tdb The database to get the logging function from. + * + * @return The logging function of the database. + * + * @see tdb_get_logging_private() + */ +tdb_log_func tdb_log_fn(struct tdb_context *tdb); + +/** + * @brief Get the private data of the logging function. + * + * @param[in] tdb The database to get the data from. + * + * @return The private data pointer of the logging function. + * + * @see tdb_log_fn() + */ +void *tdb_get_logging_private(struct tdb_context *tdb); + +/** + * @brief Start a transaction. + * + * All operations after the transaction start can either be committed with + * tdb_transaction_commit() or cancelled with tdb_transaction_cancel(). + * + * If you call tdb_transaction_start() again on the same tdb context while a + * transaction is in progress, then the same transaction buffer is re-used. The + * number of tdb_transaction_{commit,cancel} operations must match the number + * of successful tdb_transaction_start() calls. + * + * Note that transactions are by default disk synchronous, and use a recover + * area in the database to automatically recover the database on the next open + * if the system crashes during a transaction. You can disable the synchronous + * transaction recovery setup using the TDB_NOSYNC flag, which will greatly + * speed up operations at the risk of corrupting your database if the system + * crashes. + * + * Operations made within a transaction are not visible to other users of the + * database until a successful commit. + * + * @param[in] tdb The database to start the transaction. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_transaction_start(struct tdb_context *tdb); + +/** + * @brief Start a transaction, non-blocking. + * + * @param[in] tdb The database to start the transaction. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + * @see tdb_transaction_start() + */ +int tdb_transaction_start_nonblock(struct tdb_context *tdb); + +/** + * @brief Prepare to commit a current transaction, for two-phase commits. + * + * Once prepared for commit, the only allowed calls are tdb_transaction_commit() + * or tdb_transaction_cancel(). Preparing allocates disk space for the pending + * updates, so a subsequent commit should succeed (barring any hardware + * failures). + * + * @param[in] tdb The database to prepare the commit. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_transaction_prepare_commit(struct tdb_context *tdb); + +/** + * @brief Commit a current transaction. + * + * This updates the database and releases the current transaction locks. + * + * @param[in] tdb The database to commit the transaction. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_transaction_commit(struct tdb_context *tdb); + +/** + * @brief Cancel a current transaction. + * + * This discards all write and lock operations that have been made since the + * transaction started. + * + * @param[in] tdb The tdb to cancel the transaction on. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_transaction_cancel(struct tdb_context *tdb); + +/** + * @brief Get the tdb sequence number. + * + * Only makes sense if the writers opened with TDB_SEQNUM set. Note that this + * sequence number will wrap quite quickly, so it should only be used for a + * 'has something changed' test, not for code that relies on the count of the + * number of changes made. If you want a counter then use a tdb record. + * + * The aim of this sequence number is to allow for a very lightweight test of a + * possible tdb change. + * + * @param[in] tdb The database to get the sequence number from. + * + * @return The sequence number or 0. + * + * @see tdb_open() + * @see tdb_enable_seqnum() + */ +int tdb_get_seqnum(struct tdb_context *tdb); + +/** + * @brief Get the hash size. + * + * @param[in] tdb The database to get the hash size from. + * + * @return The hash size. + */ +int tdb_hash_size(struct tdb_context *tdb); + +/** + * @brief Get the map size. + * + * @param[in] tdb The database to get the map size from. + * + * @return The map size. + */ +size_t tdb_map_size(struct tdb_context *tdb); + +/** + * @brief Get the tdb flags set during open. + * + * @param[in] tdb The database to get the flags form. + * + * @return The flags set to on the database. + */ +int tdb_get_flags(struct tdb_context *tdb); + +/** + * @brief Add flags to the database. + * + * @param[in] tdb The database to add the flags. + * + * @param[in] flag The tdb flags to add. + */ +void tdb_add_flags(struct tdb_context *tdb, unsigned flag); + +/** + * @brief Remove flags from the database. + * + * @param[in] tdb The database to remove the flags. + * + * @param[in] flag The tdb flags to remove. + */ +void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); + +/** + * @brief Enable sequence number handling on an open tdb. + * + * @param[in] tdb The database to enable sequence number handling. + * + * @see tdb_get_seqnum() + */ +void tdb_enable_seqnum(struct tdb_context *tdb); + +/** + * @brief Increment the tdb sequence number. + * + * This only works if the tdb has been opened using the TDB_SEQNUM flag or + * enabled useing tdb_enable_seqnum(). + * + * @param[in] tdb The database to increment the sequence number. + * + * @see tdb_enable_seqnum() + * @see tdb_get_seqnum() + */ +void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); + +/** + * @brief Create a hash of the key. + * + * @param[in] key The key to hash + * + * @return The hash. + */ +unsigned int tdb_jenkins_hash(TDB_DATA *key); + +/** + * @brief Check the consistency of the database. + * + * This check the consistency of the database calling back the check function + * (if non-NULL) on each record. If some consistency check fails, or the + * supplied check function returns -1, tdb_check returns -1, otherwise 0. + * + * @note The logging function (if set) will be called with additional + * information on the corruption found. + * + * @param[in] tdb The database to check. + * + * @param[in] check The check function to use. + * + * @param[in] private_data the private data to pass to the check function. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_check(struct tdb_context *tdb, + int (*check) (TDB_DATA key, TDB_DATA data, void *private_data), void *private_data); +/* @} ******************************************************************/ + /* Low level locking functions: use with care */ -_PUBLIC_ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key); -_PUBLIC_ int tdb_transaction_write_lock(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_write_unlock(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_write_lock_mark(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb); - -_PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr); +int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key); +int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key); + +void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr); /* wipe and repack */ -_PUBLIC_ int tdb_wipe_all(struct tdb_context *tdb); -_PUBLIC_ int tdb_repack(struct tdb_context *tdb); +int tdb_wipe_all(struct tdb_context *tdb); +int tdb_repack(struct tdb_context *tdb); /* Debug functions. Not used in production. */ -_PUBLIC_ void tdb_dump_all(struct tdb_context *tdb); -_PUBLIC_ int tdb_printfreelist(struct tdb_context *tdb); -_PUBLIC_ int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); -_PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb); +void tdb_dump_all(struct tdb_context *tdb); +int tdb_printfreelist(struct tdb_context *tdb); +int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); +int tdb_freelist_size(struct tdb_context *tdb); +char *tdb_summary(struct tdb_context *tdb); -_PUBLIC_ extern TDB_DATA tdb_null; +extern TDB_DATA tdb_null; #ifdef __cplusplus } diff --git a/ctdb/lib/tdb/install-sh b/ctdb/lib/tdb/install-sh deleted file mode 100755 index 58719246f04..00000000000 --- a/ctdb/lib/tdb/install-sh +++ /dev/null @@ -1,238 +0,0 @@ -#! /bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. -# - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/ctdb/lib/tdb/pytdb.c b/ctdb/lib/tdb/pytdb.c index b857438e16e..48927522f3a 100644 --- a/ctdb/lib/tdb/pytdb.c +++ b/ctdb/lib/tdb/pytdb.c @@ -9,7 +9,7 @@ ** NOTE! The following LGPL license applies to the tdb ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -41,7 +41,7 @@ typedef struct { bool closed; } PyTdbObject; -PyAPI_DATA(PyTypeObject) PyTdb; +staticforward PyTypeObject PyTdb; static void PyErr_SetTDBError(TDB_CONTEXT *tdb) { @@ -479,7 +479,7 @@ static void tdb_object_dealloc(PyTdbObject *self) { if (!self->closed) tdb_close(self->ctx); - PyObject_Del(self); + self->ob_type->tp_free(self); } static PyObject *obj_getitem(PyTdbObject *self, PyObject *key) @@ -538,8 +538,8 @@ static PyMappingMethods tdb_object_mapping = { .mp_subscript = (binaryfunc)obj_getitem, .mp_ass_subscript = (objobjargproc)obj_setitem, }; -PyTypeObject PyTdb = { - .tp_name = "Tdb", +static PyTypeObject PyTdb = { + .tp_name = "tdb.Tdb", .tp_basicsize = sizeof(PyTdbObject), .tp_methods = tdb_object_methods, .tp_getset = tdb_object_getsetters, @@ -558,6 +558,7 @@ static PyMethodDef tdb_methods[] = { { NULL } }; +void inittdb(void); void inittdb(void) { PyObject *m; @@ -568,7 +569,8 @@ void inittdb(void) if (PyType_Ready(&PyTdbIterator) < 0) return; - m = Py_InitModule3("tdb", tdb_methods, "TDB is a simple key-value database similar to GDBM that supports multiple writers."); + m = Py_InitModule3("tdb", tdb_methods, + "simple key-value database that supports multiple writers."); if (m == NULL) return; diff --git a/ctdb/lib/tdb/python.mk b/ctdb/lib/tdb/python.mk deleted file mode 100644 index 1f2d4ca4a8e..00000000000 --- a/ctdb/lib/tdb/python.mk +++ /dev/null @@ -1,6 +0,0 @@ -[PYTHON::pytdb] -LIBRARY_REALNAME = tdb.$(SHLIBEXT) -PUBLIC_DEPENDENCIES = LIBTDB DYNCONFIG - -pytdb_OBJ_FILES = $(tdbsrcdir)/pytdb.o - diff --git a/ctdb/lib/tdb/python/tests/simple.py b/ctdb/lib/tdb/python/tests/simple.py index 615de494b51..2877092fe31 100644 --- a/ctdb/lib/tdb/python/tests/simple.py +++ b/ctdb/lib/tdb/python/tests/simple.py @@ -12,13 +12,21 @@ import os, tempfile class OpenTdbTests(TestCase): + def test_nonexistant_read(self): - self.assertRaises(IOError, tdb.Tdb, "/some/nonexistant/file", 0, tdb.DEFAULT, os.O_RDWR) + self.assertRaises(IOError, tdb.Tdb, "/some/nonexistant/file", 0, + tdb.DEFAULT, os.O_RDWR) class CloseTdbTests(TestCase): def test_double_close(self): - self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) + # No hash size in tdb2. + if tdb.__version__.startswith("2"): + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) + else: + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) # ensure that double close does not crash python @@ -36,9 +44,15 @@ class InternalTdbTests(TestCase): class SimpleTdbTests(TestCase): + def setUp(self): super(SimpleTdbTests, self).setUp() - self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) + if tdb.__version__.startswith("2"): + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) + else: + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) self.assertNotEqual(None, self.tdb) def tearDown(self): @@ -51,7 +65,8 @@ class SimpleTdbTests(TestCase): self.tdb.lock_all() def test_max_dead(self): - self.tdb.max_dead = 20 + if not tdb.__version__.startswith("2"): + self.tdb.max_dead = 20 def test_unlockall(self): self.tdb.lock_all() @@ -62,7 +77,8 @@ class SimpleTdbTests(TestCase): self.tdb.read_unlock_all() def test_reopen(self): - self.tdb.reopen() + if not tdb.__version__.startswith("2"): + self.tdb.reopen() def test_store(self): self.tdb.store("bar", "bla") @@ -70,7 +86,8 @@ class SimpleTdbTests(TestCase): def test_getitem(self): self.tdb["bar"] = "foo" - self.tdb.reopen() + if not tdb.__version__.startswith("2"): + self.tdb.reopen() self.assertEquals("foo", self.tdb["bar"]) def test_delete(self): @@ -86,13 +103,16 @@ class SimpleTdbTests(TestCase): self.assertRaises(KeyError, lambda: self.tdb["bla"]) def test_hash_size(self): - self.tdb.hash_size + if not tdb.__version__.startswith("2"): + self.tdb.hash_size def test_map_size(self): - self.tdb.map_size + if not tdb.__version__.startswith("2"): + self.tdb.map_size def test_freelist_size(self): - self.tdb.freelist_size + if not tdb.__version__.startswith("2"): + self.tdb.freelist_size def test_name(self): self.tdb.filename @@ -100,7 +120,9 @@ class SimpleTdbTests(TestCase): def test_iterator(self): self.tdb["bla"] = "1" self.tdb["brainslug"] = "2" - self.assertEquals(["bla", "brainslug"], list(self.tdb)) + l = list(self.tdb) + l.sort() + self.assertEquals(["bla", "brainslug"], l) def test_transaction_cancel(self): self.tdb["bloe"] = "2" @@ -138,17 +160,19 @@ class SimpleTdbTests(TestCase): self.assertEquals(0, len(list(self.tdb))) def test_repack(self): - self.tdb["foo"] = "abc" - self.tdb["bar"] = "def" - del self.tdb["foo"] - self.tdb.repack() + if not tdb.__version__.startswith("2"): + self.tdb["foo"] = "abc" + self.tdb["bar"] = "def" + del self.tdb["foo"] + self.tdb.repack() def test_seqnum(self): - self.tdb.enable_seqnum() - seq1 = self.tdb.seqnum - self.tdb.increment_seqnum_nonblock() - seq2 = self.tdb.seqnum - self.assertEquals(seq2-seq1, 1) + if not tdb.__version__.startswith("2"): + self.tdb.enable_seqnum() + seq1 = self.tdb.seqnum + self.tdb.increment_seqnum_nonblock() + seq2 = self.tdb.seqnum + self.assertEquals(seq2-seq1, 1) def test_len(self): self.assertEquals(0, len(list(self.tdb))) @@ -156,8 +180,12 @@ class SimpleTdbTests(TestCase): self.assertEquals(1, len(list(self.tdb))) def test_add_flags(self): - self.tdb.add_flags(tdb.NOMMAP) - self.tdb.remove_flags(tdb.NOMMAP) + if tdb.__version__.startswith("2"): + self.tdb.add_flag(tdb.NOMMAP) + self.tdb.remove_flag(tdb.NOMMAP) + else: + self.tdb.add_flags(tdb.NOMMAP) + self.tdb.remove_flags(tdb.NOMMAP) class VersionTests(TestCase): diff --git a/ctdb/lib/tdb/rules.mk b/ctdb/lib/tdb/rules.mk deleted file mode 100644 index 023e0ce5341..00000000000 --- a/ctdb/lib/tdb/rules.mk +++ /dev/null @@ -1,16 +0,0 @@ -showflags:: - @echo 'tdb will be compiled with flags:' - @echo ' CFLAGS = $(CFLAGS)' - @echo ' CPPFLAGS = $(CPPFLAGS)' - @echo ' LDFLAGS = $(LDFLAGS)' - @echo ' LIBS = $(LIBS)' - -.SUFFIXES: .c .o - -.c.o: - @echo Compiling $*.c - @mkdir -p `dirname $@` - @$(CC) $(PICFLAG) $(CFLAGS) $(ABI_CHECK) -c $< -o $@ - -distclean:: - rm -f *~ */*~ diff --git a/ctdb/lib/tdb/script/abi_checks.sh b/ctdb/lib/tdb/script/abi_checks.sh deleted file mode 100755 index ba60ed003a9..00000000000 --- a/ctdb/lib/tdb/script/abi_checks.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/sh - -# -# abi_checks.sh - check for possible abi changes -# -# Copyright (C) 2009 Michael Adam <obnox@samba.org> -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, see <http://www.gnu.org/licenses/>. -# - -# -# USAGE: abi_checks.sh LIBNAME header1 [header2 ...] -# -# This script creates symbol and signature lists from the provided header -# files with the aid of the mksyms.sh and mksigs.pl scripts (saved as -# $LIBNAME.exports.check and $LIBNAME.sigatures.check). It then compares -# the resulting files with the files $LIBNAME.exports and $LIBNME.signatures -# which it expects to find in the current directory. -# - -LANG=C; export LANG -LC_ALL=C; export LC_ALL -LC_COLLATE=C; export LC_COLLATE - -script=$0 -dir_name=$(dirname ${script}) - -if test x"$1" = "x" ; then - echo "USAGE: ${script} libname header [header ...]" - exit 1 -fi - -libname="$1" -shift - -if test x"$1" = "x" ; then - echo "USAGE: ${script} libname header [header ...]" - exit 1 -fi - -headers="$*" - -exports_file=${libname}.exports -exports_file_check=${exports_file}.check -signatures_file=${libname}.signatures -signatures_file_check=${signatures_file}.check - - -${dir_name}/mksyms.sh awk ${exports_file_check} ${headers} 2>&1 > /dev/null - -cat ${headers} | ${dir_name}/mksigs.pl > ${signatures_file_check} 2> /dev/null - -normalize_exports_file() { - filename=$1 - cat ${filename} \ - | sed -e 's/^[ \t]*//g' \ - | sed -e 's/^$//g' \ - | sed -e 's/^#.*$//g' \ - | sort | uniq > ${filename}.sort -} - -normalize_exports_file ${exports_file} -normalize_exports_file ${exports_file_check} - -normalize_exports_file ${signatures_file} -normalize_exports_file ${signatures_file_check} - -diff -u ${exports_file}.sort ${exports_file_check}.sort -if test "x$?" != "x0" ; then - echo "WARNING: possible ABI change detected in exports!" -else - echo "exports check: OK" -fi - -diff -u ${signatures_file}.sort ${signatures_file_check}.sort -if test "x$?" != "x0" ; then - echo "WARNING: possible ABI change detected in signatures!" -else - echo "signatures check: OK" -fi diff --git a/ctdb/lib/tdb/script/abi_checks_gcc.sh b/ctdb/lib/tdb/script/abi_checks_gcc.sh deleted file mode 100755 index f0e02f48255..00000000000 --- a/ctdb/lib/tdb/script/abi_checks_gcc.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -make clean - -mkdir -p abi/common -mkdir -p abi/tools -ABI_CHECKS="-aux-info abi/\$@.X" -make ABI_CHECK="$ABI_CHECKS" CC="/usr/bin/gcc" - -for i in abi/*/*.X; do cat $i | grep 'tdb\.h'; done | sort | uniq | awk -F "extern " '{ print $2 }' | sort > abi/signatures -grep '^extern' include/tdb.h | grep -v '"C"' | sort | uniq | awk -F "extern " '{ print $2 }' >> abi/signatures - -cat > abi/exports << EOF -{ - global: -EOF -#Functions -cat abi/signatures | grep "(" | awk -F '(' '{ print $1 }' | awk -F ' ' '{ print " "$NF";" }' | tr -d '*' | sort >> abi/exports -#global vars -cat abi/signatures | grep -v "(" | awk -F ';' '{print $1 }' | awk -F ' ' '{ print " "$NF";" }' | tr -d '*' | sort >> abi/exports -cat >> abi/exports << EOF - - local: *; -}; -EOF - -diff -u tdb.signatures abi/signatures -if [ "$?" != "0" ]; then - echo "WARNING: Possible ABI Change!!" -fi - -diff -u tdb.exports abi/exports -if [ "$?" != "0" ]; then - echo "WARNING: Export file may be outdated!!" -fi diff --git a/ctdb/lib/tdb/script/mksigs.pl b/ctdb/lib/tdb/script/mksigs.pl deleted file mode 100755 index 755cd796039..00000000000 --- a/ctdb/lib/tdb/script/mksigs.pl +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/perl - -# mksigs.pl - extract signatures from C headers -# -# Copyright (C) Michael Adam 2009 -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -# more details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, see <http://www.gnu.org/licenses/>. - -# USAGE: cat $header_files | mksigs.pl > $signature_file -# -# The header files to parse are read from stdin. -# The output is in a form as produced by gcc with the -aux-info switch -# and printed to stdout. - -use strict; -use warnings; - -my $in_comment = 0; -my $extern_C_block = 0; - -while (my $LINE = <>) { - # find end of started multi-line-comment - if ($in_comment) { - if ($LINE =~ /^.*?\*\/(.*)$/) { - $LINE = $1; - $in_comment = 0; - } else { - # whole line within comment - next; - } - } - - # strip C++-style comments - $LINE =~ s/^(.*?)\/\/.*$/$1/; - - # strip in-line-comments: - while ($LINE =~ /\/\*.*?\*\//) { - $LINE =~ s/\/\*.*?\*\///; - } - - # find starts of multi-line-comments - if ($LINE =~ /^(.*)\/\*/) { - $in_comment = 1; - $LINE = $1; - } - - # skip empty lines - next if $LINE =~ /^\s*$/; - - # remove leading spaces - $LINE =~ s/^\s*(.*)$/$1/; - - # concatenate lines split with "\" (usually macro defines) - while ($LINE =~ /^(.*?)\s+\\$/) { - my $LINE2 = <>; - $LINE = $1; - $LINE2 =~ s/^\s*(.*)$/$1/; - $LINE .= " " . $LINE2; - } - - # remove all preprocessor directives - next if ($LINE =~ /^#/); - - if ($LINE =~ /^extern\s+"C"\s+\{/) { - $extern_C_block = 1; - next; - } - - if (($LINE =~ /^[^\{]*\}/) and $extern_C_block) { - $extern_C_block = 0; - next; - } - - $LINE =~ s/^extern\s//; - - # concatenate braces stretched over multiple lines - # (from structs or enums) - my $REST = $LINE; - my $braces = 0; - while (($REST =~ /[\{\}]/) or ($braces)) { - while ($REST =~ /[\{\}]/) { - # collect opening - while ($REST =~ /^[^\{\}]*\{(.*)$/) { - $braces++; - $REST = $1; - } - - # collect closing - while ($REST =~ /^[^\{\}]*\}(.*)$/) { - $braces--; - $REST = $1; - } - } - - # concatenate if not balanced - if ($braces) { - if (my $LINE2 = <>) { - $LINE2 =~ s/^\s*(.*)$/$1/; - chomp($LINE); - $LINE .= " " . $LINE2; - chomp $REST; - $REST .= " " . $LINE2; - } else { - print "ERROR: unbalanced braces ($braces)\n"; - last; - } - } - } - - # concetenate function prototypes that stretch over multiple lines - $REST = $LINE; - my $parenthesis = 0; - while (($REST =~ /[\(\)]/) or ($parenthesis)) { - while ($REST =~ /[\(\)]/) { - # collect opening - while ($REST =~ /^[^\(\)]*\((.*)$/) { - $parenthesis++; - $REST = $1; - } - - # collect closing - while ($REST =~ /^[^\(\)]*\)(.*)$/) { - $parenthesis--; - $REST = $1; - } - } - - # concatenate if not balanced - if ($parenthesis) { - if (my $LINE2 = <>) { - $LINE2 =~ s/^\s*(.*)$/$1/; - chomp($LINE); - $LINE .= " " . $LINE2; - chomp($REST); - $REST .= " " . $LINE2; - } else { - print "ERROR: unbalanced parantheses ($parenthesis)\n"; - last; - } - } - } - - next if ($LINE =~ /^typedef\s/); - next if ($LINE =~ /^enum\s+[^\{\(]+\s+\{/); - next if ($LINE =~ /^struct\s+[^\{\(]+\s+\{.*\}\s*;/); - next if ($LINE =~ /^struct\s+[a-zA-Z0-9_]+\s*;/); - - # remove trailing spaces - $LINE =~ s/(.*?)\s*$/$1/; - - $LINE =~ s/^(.*\))\s+PRINTF_ATTRIBUTE\([^\)]*\)(\s*[;,])/$1$2/; - $LINE =~ s/^(.*\))\s*[a-zA-Z0-9_]+\s*;$/$1;/; - - # remove parameter names - slightly too coarse probably - $LINE =~ s/([\s\(]\*?)[_0-9a-zA-Z]+\s*([,\)])/$1$2/g; - - # remedy (void) from last line - $LINE =~ s/\(\)/(void)/g; - - # normalize spaces - $LINE =~ s/\s*\)\s*/)/g; - $LINE =~ s/\s*\(\s*/ (/g; - $LINE =~ s/\s*,\s*/, /g; - - # normalize unsigned - $LINE =~ s/([\s,\(])unsigned([,\)])/$1unsigned int$2/g; - - # normalize bool - $LINE =~ s/(\b)bool(\b)/_Bool/g; - - print $LINE . "\n"; -} diff --git a/ctdb/lib/tdb/script/mksyms.awk b/ctdb/lib/tdb/script/mksyms.awk deleted file mode 100644 index ca14da0f217..00000000000 --- a/ctdb/lib/tdb/script/mksyms.awk +++ /dev/null @@ -1,76 +0,0 @@ -# -# mksyms.awk -# -# Extract symbols to export from C-header files. -# output in version-script format for linking shared libraries. -# -# Copyright (C) 2008 Micheal Adam <obnox@samba.org> -# -BEGIN { - inheader=0; - current_file=""; - print "#" - print "# This file is automatically generated with \"make symbols\". DO NOT EDIT " - print "#" - print "{" - print "\tglobal:" -} - -END { - print"" - print "\tlocal: *;" - print "};" -} - -{ - if (FILENAME!=current_file) { - print "\t\t# The following definitions come from",FILENAME - current_file=FILENAME - } - if (inheader) { - if (match($0,"[)][^()]*[;][ \t]*$")) { - inheader = 0; - } - next; - } -} - -/^static/ || /^[ \t]*typedef/ || !/^[a-zA-Z\_]/ { - next; -} - -/^extern[ \t]+[^()]+[;][ \t]*$/ { - gsub(/[^ \t]+[ \t]+/, ""); - sub(/[;][ \t]*$/, ""); - printf "\t\t%s;\n", $0; - next; -} - -# look for function headers: -{ - gotstart = 0; - if ($0 ~ /^[A-Za-z_][A-Za-z0-9_]+/) { - gotstart = 1; - } - if(!gotstart) { - next; - } -} - -/[_A-Za-z0-9]+[ \t]*[(].*[)][^()]*;[ \t]*$/ { - sub(/[(].*$/, ""); - gsub(/[^ \t]+[ \t]+/, ""); - gsub(/^[*]+/, ""); - printf "\t\t%s;\n",$0; - next; -} - -/[_A-Za-z0-9]+[ \t]*[(]/ { - inheader=1; - sub(/[(].*$/, ""); - gsub(/[^ \t]+[ \t]+/, ""); - gsub(/^[*]/, ""); - printf "\t\t%s;\n",$0; - next; -} - diff --git a/ctdb/lib/tdb/script/mksyms.sh b/ctdb/lib/tdb/script/mksyms.sh deleted file mode 100755 index 714d55abae6..00000000000 --- a/ctdb/lib/tdb/script/mksyms.sh +++ /dev/null @@ -1,45 +0,0 @@ -#! /bin/sh - -# -# mksyms.sh -# -# Extract symbols to export from C-header files. -# output in version-script format for linking shared libraries. -# -# This is the shell wrapper for the mksyms.awk core script. -# -# Copyright (C) 2008 Micheal Adam <obnox@samba.org> -# - -LANG=C; export LANG -LC_ALL=C; export LC_ALL -LC_COLLATE=C; export LC_COLLATE - -if [ $# -lt 2 ] -then - echo "Usage: $0 awk output_file header_files" - exit 1 -fi - -awk="$1" -shift - -symsfile="$1" -shift -symsfile_tmp="$symsfile.$$.tmp~" - -proto_src="`echo $@ | tr ' ' '\n' | sort | uniq `" - -echo creating $symsfile - -mkdir -p `dirname $symsfile` - -${awk} -f `dirname $0`/mksyms.awk $proto_src > $symsfile_tmp - -if cmp -s $symsfile $symsfile_tmp 2>/dev/null -then - echo "$symsfile unchanged" - rm $symsfile_tmp -else - mv $symsfile_tmp $symsfile -fi diff --git a/ctdb/lib/tdb/script/release-script.sh b/ctdb/lib/tdb/script/release-script.sh deleted file mode 100644 index e9a023d7a51..00000000000 --- a/ctdb/lib/tdb/script/release-script.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -LNAME=tdb -LINCLUDE=include/tdb.h - -if [ "$1" = "" ]; then - echo "Please provide version string, eg: 1.2.0" - exit 1 -fi - -if [ ! -d "lib/${LNAME}" ]; then - echo "Run this script from the samba base directory." - exit 1 -fi - -curbranch=`git branch |grep "^*" | tr -d "* "` - -version=$1 -strver=`echo ${version} | tr "." "-"` - -# Checkout the release tag -git branch -f ${LNAME}-release-script-${strver} ${LNAME}-${strver} -if [ ! "$?" = "0" ]; then - echo "Unable to checkout ${LNAME}-${strver} release" - exit 1 -fi - -function cleanquit { - #Clean up - git checkout $curbranch - git branch -d ${LNAME}-release-script-${strver} - exit $1 -} - -# NOTE: use cleanquit after this point -git checkout ${LNAME}-release-script-${strver} - -# Test configure agrees with us -confver=`grep "^AC_INIT" lib/${LNAME}/configure.ac | tr -d "AC_INIT(${LNAME}, " | tr -d ")"` -if [ ! "$confver" = "$version" ]; then - echo "Wrong version, requested release for ${version}, found ${confver}" - exit 1 -fi - -# Check exports and signatures are up to date -pushd lib/${LNAME} -./script/abi_checks.sh ${LNAME} ${LINCLUDE} -abicheck=$? -popd -if [ ! "$abicheck" = "0" ]; then - echo "ERROR: ABI Checks produced warnings!" - cleanquit 1 -fi - -git clean -f -x -d lib/${LNAME} -git clean -f -x -d lib/replace - -# Now build tarball -cp -a lib/${LNAME} ${LNAME}-${version} -cp -a lib/replace ${LNAME}-${version}/libreplace -pushd ${LNAME}-${version} -./autogen.sh -popd -tar cvzf ${LNAME}-${version}.tar.gz ${LNAME}-${version} -rm -fr ${LNAME}-${version} - -cleanquit 0 diff --git a/ctdb/lib/tdb/tdb.exports b/ctdb/lib/tdb/tdb.exports deleted file mode 100644 index 73b8fd634c3..00000000000 --- a/ctdb/lib/tdb/tdb.exports +++ /dev/null @@ -1,65 +0,0 @@ -{ - global: - tdb_add_flags; - tdb_append; - tdb_chainlock; - tdb_chainlock_mark; - tdb_chainlock_nonblock; - tdb_chainlock_read; - tdb_chainlock_unmark; - tdb_chainunlock; - tdb_chainunlock_read; - tdb_check; - tdb_close; - tdb_delete; - tdb_dump_all; - tdb_enable_seqnum; - tdb_error; - tdb_errorstr; - tdb_exists; - tdb_fd; - tdb_fetch; - tdb_firstkey; - tdb_freelist_size; - tdb_get_flags; - tdb_get_logging_private; - tdb_get_seqnum; - tdb_hash_size; - tdb_increment_seqnum_nonblock; - tdb_lockall; - tdb_lockall_mark; - tdb_lockall_nonblock; - tdb_lockall_read; - tdb_lockall_read_nonblock; - tdb_lockall_unmark; - tdb_log_fn; - tdb_map_size; - tdb_name; - tdb_nextkey; - tdb_open; - tdb_open_ex; - tdb_parse_record; - tdb_printfreelist; - tdb_remove_flags; - tdb_reopen; - tdb_reopen_all; - tdb_repack; - tdb_setalarm_sigptr; - tdb_set_logging_function; - tdb_set_max_dead; - tdb_store; - tdb_transaction_cancel; - tdb_transaction_commit; - tdb_transaction_prepare_commit; - tdb_transaction_start; - tdb_transaction_start_nonblock; - tdb_traverse; - tdb_traverse_read; - tdb_unlockall; - tdb_unlockall_read; - tdb_validate_freelist; - tdb_wipe_all; - tdb_null; - - local: *; -}; diff --git a/ctdb/lib/tdb/tdb.mk b/ctdb/lib/tdb/tdb.mk deleted file mode 100644 index 3c52b7305b0..00000000000 --- a/ctdb/lib/tdb/tdb.mk +++ /dev/null @@ -1,92 +0,0 @@ -dirs:: - @mkdir -p bin common tools - -PROGS = bin/tdbtool$(EXEEXT) bin/tdbrestore$(EXEEXT) bin/tdbdump$(EXEEXT) bin/tdbbackup$(EXEEXT) -PROGS_NOINSTALL = bin/tdbtest$(EXEEXT) bin/tdbtorture$(EXEEXT) -ALL_PROGS = $(PROGS) $(PROGS_NOINSTALL) - -TDB_SONAME = libtdb.$(SHLIBEXT).1 -TDB_SOLIB = libtdb.$(SHLIBEXT).$(PACKAGE_VERSION) -TDB_STLIB = libtdb.a - -TDB_LIB = $(TDB_STLIB) - -bin/tdbtest$(EXEEXT): tools/tdbtest.o $(TDB_LIB) - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtest tools/tdbtest.o -L. -ltdb -lgdbm - -bin/tdbtool$(EXEEXT): tools/tdbtool.o $(TDB_LIB) - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtool tools/tdbtool.o -L. -ltdb - -bin/tdbtorture$(EXEEXT): tools/tdbtorture.o $(TDB_LIB) - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbtorture tools/tdbtorture.o -L. -ltdb - -bin/tdbdump$(EXEEXT): tools/tdbdump.o $(TDB_LIB) - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbdump tools/tdbdump.o -L. -ltdb - -bin/tdbrestore$(EXEEXT): tools/tdbrestore.o $(TDB_LIB) - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbrestore tools/tdbrestore.o -L. -ltdb $(TDB_DEPS) - -bin/tdbbackup$(EXEEXT): tools/tdbbackup.o $(TDB_LIB) - $(CC) $(CFLAGS) $(LDFLAGS) -o bin/tdbbackup tools/tdbbackup.o -L. -ltdb - -test:: abi_checks - -test:: bin/tdbtorture$(EXEEXT) $(TDB_SONAME) - $(LIB_PATH_VAR)=. bin/tdbtorture$(EXEEXT) - -abi_checks:: - @echo ABI checks: - @./script/abi_checks.sh tdb include/tdb.h - -clean:: - rm -f test.db test.tdb torture.tdb test.gdbm - rm -f $(TDB_SONAME) $(TDB_SOLIB) $(TDB_STLIB) libtdb.$(SHLIBEXT) - rm -f $(ALL_PROGS) tdb.pc - rm -f tdb.exports.sort tdb.exports.check tdb.exports.check.sort - rm -f tdb.signatures.sort tdb.signatures.check tdb.signatures.check.sort - -build-python:: tdb.$(SHLIBEXT) - -pytdb.o: $(tdbdir)/pytdb.c - $(CC) $(PICFLAG) -c $(tdbdir)/pytdb.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags` - -tdb.$(SHLIBEXT): libtdb.$(SHLIBEXT) pytdb.o - $(SHLD) $(SHLD_FLAGS) -o $@ pytdb.o -L. -ltdb `$(PYTHON_CONFIG) --ldflags` - -install:: installdirs installbin installheaders installlibs \ - $(PYTHON_INSTALL_TARGET) - -install-python:: build-python - mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` - cp tdb.$(SHLIBEXT) $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"` - -check-python:: build-python $(TDB_SONAME) - $(LIB_PATH_VAR)=. PYTHONPATH=".:$(tdbdir)" $(PYTHON) $(tdbdir)/python/tests/simple.py - -clean:: - rm -f tdb.$(SHLIBEXT) - -installdirs:: - mkdir -p $(DESTDIR)$(bindir) - mkdir -p $(DESTDIR)$(includedir) - mkdir -p $(DESTDIR)$(libdir) - mkdir -p $(DESTDIR)$(libdir)/pkgconfig - -installbin:: all installdirs - cp $(PROGS) $(DESTDIR)$(bindir) - -installheaders:: installdirs - cp $(srcdir)/include/tdb.h $(DESTDIR)$(includedir) - -installlibs:: all installdirs - cp tdb.pc $(DESTDIR)$(libdir)/pkgconfig - cp $(TDB_STLIB) $(TDB_SOLIB) $(DESTDIR)$(libdir) - -$(TDB_STLIB): $(TDB_OBJ) - ar -rv $(TDB_STLIB) $(TDB_OBJ) - -libtdb.$(SHLIBEXT): $(TDB_SOLIB) - ln -fs $< $@ - -$(TDB_SONAME): $(TDB_SOLIB) - ln -fs $< $@ diff --git a/ctdb/lib/tdb/tdb.signatures b/ctdb/lib/tdb/tdb.signatures deleted file mode 100644 index 2148479667a..00000000000 --- a/ctdb/lib/tdb/tdb.signatures +++ /dev/null @@ -1,61 +0,0 @@ -const char *tdb_errorstr (struct tdb_context *); -const char *tdb_name (struct tdb_context *); -enum TDB_ERROR tdb_error (struct tdb_context *); -int tdb_append (struct tdb_context *, TDB_DATA, TDB_DATA); -int tdb_chainlock_mark (struct tdb_context *, TDB_DATA); -int tdb_chainlock_nonblock (struct tdb_context *, TDB_DATA); -int tdb_chainlock_read (struct tdb_context *, TDB_DATA); -int tdb_chainlock (struct tdb_context *, TDB_DATA); -int tdb_chainlock_unmark (struct tdb_context *, TDB_DATA); -int tdb_chainunlock_read (struct tdb_context *, TDB_DATA); -int tdb_chainunlock (struct tdb_context *, TDB_DATA); -int tdb_close (struct tdb_context *); -int tdb_delete (struct tdb_context *, TDB_DATA); -int tdb_exists (struct tdb_context *, TDB_DATA); -int tdb_fd (struct tdb_context *); -int tdb_freelist_size (struct tdb_context *); -int tdb_get_flags (struct tdb_context *); -int tdb_get_seqnum (struct tdb_context *); -int tdb_hash_size (struct tdb_context *); -int tdb_lockall_mark (struct tdb_context *); -int tdb_lockall_nonblock (struct tdb_context *); -int tdb_lockall_read_nonblock (struct tdb_context *); -int tdb_lockall_read (struct tdb_context *); -int tdb_lockall (struct tdb_context *); -int tdb_lockall_unmark (struct tdb_context *); -int tdb_parse_record (struct tdb_context *, TDB_DATA, int (*) (TDB_DATA, TDB_DATA, void *), void *); -int tdb_printfreelist (struct tdb_context *); -int tdb_reopen_all (int); -int tdb_reopen (struct tdb_context *); -int tdb_repack (struct tdb_context *); -int tdb_store (struct tdb_context *, TDB_DATA, TDB_DATA, int); -int tdb_transaction_cancel (struct tdb_context *); -int tdb_transaction_commit (struct tdb_context *); -int tdb_transaction_prepare_commit (struct tdb_context *); -int tdb_transaction_recover (struct tdb_context *); -int tdb_transaction_start (struct tdb_context *); -int tdb_transaction_start_nonblock (struct tdb_context *); -int tdb_traverse_read (struct tdb_context *, tdb_traverse_func, void *); -int tdb_traverse (struct tdb_context *, tdb_traverse_func, void *); -int tdb_unlockall_read (struct tdb_context *); -int tdb_unlockall (struct tdb_context *); -int tdb_validate_freelist (struct tdb_context *, int *); -int tdb_wipe_all (struct tdb_context *); -size_t tdb_map_size (struct tdb_context *); -struct tdb_context *tdb_open (const char *, int, int, int, mode_t); -struct tdb_context *tdb_open_ex (const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func); -TDB_DATA tdb_fetch (struct tdb_context *, TDB_DATA); -TDB_DATA tdb_firstkey (struct tdb_context *); -TDB_DATA tdb_nextkey (struct tdb_context *, TDB_DATA); -tdb_log_func tdb_log_fn (struct tdb_context *); -void tdb_add_flags (struct tdb_context *, unsigned int); -void tdb_dump_all (struct tdb_context *); -void tdb_enable_seqnum (struct tdb_context *); -void *tdb_get_logging_private (struct tdb_context *); -void tdb_increment_seqnum_nonblock (struct tdb_context *); -void tdb_remove_flags (struct tdb_context *, unsigned int); -void tdb_setalarm_sigptr (struct tdb_context *, volatile sig_atomic_t *); -void tdb_set_logging_function (struct tdb_context *, const struct tdb_logging_context *); -void tdb_set_max_dead (struct tdb_context *, int); -int tdb_check (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *); -TDB_DATA tdb_null; diff --git a/ctdb/lib/tdb/tools/tdbbackup.c b/ctdb/lib/tdb/tools/tdbbackup.c index 6aca8dd99c5..11ecaa0290a 100644 --- a/ctdb/lib/tdb/tools/tdbbackup.c +++ b/ctdb/lib/tdb/tools/tdbbackup.c @@ -152,8 +152,9 @@ static int backup_tdb(const char *old_name, const char *new_name, int hash_size) return 1; } - if (tdb_transaction_start(tdb_new) != 0) { - printf("Failed to start transaction on new tdb\n"); + /* lock the backup tdb so that nobody else can change it */ + if (tdb_lockall(tdb_new) != 0) { + printf("Failed to lock backup tdb\n"); tdb_close(tdb); tdb_close(tdb_new); unlink(tmp_name); @@ -177,12 +178,16 @@ static int backup_tdb(const char *old_name, const char *new_name, int hash_size) /* close the old tdb */ tdb_close(tdb); - if (tdb_transaction_commit(tdb_new) != 0) { - fprintf(stderr, "Failed to commit new tdb\n"); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; + /* copy done, unlock the backup tdb */ + tdb_unlockall(tdb_new); + +#ifdef HAVE_FDATASYNC + if (fdatasync(tdb_fd(tdb_new)) != 0) { +#else + if (fsync(tdb_fd(tdb_new)) != 0) { +#endif + /* not fatal */ + fprintf(stderr, "failed to fsync backup file\n"); } /* close the new tdb and re-open read-only */ diff --git a/ctdb/lib/tdb/tools/tdbrestore.c b/ctdb/lib/tdb/tools/tdbrestore.c index 485c440df1f..8106cf9b06a 100644 --- a/ctdb/lib/tdb/tools/tdbrestore.c +++ b/ctdb/lib/tdb/tools/tdbrestore.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <assert.h> @@ -39,7 +38,7 @@ static int read_linehead(FILE *f) if (c == EOF) { return -1; } - if (c == '\(') { + if (c == '(') { break; } } @@ -171,7 +170,7 @@ static int read_rec(FILE *f, TDB_CONTEXT *tdb, int *eof) || (swallow(f, "}\n", NULL) == -1)) { goto fail; } - if (tdb_store(tdb, key, data, TDB_INSERT) == -1) { + if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { fprintf(stderr, "TDB error: %s\n", tdb_errorstr(tdb)); goto fail; } @@ -207,7 +206,6 @@ static int restore_tdb(const char *fname) fprintf(stderr, "Error closing tdb\n"); return 1; } - fprintf(stderr, "EOF\n"); return 0; } diff --git a/ctdb/lib/tdb/tools/tdbtest.c b/ctdb/lib/tdb/tools/tdbtest.c index 416bc50a5b0..44c78efda5c 100644 --- a/ctdb/lib/tdb/tools/tdbtest.c +++ b/ctdb/lib/tdb/tools/tdbtest.c @@ -215,16 +215,38 @@ static void merge_test(void) tdb_delete(db, key); } +static char *test_path(const char *filename) +{ + const char *prefix = getenv("TEST_DATA_PREFIX"); + + if (prefix) { + char *path = NULL; + int ret; + + ret = asprintf(&path, "%s/%s", prefix, filename); + if (ret == -1) { + return NULL; + } + return path; + } + + return strdup(filename); +} + int main(int argc, const char *argv[]) { int i, seed=0; int loops = 10000; int num_entries; - char test_gdbm[] = "test.gdbm"; + char test_gdbm[1] = "test.gdbm"; + char *test_tdb; - unlink("test.gdbm"); + test_gdbm[0] = test_path("test.gdbm"); + test_tdb = test_path("test.tdb"); - db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, + unlink(test_gdbm[0]); + + db = tdb_open(test_tdb, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT | O_TRUNC, 0600); gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST, 0600, NULL); @@ -261,5 +283,8 @@ static void merge_test(void) tdb_close(db); gdbm_close(gdbm); + free(test_gdbm[0]); + free(test_tdb); + return 0; } diff --git a/ctdb/lib/tdb/tools/tdbtool.c b/ctdb/lib/tdb/tools/tdbtool.c index b380883e0ac..dc5747f87aa 100644 --- a/ctdb/lib/tdb/tools/tdbtool.c +++ b/ctdb/lib/tdb/tools/tdbtool.c @@ -61,6 +61,7 @@ enum commands { CMD_NEXT, CMD_SYSTEM, CMD_CHECK, + CMD_REPACK, CMD_QUIT, CMD_HELP }; @@ -98,6 +99,7 @@ COMMAND_TABLE cmd_table[] = { {"quit", CMD_QUIT}, {"q", CMD_QUIT}, {"!", CMD_SYSTEM}, + {"repack", CMD_REPACK}, {NULL, CMD_HELP} }; @@ -203,6 +205,7 @@ static void help(void) " list : print the database hash table and freelist\n" " free : print the database freelist\n" " check : check the integrity of an opened database\n" +" repack : repack the database\n" " speed : perform speed tests on the database\n" " ! command : execute system command\n" " 1 | first : print the first record\n" @@ -257,7 +260,7 @@ static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) dbuf.dptr = (unsigned char *)data; dbuf.dsize = datalen; - if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { + if (tdb_store(tdb, key, dbuf, TDB_INSERT) != 0) { terror("insert failed"); } } @@ -284,7 +287,7 @@ static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) printf("Storing key:\n"); print_rec(tdb, key, dbuf, NULL); - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) != 0) { terror("store failed"); } } @@ -363,7 +366,7 @@ static void move_rec(char *keyname, size_t keylen, char* tdbname) return; } - if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { + if (tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) != 0) { terror("failed to move record"); } else @@ -409,12 +412,14 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void * static void info_tdb(void) { - int count; - total_bytes = 0; - if ((count = tdb_traverse(tdb, traverse_fn, NULL)) == -1) + char *summary = tdb_summary(tdb); + + if (!summary) { printf("Error = %s\n", tdb_errorstr(tdb)); - else - printf("%d records totalling %d bytes\n", count, total_bytes); + } else { + printf("%s", summary); + free(summary); + } } static void speed_tdb(const char *tlimit) @@ -445,12 +450,9 @@ static void speed_tdb(const char *tlimit) printf("Testing fetch speed for %u seconds\n", timelimit); _start_timer(); do { - long int r = random(); - TDB_DATA key, dbuf; + TDB_DATA key; key.dptr = discard_const_p(uint8_t, str); key.dsize = strlen((char *)key.dptr); - dbuf.dptr = (uint8_t *) &r; - dbuf.dsize = sizeof(r); tdb_fetch(tdb, key); t = _end_timer(); ops++; @@ -538,9 +540,9 @@ static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) print_rec(the_tdb, *pkey, dbuf, NULL); } -static int count(TDB_DATA key, TDB_DATA data, void *private) +static int count(TDB_DATA key, TDB_DATA data, void *private_data) { - (*(unsigned int *)private)++; + (*(unsigned int *)private_data)++; return 0; } @@ -609,6 +611,10 @@ static int do_command(void) bIterate = 0; tdb_transaction_commit(tdb); return 0; + case CMD_REPACK: + bIterate = 0; + tdb_repack(tdb); + return 0; case CMD_TRANSACTION_CANCEL: bIterate = 0; tdb_transaction_cancel(tdb); @@ -691,7 +697,7 @@ static int do_command(void) return 0; } -static char *convert_string(char *instring, size_t *sizep) +static char *tdb_convert_string(char *instring, size_t *sizep) { size_t length = 0; char *outp, *inp; @@ -757,15 +763,15 @@ int main(int argc, char *argv[]) } } } - if (arg1) arg1 = convert_string(arg1,&arg1len); - if (arg2) arg2 = convert_string(arg2,&arg2len); + if (arg1) arg1 = tdb_convert_string(arg1,&arg1len); + if (arg2) arg2 = tdb_convert_string(arg2,&arg2len); if (do_command()) break; } break; case 5: - arg2 = convert_string(argv[4],&arg2len); + arg2 = tdb_convert_string(argv[4],&arg2len); case 4: - arg1 = convert_string(argv[3],&arg1len); + arg1 = tdb_convert_string(argv[3],&arg1len); case 3: cmdname = argv[2]; default: diff --git a/ctdb/lib/tdb/tools/tdbtorture.c b/ctdb/lib/tdb/tools/tdbtorture.c index 79fe3cd5e0e..64c50434412 100644 --- a/ctdb/lib/tdb/tools/tdbtorture.c +++ b/ctdb/lib/tdb/tools/tdbtorture.c @@ -228,9 +228,9 @@ static void send_count_and_suicide(int sig) kill(getpid(), SIGUSR2); } -static int run_child(int i, int seed, unsigned num_loops, unsigned start) +static int run_child(const char *filename, int i, int seed, unsigned num_loops, unsigned start) { - db = tdb_open_ex("torture.tdb", hash_size, TDB_DEFAULT, + db = tdb_open_ex(filename, hash_size, TDB_DEFAULT, O_RDWR | O_CREAT, 0600, &log_ctx, NULL); if (!db) { fatal("db open failed"); @@ -270,6 +270,24 @@ static int run_child(int i, int seed, unsigned num_loops, unsigned start) return (error_count < 100 ? error_count : 100); } +static char *test_path(const char *filename) +{ + const char *prefix = getenv("TEST_DATA_PREFIX"); + + if (prefix) { + char *path = NULL; + int ret; + + ret = asprintf(&path, "%s/%s", prefix, filename); + if (ret == -1) { + return NULL; + } + return path; + } + + return strdup(filename); +} + int main(int argc, char * const *argv) { int i, seed = -1; @@ -280,6 +298,7 @@ int main(int argc, char * const *argv) pid_t *pids; int kill_random = 0; int *done; + char *test_tdb; log_ctx.log_fn = tdb_log; @@ -308,7 +327,9 @@ int main(int argc, char * const *argv) } } - unlink("torture.tdb"); + test_tdb = test_path("torture.tdb"); + + unlink(test_tdb); if (seed == -1) { seed = (getpid() + time(NULL)) & 0x7FFFFFFF; @@ -316,7 +337,7 @@ int main(int argc, char * const *argv) if (num_procs == 1 && !kill_random) { /* Don't fork for this case, makes debugging easier. */ - error_count = run_child(0, seed, num_loops, 0); + error_count = run_child(test_tdb, 0, seed, num_loops, 0); goto done; } @@ -336,7 +357,7 @@ int main(int argc, char * const *argv) printf("Testing with %d processes, %d loops, %d hash_size, seed=%d%s\n", num_procs, num_loops, hash_size, seed, always_transaction ? " (all within transactions)" : ""); } - exit(run_child(i, seed, num_loops, 0)); + exit(run_child(test_tdb, i, seed, num_loops, 0)); } } @@ -389,8 +410,8 @@ int main(int argc, char * const *argv) } pids[j] = fork(); if (pids[j] == 0) - exit(run_child(j, seed, num_loops, - done[j])); + exit(run_child(test_tdb, j, seed, + num_loops, done[j])); printf("Restarting child %i for %u-%u\n", j, done[j], num_loops); continue; @@ -414,7 +435,7 @@ int main(int argc, char * const *argv) done: if (error_count == 0) { - db = tdb_open_ex("torture.tdb", hash_size, TDB_DEFAULT, + db = tdb_open_ex(test_tdb, hash_size, TDB_DEFAULT, O_RDWR, 0, &log_ctx, NULL); if (!db) { fatal("db open failed"); @@ -427,5 +448,6 @@ done: printf("OK\n"); } + free(test_tdb); return error_count; } |