[SCM] CTDB repository - branch master updated - ctdb-2.1-47-g1c7adbc

Amitay Isaacs amitay at samba.org
Sun Apr 7 22:23:36 MDT 2013


The branch, master has been updated
       via  1c7adbccc69ac276d2b957ad16c3802fdb8868ca (commit)
       via  fe8c4880b371492a38554868d4ca10918c54e412 (commit)
       via  524ec206e6a5e8b11723f4d8d1251ed5d84063b0 (commit)
       via  74acc2c568300ef42740cf11299a1b2507047f60 (commit)
       via  f7f8bde2376f8180a0dca6d7b8d7d2a4a12f4bd8 (commit)
       via  c137531fae8f7f6392746ce1b9ac6f219775fc29 (commit)
       via  bf7296ce9b98563bcb8426cd035dbeab6d884f59 (commit)
       via  20be1f991dd75c2333c9ec9db226432a819f57ba (commit)
       via  4e1ec7412866f2d31c41de1bec0fbf788c03051b (commit)
      from  85b777196289646ca37e06ebbf1f7a684d0aabc5 (commit)

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


- Log -----------------------------------------------------------------
commit 1c7adbccc69ac276d2b957ad16c3802fdb8868ca
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 5 13:34:06 2013 +1100

    recoverd/takeover: Use IP->node mapping info from nodes hosting that IP
    
    When collating IP information for IP layout, only trust the nodes that are
    hosting an IP, to have correct information about that IP.  Ignore what all the
    other nodes think.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit fe8c4880b371492a38554868d4ca10918c54e412
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Apr 3 14:44:08 2013 +1100

    statd-callout: Make sure statd callout script always runs as root
    
    In RHEL 6+, rpc.statd runs as "rpcuser" instead of root as on RHEL 5. This
    prevents CTDB tool commands talking to daemon since "rpcuser" cannot access
    CTDB socket.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Pair-Programmed-With: Martin Schwenke <martin at meltin.net>

commit 524ec206e6a5e8b11723f4d8d1251ed5d84063b0
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Mar 18 13:45:08 2013 +1100

    client: Set the socket non-blocking only after connect succeeds
    
    If the socket is set non-blocking before connect, then we should catch
    EAGAIN errors and retry. Instead of adding a random number of retries,
    better to wait for connect to succeed and then set the socket to
    non-blocking.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 74acc2c568300ef42740cf11299a1b2507047f60
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 5 13:19:34 2013 +1100

    Revert "client: handle transient connection errors"
    
    This reverts commit dc0c58547cd4b20a8e2cd21f3c8363f34fd03e75.
    
    There is a simpler solution that retrying random number of times. Do not set
    socket non-blocking till connect succeeds.

commit f7f8bde2376f8180a0dca6d7b8d7d2a4a12f4bd8
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Apr 3 14:59:21 2013 +0200

    common/messaging: Use the jenkins hash in ctdb_message
    
    This give a better hash distribution

commit c137531fae8f7f6392746ce1b9ac6f219775fc29
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Apr 5 13:11:31 2013 +1100

    common/messaging: use tdb_parse_record in message_list_db_fetch
    
    This avoids malloc/free in a hot code path.

commit bf7296ce9b98563bcb8426cd035dbeab6d884f59
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Apr 3 15:08:14 2013 +1100

    common/messaging: Abstract db related operations inside db functions
    
    This simplifies the use of message indexdb API and abstracts tdb related code
    inside the API.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 20be1f991dd75c2333c9ec9db226432a819f57ba
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Apr 2 16:57:51 2013 +1100

    common/messaging: Don't forget to free the result returned by tdb_fetch()
    
    This fixes a memory leak in the messaging code.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 4e1ec7412866f2d31c41de1bec0fbf788c03051b
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Apr 2 12:08:39 2013 +1100

    common/messaging: Free message list header if all message handlers are freed
    
    This makes sure that even if the srvids are not deregistered, the header
    structure is freed when the last message handler has been freed as a result of
    client going away.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

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

Summary of changes:
 Makefile.in                |    1 +
 client/ctdb_client.c       |   39 +++-------------
 common/ctdb_message.c      |  110 +++++++++++++++++++++-----------------------
 config/ctdb.sudoers        |    3 +
 config/statd-callout       |    3 +
 libctdb/ctdb.c             |    6 +-
 packaging/RPM/ctdb.spec.in |    4 +-
 server/ctdb_takeover.c     |    8 +++-
 8 files changed, 80 insertions(+), 94 deletions(-)
 create mode 100644 config/ctdb.sudoers


