[SCM] CTDB repository - branch master updated - ctdb-1.0.114-148-g18168da

Ronnie Sahlberg sahlberg at samba.org
Tue Jun 8 17:22:55 MDT 2010


The branch, master has been updated
       via  18168da84a6aa8d69465e43402444c7ec979604a (commit)
       via  ae5b89dca00ca080c70868430fa54ba07bd6f5f4 (commit)
       via  2638dbae7bf1a35ed37802e35e179e435a5d622a (commit)
       via  3f939956ddd693cba6ea5c655288f4f5ca95f768 (commit)
       via  a6fed3f577c7ec51df38ed15ecb9db6ea2ae7c8f (commit)
       via  dc081d40051b9204bb38e4de7dfe8d78656593d0 (commit)
      from  b977901a49a9fed45cc8a2fe880eb749f58278f6 (commit)

http://gitweb.samba.org/?p=sahlberg/ctdb.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 18168da84a6aa8d69465e43402444c7ec979604a
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Jun 9 09:17:35 2010 +1000

    Some "ctdb ..." commands can be run without having the main daemon running.
    
    In that case, when the main daemon is not running
    the ctdb context will be initialized to NULL, since we can not connect.
    
    Move the calls to read the ctdb socketname and connecting via libctdb to
    only happen when we are executing a "ctdb ..." command that requires that we talk to the actual daemon.
    Otherwise we will get an ugly SEGV for the "ctdb ..." commandline tool
    when trying to run a command that is supposed to work also when the daemon is down.

commit ae5b89dca00ca080c70868430fa54ba07bd6f5f4
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Tue Jun 8 18:09:42 2010 +0930

    libctdb: connect TDB logging to our logging
    
    A simple connector function, made a bit more complex because TDB adds
    a '\n' and we don't.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 2638dbae7bf1a35ed37802e35e179e435a5d622a
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Tue Jun 8 18:10:36 2010 +0930

    libctdb: always check header hasn't changed on local tdb
    
    The code on which this is based could alter the header: a normal client
    can't.  If we use this differently later we can change this.  For the
    moment it's a nice extra check.
    
    We optimize out the record write altogether when the record hasn't
    changed, rather than just suppressing the seqnum update.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit 3f939956ddd693cba6ea5c655288f4f5ca95f768
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Tue Jun 8 17:11:40 2010 +0930

    libctdb: more bool conversion, and accompany lock by ctdb_db in API
    
    I missed some int->bool conversions previously, particularly the
    return of ctdb_writerecord().
    
    By always handing functions ctdb_connection or ctdb_db, we keep it
    consistent with the rest of the API and can do extra lock consistency
    checks.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit a6fed3f577c7ec51df38ed15ecb9db6ea2ae7c8f
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Tue Jun 8 16:53:17 2010 +0930

    libctdb: clarify logging levels
    
    Now we have more messages, it seems to make sense to document their usage
    and make them consistent.
    
    In particular, LOG_CRIT for internal libctdb problems, LOG_ALERT for
    API misuse.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit dc081d40051b9204bb38e4de7dfe8d78656593d0
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Tue Jun 8 16:52:23 2010 +0930

    libctdb: use magic to detect free/invalid locks
    
    Rather than using a binary, we use a magic value for locking.  We also
    split out the "dont have the lock yet" from the "do have the lock"
    paths for clarity and extra checking.
    
    This should detect a superset of the previous case, even if they free
    (and reuse) the lock memory.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

-----------------------------------------------------------------------

Summary of changes:
 include/ctdb.h            |   34 +++++++++---
 libctdb/ctdb.c            |  130 +++++++++++++++++++++++++++++---------------
 libctdb/libctdb_private.h |   13 ++++-
 libctdb/local_tdb.c       |   55 +++++++++++--------
 libctdb/logging.c         |   52 ++++++++++++++++++
 libctdb/messages.c        |    2 +-
 libctdb/sync.c            |    2 +-
 libctdb/tst.c             |    8 ++-
 tools/ctdb.c              |   21 ++++----
 9 files changed, 222 insertions(+), 95 deletions(-)


Changeset truncated at 500 lines:

diff --git a/include/ctdb.h b/include/ctdb.h
index 0dc5da7..e4aff86 100644
--- a/include/ctdb.h
+++ b/include/ctdb.h
@@ -46,6 +46,23 @@
  * programs; these can be found in the section marked "Synchronous API".
  */
 