Changeset truncated at 500 lines:

diff --git a/Makefile.in b/Makefile.in
index 762f788..9511e90 100755
--- a/Makefile.in
+++ b/Makefile.in
@@ -330,6 +330,7 @@ install: all manpages $(PMDA_INSTALL)
 	${INSTALLCMD} -m 644 include/ctdb_protocol.h $(DESTDIR)$(includedir)
 	${INSTALLCMD} -m 644 include/ctdb_private.h $(DESTDIR)$(includedir) # for samba3
 	${INSTALLCMD} -m 644 include/ctdb_typesafe_cb.h $(DESTDIR)$(includedir)
+	${INSTALLCMD} -m 440 config/ctdb.sudoers $(DESTDIR)$(etcdir)/sudoers.d/ctdb
 	${INSTALLCMD} -m 644 config/functions $(DESTDIR)$(etcdir)/ctdb
 	${INSTALLCMD} -m 755 config/statd-callout $(DESTDIR)$(etcdir)/ctdb
 	${INSTALLCMD} -m 644 README $(DESTDIR)$(docdir)/ctdb/README
diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index d2cf0f6..76780b0 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -253,57 +253,32 @@ done:
 }
 
 /*
-  connect with exponential backoff, thanks Stevens
+  connect to a unix domain socket
 */
-#define CONNECT_MAXSLEEP 64
-static int ctdb_connect_retry(struct ctdb_context *ctdb)
+int ctdb_socket_connect(struct ctdb_context *ctdb)
 {
 	struct sockaddr_un addr;
-	int secs;
-	int ret = 0;
 
 	memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
 	strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path));
 
-	for (secs = 1; secs <= CONNECT_MAXSLEEP; secs *= 2) {
-		ret = connect(ctdb->daemon.sd, (struct sockaddr *)&addr,
-			      sizeof(addr));
-		if ((ret == 0) || (errno != EAGAIN)) {
-			break;
-		}
-
-		if (secs <= (CONNECT_MAXSLEEP / 2)) {
-			DEBUG(DEBUG_ERR,("connect failed: %s, retry in %d second(s)\n",
-					 strerror(errno), secs));
-			sleep(secs);
-		}
-	}
-
-	return ret;
-}
-
-/*
-  connect to a unix domain socket
-*/
-int ctdb_socket_connect(struct ctdb_context *ctdb)
-{
 	ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
 	if (ctdb->daemon.sd == -1) {
 		DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
 		return -1;
 	}
 
-	set_nonblocking(ctdb->daemon.sd);
-	set_close_on_exec(ctdb->daemon.sd);
-
-	if (ctdb_connect_retry(ctdb) == -1) {
-		DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
+	if (connect(ctdb->daemon.sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
 		close(ctdb->daemon.sd);
 		ctdb->daemon.sd = -1;
+		DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
 		return -1;
 	}
 
+	set_nonblocking(ctdb->daemon.sd);
+	set_close_on_exec(ctdb->daemon.sd);
+	
 	ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd, 
 					      CTDB_DS_ALIGNMENT, 
 					      ctdb_client_read_cb, ctdb, "to-ctdbd");
diff --git a/common/ctdb_message.c b/common/ctdb_message.c
index 50d2189..b0d2ea0 100644
--- a/common/ctdb_message.c
+++ b/common/ctdb_message.c
@@ -31,7 +31,9 @@
 static int message_list_db_init(struct ctdb_context *ctdb)
 {
 	ctdb->message_list_indexdb = tdb_open("messagedb", 8192,
-					      TDB_INTERNAL|TDB_DISALLOW_NESTING,
+					      TDB_INTERNAL|
+					      TDB_INCOMPATIBLE_HASH|
+					      TDB_DISALLOW_NESTING,
 					      O_RDWR|O_CREAT, 0);
 	if (ctdb->message_list_indexdb == NULL) {
 		DEBUG(DEBUG_ERR, ("Failed to create message list indexdb\n"));
@@ -41,9 +43,11 @@ static int message_list_db_init(struct ctdb_context *ctdb)
 	return 0;
 }
 
-static int message_list_db_add(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data)
+static int message_list_db_add(struct ctdb_context *ctdb, uint64_t srvid,
+			       struct ctdb_message_list_header *h)
 {
 	int ret;
+	TDB_DATA key, data;
 
 	if (ctdb->message_list_indexdb == NULL) {
 		ret = message_list_db_init(ctdb);
@@ -52,6 +56,12 @@ static int message_list_db_add(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA
 		}
 	}
 
+	key.dptr = (uint8_t *)&srvid;
+	key.dsize = sizeof(uint64_t);
+
+	data.dptr = (uint8_t *)&h;
+	data.dsize = sizeof(struct ctdb_message_list_header *);
+
 	ret = tdb_store(ctdb->message_list_indexdb, key, data, TDB_INSERT);
 	if (ret < 0) {
 		DEBUG(DEBUG_ERR, ("Failed to add message list handler (%s)\n",
@@ -62,14 +72,18 @@ static int message_list_db_add(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA
 	return 0;
 }
 
-static int message_list_db_delete(struct ctdb_context *ctdb, TDB_DATA key)
+static int message_list_db_delete(struct ctdb_context *ctdb, uint64_t srvid)
 {
 	int ret;
+	TDB_DATA key;
 
 	if (ctdb->message_list_indexdb == NULL) {
 		return -1;
 	}
 
+	key.dptr = (uint8_t *)&srvid;
+	key.dsize = sizeof(uint64_t);
+
 	ret = tdb_delete(ctdb->message_list_indexdb, key);
 	if (ret < 0) {
 		DEBUG(DEBUG_ERR, ("Failed to delete message list handler (%s)\n",
@@ -80,17 +94,34 @@ static int message_list_db_delete(struct ctdb_context *ctdb, TDB_DATA key)
 	return 0;
 }
 
-static int message_list_db_fetch(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA *data)
+static int message_list_db_fetch_parser(TDB_DATA key, TDB_DATA data,
+					void *private_data)
 {
-	if (ctdb->message_list_indexdb == NULL) {
+	struct ctdb_message_list_header **h =
+		(struct ctdb_message_list_header **)private_data;
+
+	if (data.dsize != sizeof(struct ctdb_message_list_header *)) {
 		return -1;
 	}
 
-	*data = tdb_fetch(ctdb->message_list_indexdb, key);
-	if (data->dsize == 0) {
+	*h = *(struct ctdb_message_list_header **)data.dptr;
+	return 0;
+}
+
+static int message_list_db_fetch(struct ctdb_context *ctdb, uint64_t srvid,
+				 struct ctdb_message_list_header **h)
+{
+	TDB_DATA key;
+
+	if (ctdb->message_list_indexdb == NULL) {
 		return -1;
 	}
-	return 0;
+
+	key.dptr = (uint8_t *)&srvid;
+	key.dsize = sizeof(uint64_t);
+
+	return tdb_parse_record(ctdb->message_list_indexdb, key,
+				message_list_db_fetch_parser, h);
 }
 
 /*
@@ -100,29 +131,18 @@ int ctdb_dispatch_message(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA da
 {
 	struct ctdb_message_list_header *h;
 	struct ctdb_message_list *m;
-	TDB_DATA key, hdata;
 	uint64_t srvid_all = CTDB_SRVID_ALL;
 	int ret;
 
-	key.dptr = (uint8_t *)&srvid;
-	key.dsize = sizeof(uint64_t);
-
-	ret = message_list_db_fetch(ctdb, key, &hdata);
+	ret = message_list_db_fetch(ctdb, srvid, &h);
 	if (ret == 0) {
-		h = *(struct ctdb_message_list_header **)hdata.dptr;
-
 		for (m=h->m; m; m=m->next) {
 			m->message_handler(ctdb, srvid, data, m->message_private);
 		}
 	}
 
-	key.dptr = (uint8_t *)&srvid_all;
-	key.dsize = sizeof(uint64_t);
-
-	ret = message_list_db_fetch(ctdb, key, &hdata);
+	ret = message_list_db_fetch(ctdb, srvid_all, &h);
 	if (ret == 0) {
-		h = *(struct ctdb_message_list_header **)hdata.dptr;
-
 		for(m=h->m; m; m=m->next) {
 			m->message_handler(ctdb, srvid, data, m->message_private);
 		}
@@ -151,7 +171,6 @@ void ctdb_request_message(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
 static int message_header_destructor(struct ctdb_message_list_header *h)
 {
 	struct ctdb_message_list *m;
-	TDB_DATA key;
 
 	while (h->m != NULL) {
 		m = h->m;
@@ -159,10 +178,7 @@ static int message_header_destructor(struct ctdb_message_list_header *h)
 		TALLOC_FREE(m);
 	}
 
-	key.dptr = (uint8_t *)&h->srvid;
-	key.dsize = sizeof(uint64_t);
-
-	message_list_db_delete(h->ctdb, key);
+	message_list_db_delete(h->ctdb, h->srvid);
 	DLIST_REMOVE(h->ctdb->message_list_header, h);
 
 	return 0;
@@ -176,6 +192,9 @@ static int message_handler_destructor(struct ctdb_message_list *m)
 	struct ctdb_message_list_header *h = m->h;
 
 	DLIST_REMOVE(h->m, m);
+	if (h->m == NULL) {
+		talloc_free(h);
+	}
 	return 0;
 }
 
@@ -190,7 +209,6 @@ int ctdb_register_message_handler(struct ctdb_context *ctdb,
 {
 	struct ctdb_message_list_header *h;
 	struct ctdb_message_list *m;
-	TDB_DATA key, data;
 	int ret;
 
 	m = talloc_zero(mem_ctx, struct ctdb_message_list);
@@ -199,11 +217,8 @@ int ctdb_register_message_handler(struct ctdb_context *ctdb,
 	m->message_handler = handler;
 	m->message_private = private_data;
 
-	key.dptr = (uint8_t *)&srvid;
-	key.dsize = sizeof(uint64_t);
-
-	ret = message_list_db_fetch(ctdb, key, &data);
-	if (ret < 0) {
+	ret = message_list_db_fetch(ctdb, srvid, &h);
+	if (ret != 0) {
 		/* srvid not registered yet */
 		h = talloc_zero(ctdb, struct ctdb_message_list_header);
 		CTDB_NO_MEMORY(ctdb, h);
@@ -211,9 +226,7 @@ int ctdb_register_message_handler(struct ctdb_context *ctdb,
 		h->ctdb = ctdb;
 		h->srvid = srvid;
 
-		data.dptr = (uint8_t *)&h;
-		data.dsize = sizeof(struct ctdb_message_list_header *);
-		ret = message_list_db_add(ctdb, key, data);
+		ret = message_list_db_add(ctdb, srvid, h);
 		if (ret < 0) {
 			talloc_free(m);
 			talloc_free(h);
@@ -222,8 +235,6 @@ int ctdb_register_message_handler(struct ctdb_context *ctdb,
 
 		DLIST_ADD(ctdb->message_list_header, h);
 		talloc_set_destructor(h, message_header_destructor);
-	} else {
-		h = *(struct ctdb_message_list_header **)data.dptr;
 	}
 
 	m->h = h;
@@ -240,24 +251,16 @@ int ctdb_deregister_message_handler(struct ctdb_context *ctdb, uint64_t srvid, v
 {
 	struct ctdb_message_list_header *h;
 	struct ctdb_message_list *m;
-	TDB_DATA key, data;
 	int ret;
 
-	key.dptr = (uint8_t *)&srvid;
-	key.dsize = sizeof(uint64_t);
-
-	ret = message_list_db_fetch(ctdb, key, &data);
-	if (ret < 0) {
+	ret = message_list_db_fetch(ctdb, srvid, &h);
+	if (ret != 0) {
 		return -1;
 	}
 
-	h = *(struct ctdb_message_list_header **)data.dptr;
 	for (m=h->m; m; m=m->next) {
 		if (m->message_private == private_data) {
 			talloc_free(m);
-			if (h->m == NULL) {
-				talloc_free(h);
-			}
 			return 0;
 		}
 	}
@@ -272,17 +275,10 @@ int ctdb_deregister_message_handler(struct ctdb_context *ctdb, uint64_t srvid, v
 bool ctdb_check_message_handler(struct ctdb_context *ctdb, uint64_t srvid)
 {
 	struct ctdb_message_list_header *h;
-	TDB_DATA key, data;
-
-	key.dptr = (uint8_t *)&srvid;
-	key.dsize = sizeof(uint64_t);
-
-	if (message_list_db_fetch(ctdb, key, &data) < 0) {
-		return false;
-	}
+	int ret;
 
-	h = *(struct ctdb_message_list_header **)data.dptr;
-	if (h->m == NULL) {
+	ret = message_list_db_fetch(ctdb, srvid, &h);
+	if (ret != 0 || h->m == NULL) {
 		return false;
 	}
 
diff --git a/config/ctdb.sudoers b/config/ctdb.sudoers
new file mode 100644
index 0000000..1c6619b
--- /dev/null
+++ b/config/ctdb.sudoers
@@ -0,0 +1,3 @@
+Defaults!/etc/ctdb/statd-callout	!requiretty
+
+rpcuser		ALL=(ALL) 	NOPASSWD: /etc/ctdb/statd-callout
diff --git a/config/statd-callout b/config/statd-callout
index a9c2e3d..94bd2dd 100755
--- a/config/statd-callout
+++ b/config/statd-callout
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+# This must run as root as CTDB tool commands need to access CTDB socket
+[ $(id -u) -eq 0 ] || exec sudo "$0" "$@"
+
 # this script needs to be installed so that statd points to it with the -H 
 # command line argument. The easiest way to do that is to put something like this in 
 # /etc/sysconfig/nfs:
diff --git a/libctdb/ctdb.c b/libctdb/ctdb.c
index 191b097..6d837c9 100644
--- a/libctdb/ctdb.c
+++ b/libctdb/ctdb.c
@@ -179,12 +179,12 @@ struct ctdb_connection *ctdb_connect(const char *addr,
 	if (ctdb->fd < 0)
 		goto free_fail;
 
-	set_nonblocking(ctdb->fd);
-	set_close_on_exec(ctdb->fd);
-
 	if (connect(ctdb->fd, (struct sockaddr *)&sun, sizeof(sun)) == -1)
 		goto close_fail;
 
+	set_nonblocking(ctdb->fd);
+	set_close_on_exec(ctdb->fd);
+
 	/* Immediately queue a request to get our pnn. */
 	if (!ctdb_getpnn_send(ctdb, CTDB_CURRENT_NODE, set_pnn, NULL))
 		goto close_fail;
diff --git a/packaging/RPM/ctdb.spec.in b/packaging/RPM/ctdb.spec.in
index 50287ab..cb86044 100644
--- a/packaging/RPM/ctdb.spec.in
+++ b/packaging/RPM/ctdb.spec.in
@@ -13,7 +13,7 @@ URL: http://ctdb.samba.org/
 Source: ctdb-%{version}.tar.gz
 
 # Packages
-Requires: coreutils, sed, gawk, iptables, iproute, procps, ethtool
+Requires: coreutils, sed, gawk, iptables, iproute, procps, ethtool, sudo
 # Commands - package name might vary
 Requires: /usr/bin/killall, /bin/kill, /bin/netstat
 # Directories
@@ -96,6 +96,7 @@ rm -rf $RPM_BUILD_ROOT
 # Create the target build directory hierarchy
 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig
 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/init.d
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sudoers.d
 
 make DESTDIR=$RPM_BUILD_ROOT docdir=%{_docdir} install install_tests
 
@@ -136,6 +137,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_docdir}/ctdb/onnode.1.html
 %{_docdir}/ctdb/ltdbtool.1.html
 %{_docdir}/ctdb/ping_pong.1.html
+%{_sysconfdir}/sudoers.d/ctdb
 %{_sysconfdir}/ctdb/events.d/00.ctdb
 %{_sysconfdir}/ctdb/events.d/01.reclock
 %{_sysconfdir}/ctdb/events.d/10.interface
diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c
index d601b17..48704bd 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -1463,7 +1463,13 @@ create_merged_ip_list(struct ctdb_context *ctdb)
 
 			tmp_ip = talloc_zero(ctdb->ip_tree, struct ctdb_public_ip_list);
 			CTDB_NO_MEMORY_NULL(ctdb, tmp_ip);
-			tmp_ip->pnn  = public_ips->ips[j].pnn;
+			/* Do not use information about IP addresses hosted
+			 * on other nodes, it may not be accurate */
+			if (public_ips->ips[j].pnn == ctdb->nodes[i]->pnn) {
+				tmp_ip->pnn = public_ips->ips[j].pnn;
+			} else {
+				tmp_ip->pnn = -1;
+			}
 			tmp_ip->addr = public_ips->ips[j].addr;
 			tmp_ip->next = NULL;
 


-- 
CTDB repository


More information about the samba-cvs mailing list