+/**
+ * ctdb_log_fn_t - logging function for ctdbd
+ * @log_priv: private (typesafe) arg via ctdb_connect
+ * @severity: syslog-style severity
+ * @format: printf-style format string.
+ * @ap: arguments for formatting.
+ *
+ * The severity passed to log() are as per syslog(3).  In particular,
+ * LOG_DEBUG is used for tracing, LOG_WARNING is used for unusual
+ * conditions which don't necessarily return an error through the API,
+ * LOG_ERR is used for errors such as lost communication with ctdbd or
+ * out-of-memory, LOG_ALERT is used for library usage bugs, LOG_CRIT is
+ * used for libctdb internal consistency checks.
+ *
+ * The log() function can be typesafe: the @log_priv arg to
+ * ctdb_donnect and signature of log() should match.
+ */
 typedef void (*ctdb_log_fn_t)(void *log_priv,
 			      int severity, const char *format, va_list ap);
 
@@ -58,12 +75,8 @@ typedef void (*ctdb_log_fn_t)(void *log_priv,
  * Returns a ctdb context if successful or NULL.  Use ctdb_free() to
  * release the returned ctdb_connection when finished.
  *
- * The log() function can be typesafe: the log_priv arg and signature
- * of log() should match.  The priority passed to log() os as per
- * syslog(3).
- *
  * See Also:
- *	ctdb_log_file()
+ *	ctdb_log_fn_t, ctdb_log_file()
  */
 struct ctdb_connection *ctdb_connect(const char *addr,
 				     ctdb_log_fn_t log_fn, void *log_priv);
@@ -191,7 +204,7 @@ struct ctdb_db;
  */
 struct ctdb_request *
 ctdb_attachdb_send(struct ctdb_connection *ctdb,
-		   const char *name, int persistent, uint32_t tdb_flags,
+		   const char *name, bool persistent, uint32_t tdb_flags,
 		   ctdb_callback_t callback, void *cbdata);
 
 /**
@@ -255,16 +268,19 @@ bool ctdb_readrecordlock_async(struct ctdb_db *ctdb_db, TDB_DATA key,
 
 /**
  * ctdb_writerecord - write a locked record in a TDB
+ * @ctdb_db: the database handle from ctdb_attachdb/ctdb_attachdb_recv.
  * @lock: the lock from ctdb_readrecordlock/ctdb_readrecordlock_recv
  * @data: the new data to place in the record.
  */
-int ctdb_writerecord(struct ctdb_lock *lock, TDB_DATA data);
+bool ctdb_writerecord(struct ctdb_db *ctdb_db,
+		      struct ctdb_lock *lock, TDB_DATA data);
 
 /**
  * ctdb_release_lock - release a record lock on a TDB
+ * @ctdb_db: the database handle from ctdb_attachdb/ctdb_attachdb_recv.
  * @lock: the lock from ctdb_readrecordlock/ctdb_readrecordlock_async
  */
-void ctdb_release_lock(struct ctdb_lock *lock);
+void ctdb_release_lock(struct ctdb_db *ctdb_db, struct ctdb_lock *lock);
 
 /**
  * ctdb_message_fn_t - messaging callback for ctdb messages
@@ -437,7 +453,7 @@ void ctdb_cancel(struct ctdb_connection *ctdb, struct ctdb_request *req);
  * Returns NULL on failure.
  */
 struct ctdb_db *ctdb_attachdb(struct ctdb_connection *ctdb,
-			      const char *name, int persistent,
+			      const char *name, bool persistent,
 			      uint32_t tdb_flags);
 
 /**
diff --git a/libctdb/ctdb.c b/libctdb/ctdb.c
index b7f1c59..df42949 100644
--- a/libctdb/ctdb.c
+++ b/libctdb/ctdb.c
@@ -42,8 +42,8 @@ struct ctdb_lock {
 	struct ctdb_db *ctdb_db;
 	TDB_DATA key;
 
-	/* This will always be true by the time user sees this. */
-	bool held;
+	/* This will always be set by the time user sees this. */
+	unsigned long held_magic;
 	struct ctdb_ltdb_header *hdr;
 
 	/* For convenience, we stash original callback here. */
@@ -222,7 +222,7 @@ static struct ctdb_reply_call *unpack_reply_call(struct ctdb_connection *ctdb,
 	/* Library user error if this isn't a reply to a call. */
 	if (req->hdr.hdr->operation != CTDB_REQ_CALL) {
 		errno = EINVAL;
-		DEBUG(ctdb, LOG_ERR,
+		DEBUG(ctdb, LOG_ALERT,
 		      "This was not a ctdbd call request: operation %u",
 		      req->hdr.hdr->operation);
 		return NULL;
@@ -230,7 +230,7 @@ static struct ctdb_reply_call *unpack_reply_call(struct ctdb_connection *ctdb,
 
 	if (req->hdr.call->callid != callid) {
 		errno = EINVAL;
-		DEBUG(ctdb, LOG_ERR,
+		DEBUG(ctdb, LOG_ALERT,
 		      "This was not a ctdbd %u call request: %u",
 		      callid, req->hdr.call->callid);
 		return NULL;
@@ -259,13 +259,13 @@ struct ctdb_reply_control *unpack_reply_control(struct ctdb_connection *ctdb,
 	/* Library user error if this isn't a reply to a call. */
 	if (len < sizeof(*inhdr)) {
 		errno = EINVAL;
-		DEBUG(ctdb, LOG_CRIT,
+		DEBUG(ctdb, LOG_ALERT,
 		      "Short ctdbd control reply: %zu bytes", len);
 		return NULL;
 	}
 	if (req->hdr.hdr->operation != CTDB_REQ_CONTROL) {
 		errno = EINVAL;
-		DEBUG(ctdb, LOG_ERR,
+		DEBUG(ctdb, LOG_ALERT,
 		      "This was not a ctdbd control request: operation %u",
 		      req->hdr.hdr->operation);
 		return NULL;
@@ -274,7 +274,7 @@ struct ctdb_reply_control *unpack_reply_control(struct ctdb_connection *ctdb,
 	/* ... or if it was a different control from what we expected. */
 	if (req->hdr.control->opcode != control) {
 		errno = EINVAL;
-		DEBUG(ctdb, LOG_ERR,
+		DEBUG(ctdb, LOG_ALERT,
 		      "This was not an opcode %u ctdbd control request: %u",
 		      control, req->hdr.control->opcode);
 		return NULL;
@@ -335,7 +335,7 @@ bool ctdb_service(struct ctdb_connection *ctdb, int revents)
 	}
 
 	if (holding_lock(ctdb)) {
-		DEBUG(ctdb, LOG_WARNING, "Do not block while holding lock!");
+		DEBUG(ctdb, LOG_ALERT, "Do not block while holding lock!");
 	}
 
 	if (revents & POLLOUT) {
@@ -494,6 +494,7 @@ struct ctdb_db *ctdb_attachdb_recv(struct ctdb_connection *ctdb,
 	struct ctdb_reply_control *reply;
 	struct ctdb_db *db = req->priv_data;
 	uint32_t tdb_flags = db->tdb_flags;
+	struct tdb_logging_context log;
 
 	/* Never sent the dbpath request?  We've failed. */
 	if (!dbpath_req) {
@@ -515,8 +516,10 @@ struct ctdb_db *ctdb_attachdb_recv(struct ctdb_connection *ctdb,
 	tdb_flags = db->persistent ? TDB_DEFAULT : TDB_NOSYNC;
 	tdb_flags |= TDB_DISALLOW_NESTING;
 
-	/* FIXME: Setup logging to go through our logging. */
-	db->tdb = tdb_open((char *)reply->data, 0, tdb_flags, O_RDWR, 0);
+	log.log_fn = ctdb_tdb_log_bridge;
+	log.log_private = ctdb;
+	db->tdb = tdb_open_ex((char *)reply->data, 0, tdb_flags, O_RDWR, 0,
+			      &log, NULL);
 	if (db->tdb == NULL) {
 		DEBUG(db->ctdb, LOG_ERR,
 		      "ctdb_attachdb_recv: failed to tdb_open %s",
@@ -588,7 +591,7 @@ static void destroy_req_db(struct ctdb_connection *ctdb,
 
 struct ctdb_request *
 ctdb_attachdb_send(struct ctdb_connection *ctdb,
-		   const char *name, int persistent, uint32_t tdb_flags,
+		   const char *name, bool persistent, uint32_t tdb_flags,
 		   ctdb_callback_t callback, void *private_data)
 {
 	struct ctdb_request *req;
@@ -633,35 +636,47 @@ ctdb_attachdb_send(struct ctdb_connection *ctdb,
 	return req;
 }
 
-void ctdb_release_lock(struct ctdb_lock *lock)
+static unsigned long lock_magic(struct ctdb_lock *lock)
 {
-	if (lock->held) {
-		tdb_chainunlock(lock->ctdb_db->tdb, lock->key);
-		DEBUG(lock->ctdb_db->ctdb, LOG_DEBUG,
-		      "ctdb_release_lock %p", lock);
-		lock->held = false;
-		remove_lock(lock->ctdb_db->ctdb, lock);
-	}
+	/* A non-zero magic specific to this structure. */
+	return ((unsigned long)lock->key.dptr
+		^ (((unsigned long)lock->key.dptr) << 16)
+		^ 0xBADC0FFEEBADC0DEULL)
+		| 1;
 }
 
-static void ctdb_free_lock(struct ctdb_lock *lock)
+/* This is only called on locks before they're held. */
+static void free_lock(struct ctdb_lock *lock)
 {
-	if (lock->held) {
-		errno = EEXIST;
-		DEBUG(lock->ctdb_db->ctdb, LOG_ERR,
-			"Lock freed before it was released");
-		ctdb_release_lock(lock);
+	if (lock->held_magic) {
+		DEBUG(lock->ctdb_db->ctdb, LOG_ALERT,
+		      "free_lock invalid lock %p", lock);
 	}
 	free(lock->hdr);
 	free(lock);
 }
 
-static void ctdb_destroy_lock(struct ctdb_lock *lock)
+
+void ctdb_release_lock(struct ctdb_db *ctdb_db, struct ctdb_lock *lock)
 {
-	ctdb_release_lock(lock);
-	ctdb_free_lock(lock);
+	if (lock->held_magic != lock_magic(lock)) {
+		DEBUG(lock->ctdb_db->ctdb, LOG_ALERT,
+		      "ctdb_release_lock invalid lock %p", lock);
+	} else if (lock->ctdb_db != ctdb_db) {
+		errno = EBADF;
+		DEBUG(ctdb_db->ctdb, LOG_ALERT,
+		      "ctdb_release_lock: wrong ctdb_db.");
+	} else {
+		tdb_chainunlock(lock->ctdb_db->tdb, lock->key);
+		DEBUG(lock->ctdb_db->ctdb, LOG_DEBUG,
+		      "ctdb_release_lock %p", lock);
+		remove_lock(lock->ctdb_db->ctdb, lock);
+	}
+	lock->held_magic = 0;
+	free_lock(lock);
 }
 
+
 /* We keep the lock if local node is the dmaster. */
 static bool try_readrecordlock(struct ctdb_lock *lock, TDB_DATA *data)
 {
@@ -677,7 +692,7 @@ static bool try_readrecordlock(struct ctdb_lock *lock, TDB_DATA *data)
 	if (hdr && hdr->dmaster == lock->ctdb_db->ctdb->pnn) {
 		DEBUG(lock->ctdb_db->ctdb, LOG_DEBUG,
 		      "ctdb_readrecordlock_async: got local lock");
-		lock->held = true;
+		lock->held_magic = lock_magic(lock);
 		lock->hdr = hdr;
 		add_lock(lock->ctdb_db->ctdb, lock);
 		return true;
@@ -692,7 +707,7 @@ static bool try_readrecordlock(struct ctdb_lock *lock, TDB_DATA *data)
 static void destroy_lock(struct ctdb_connection *ctdb,
 			 struct ctdb_request *req)
 {
-	ctdb_destroy_lock(req->extra);
+	free_lock(req->extra);
 }
 
 static void readrecordlock_retry(struct ctdb_connection *ctdb,
@@ -720,7 +735,6 @@ static void readrecordlock_retry(struct ctdb_connection *ctdb,
 		/* Now it's their responsibility to free lock & request! */
 		req->extra_destructor = NULL;
 		lock->callback(lock->ctdb_db, lock, data, private);
-		ctdb_free_lock(lock);
 		return;
 	}
 
@@ -738,7 +752,7 @@ ctdb_readrecordlock_async(struct ctdb_db *ctdb_db, TDB_DATA key,
 	TDB_DATA data;
 
 	if (holding_lock(ctdb_db->ctdb)) {
-		DEBUG(ctdb_db->ctdb, LOG_ERR,
+		DEBUG(ctdb_db->ctdb, LOG_ALERT,
 		      "ctdb_readrecordlock_async: already holding lock");
 		return false;
 	}
@@ -755,12 +769,11 @@ ctdb_readrecordlock_async(struct ctdb_db *ctdb_db, TDB_DATA key,
 	lock->key.dsize = key.dsize;
 	lock->ctdb_db = ctdb_db;
 	lock->hdr = NULL;
-	lock->held = false;
+	lock->held_magic = 0;
 
 	/* Fast path. */
 	if (try_readrecordlock(lock, &data)) {
 		callback(ctdb_db, lock, data, cbdata);
-		ctdb_free_lock(lock);
 		return true;
 	}
 
@@ -770,7 +783,7 @@ ctdb_readrecordlock_async(struct ctdb_db *ctdb_db, TDB_DATA key,
 	if (!req) {
 		DEBUG(ctdb_db->ctdb, LOG_ERR,
 		      "ctdb_readrecordlock_async: allocation failed");
-		ctdb_destroy_lock(lock);
+		free_lock(lock);
 		return NULL;
 	}
 	req->extra = lock;
@@ -792,22 +805,51 @@ ctdb_readrecordlock_async(struct ctdb_db *ctdb_db, TDB_DATA key,
 	return true;
 }
 
-int ctdb_writerecord(struct ctdb_lock *lock, TDB_DATA data)
+bool ctdb_writerecord(struct ctdb_db *ctdb_db,
+		      struct ctdb_lock *lock, TDB_DATA data)
 {
-	if (!lock->held) {
+	if (lock->ctdb_db != ctdb_db) {
 		errno = EBADF;
-		DEBUG(lock->ctdb_db->ctdb, LOG_ERR,
+		DEBUG(ctdb_db->ctdb, LOG_ALERT,
+		      "ctdb_writerecord: Can not write, wrong ctdb_db.");
+		return false;
+	}
+
+	if (lock->held_magic != lock_magic(lock)) {
+		errno = EBADF;
+		DEBUG(ctdb_db->ctdb, LOG_ALERT,
 		      "ctdb_writerecord: Can not write. Lock has been released.");
-		return -1;
+		return false;
 	}
 		
-	if (lock->ctdb_db->persistent) {
+	if (ctdb_db->persistent) {
 		errno = EINVAL;
-		DEBUG(lock->ctdb_db->ctdb, LOG_ERR,
+		DEBUG(ctdb_db->ctdb, LOG_ALERT,
 		      "ctdb_writerecord: cannot write to persistent db");
-		return -1;
+		return false;
 	}
 
-	return ctdb_local_store(lock->ctdb_db->tdb, lock->key, lock->hdr,
-				data);
+	switch (ctdb_local_store(ctdb_db->tdb, lock->key, lock->hdr, data)) {
+	case 0:
+		DEBUG(ctdb_db->ctdb, LOG_DEBUG,
+		      "ctdb_writerecord: optimized away noop write.");
+		/* fall thru */
+	case 1:
+		return true;
+
+	default:
+		switch (errno) {
+		case ENOMEM:
+			DEBUG(ctdb_db->ctdb, LOG_CRIT,
+			      "ctdb_writerecord: out of memory.");
+			break;
+		case EINVAL:
+			DEBUG(ctdb_db->ctdb, LOG_ALERT,
+			      "ctdb_writerecord: record changed under lock?");
+			break;
+		default: /* TDB already logged. */
+			break;
+		}
+		return false;
+	}
 }
diff --git a/libctdb/libctdb_private.h b/libctdb/libctdb_private.h
index 51b9305..8ecfb0a 100644
--- a/libctdb/libctdb_private.h
+++ b/libctdb/libctdb_private.h
@@ -7,6 +7,7 @@
 #include <ctdb.h>
 #include <ctdb_protocol.h>
 #include <syslog.h>
+#include <tdb.h>
 
 #ifndef offsetof
 #define offsetof(t,f) ((unsigned int)&((t *)0)->f)
@@ -22,9 +23,6 @@
 
 #define DEBUG(ctdb, lvl, format, args...) do { if (lvl <= ctdb_log_level) { ctdb_do_debug(ctdb, lvl, format , ## args ); }} while(0)
 
-void ctdb_do_debug(struct ctdb_connection *, int, const char *format, ...)
-	PRINTF_ATTRIBUTE(3, 4) COLD_ATTRIBUTE;
-
 struct message_handler_info;
 struct ctdb_reply_call;
 
@@ -92,4 +90,13 @@ struct ctdb_reply_control *unpack_reply_control(struct ctdb_connection *ctdb,
 void ctdb_cancel_callback(struct ctdb_connection *ctdb,
 			  struct ctdb_request *req,
 			  void *unused);
+
+/* logging.c */
+void ctdb_tdb_log_bridge(struct tdb_context *tdb,
+			 enum tdb_debug_level level,
+			 const char *format, ...) PRINTF_ATTRIBUTE(3, 4);
+
+void ctdb_do_debug(struct ctdb_connection *, int, const char *format, ...)
+	PRINTF_ATTRIBUTE(3, 4) COLD_ATTRIBUTE;
+
 #endif /* _LIBCTDB_PRIVATE_H */
diff --git a/libctdb/local_tdb.c b/libctdb/local_tdb.c
index dbf06ed..9a19df7 100644
--- a/libctdb/local_tdb.c
+++ b/libctdb/local_tdb.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
+#include <errno.h>
 #include <ctdb_protocol.h> // For struct ctdb_ltdb_header
 #include "local_tdb.h"
 
@@ -51,44 +52,50 @@ struct ctdb_ltdb_header *ctdb_local_fetch(struct tdb_context *tdb,
 
 
 /*
-  write a record to a normal database
+  write a record to a normal database: 1 on success, 0 if noop, -1 on fail.
+  errno = EIO => tdb error.
 */
 int ctdb_local_store(struct tdb_context *tdb, TDB_DATA key,
 		     struct ctdb_ltdb_header *header, TDB_DATA data)
 {
 	TDB_DATA rec;
 	int ret;
-	bool seqnum_suppressed = false;
+	TDB_DATA old;
 
-	rec.dsize = sizeof(*header) + data.dsize;
-	rec.dptr = malloc(rec.dsize);
-	if (!rec.dptr) {
+	old = tdb_fetch(tdb, key);
+	if (old.dsize < sizeof(*header)) {
+		errno = EIO;
 		return -1;
 	}
 
-	memcpy(rec.dptr, header, sizeof(*header));
-	memcpy(rec.dptr + sizeof(*header), data.dptr, data.dsize);
+	/* Debugging check: we have lock and should not change hdr. */
+	if (memcmp(old.dptr, header, sizeof(*header)) != 0) {
+		free(old.dptr);
+		errno = EINVAL;
+		return -1;
+	}
 
-	/* Databases with seqnum updates enabled only get their seqnum
-	   changes when/if we modify the data */
-	if (tdb_get_flags(tdb) & TDB_SEQNUM) {
-		TDB_DATA old;
-		old = tdb_fetch(tdb, key);
+	/* Optimize out the nothing-changed case. */
+	if (old.dsize == sizeof(*header) + data.dsize
+	    && memcmp(old.dptr+sizeof(*header), data.dptr, data.dsize) == 0) {
+		free(old.dptr);
+		return 0;
+	}
 
-		if ( (old.dsize == rec.dsize)
-		&& !memcmp(old.dptr+sizeof(struct ctdb_ltdb_header),
-			  rec.dptr+sizeof(struct ctdb_ltdb_header),
-			  rec.dsize-sizeof(struct ctdb_ltdb_header)) ) {
-			tdb_remove_flags(tdb, TDB_SEQNUM);
-			seqnum_suppressed = true;
-		}
+	rec.dsize = sizeof(*header) + data.dsize;
+	rec.dptr = malloc(rec.dsize);
+	if (!rec.dptr) {
 		free(old.dptr);
+		errno = ENOMEM;
+		return -1;
 	}
+
 	ret = tdb_store(tdb, key, rec, TDB_REPLACE);
-	if (seqnum_suppressed) {
-		tdb_add_flags(tdb, TDB_SEQNUM);
-	}
+	free(old.dptr);
 	free(rec.dptr);
-
-	return ret;
+	if (ret != 0) {
+		errno = EIO;
+		return -1;
+	}
+	return 1;
 }
diff --git a/libctdb/logging.c b/libctdb/logging.c
index 05aaa03..83f4774 100644
--- a/libctdb/logging.c
+++ b/libctdb/logging.c
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <ctdb.h>
 #include <string.h>
+#include <tdb.h>
 #include "libctdb_private.h"
 
 int ctdb_log_level = LOG_WARNING;
@@ -34,6 +35,57 @@ void ctdb_do_debug(struct ctdb_connection *ctdb,
         va_end(ap);


-- 
CTDB repository


More information about the samba-cvs mailing list