[SCM] CTDB repository - branch 1.2.40 updated - ctdb-1.2.45

Amitay Isaacs amitay at samba.org
Thu Jul 12 23:09:02 MDT 2012


The branch, 1.2.40 has been updated
       via  95efb0cffb19a4311d706b2fd7031834a2711022 (commit)
       via  32d6d39626df46a1c0bb21554497685279ead88a (commit)
       via  0c6d9b84b12d32cb8f563f441377eaf2c9648b99 (commit)
       via  e609b63bc3dd2eb838fbf11997a49730c89a6a5e (commit)
      from  8c3aed36615e083e0b91efd70380b7711f9f9f7e (commit)

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


- Log -----------------------------------------------------------------
commit 95efb0cffb19a4311d706b2fd7031834a2711022
Author: Martin Schwenke <martin at meltin.net>
Date:   Thu Jul 12 14:03:58 2012 +1000

    New version 1.2.45
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>

commit 32d6d39626df46a1c0bb21554497685279ead88a
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Jun 20 15:10:05 2012 +1000

    When we find an ip we shouldnt host, just release it
    
    Dont call a full blown clusterwide ipreallocation,  just release it locally

commit 0c6d9b84b12d32cb8f563f441377eaf2c9648b99
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Jun 20 10:08:11 2012 +1000

    When we release an ip, get the interface name from the kernel
    
    instead of using the interface where ctdb thinks the ip is hosted at.
    The difference is that this now allows us to handle cases where we want to release an ip   but ctdbd does not know which interface the ip is assigned on.
    (user has used 'ip addr add...'  and manually assigned an ip to the wrong interface)

commit e609b63bc3dd2eb838fbf11997a49730c89a6a5e
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Jun 20 13:32:02 2012 +1000

    Add new command to find which interface is located on

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

Summary of changes:
 common/system_common.c     |   84 ++++++++++++++++++++++++++++++++++++++++++++
 include/ctdb_private.h     |    1 +
 packaging/RPM/ctdb.spec.in |    4 ++-
 server/ctdb_recoverd.c     |    8 +++-
 server/ctdb_takeover.c     |   15 ++++----
 tools/ctdb.c               |   22 +++++++++++
 6 files changed, 124 insertions(+), 10 deletions(-)


Changeset truncated at 500 lines:

diff --git a/common/system_common.c b/common/system_common.c
index f28045f..6ee615f 100644
--- a/common/system_common.c
+++ b/common/system_common.c
@@ -73,3 +73,87 @@ bool ctdb_sys_have_ip(ctdb_sock_addr *_addr)
 	close(s);
 	return ret == 0;
 }
+
+
+/* find which interface an ip address is currently assigned to */
+char *ctdb_sys_find_ifname(ctdb_sock_addr *addr)
+{
+	int s;
+	int size;
+	struct ifconf ifc;
+	char *ptr;
+
+	s = socket(AF_INET, SOCK_RAW, htons(IPPROTO_RAW));
+	if (s == -1) {
+		DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket (%s)\n",
+			 strerror(errno)));
+		return NULL;
+	}
+
+
+	size = sizeof(struct ifreq);
+	ifc.ifc_buf = NULL;
+	ifc.ifc_len = size;
+
+	while(ifc.ifc_len > (size - sizeof(struct ifreq))) {
+		size *= 2;
+
+		free(ifc.ifc_buf);	
+		ifc.ifc_len = size;
+		ifc.ifc_buf = malloc(size);
+		memset(ifc.ifc_buf, 0, size);
+		if (ioctl(s, SIOCGIFCONF, (caddr_t)&ifc) < 0) {
+			DEBUG(DEBUG_CRIT,("Failed to read ifc buffer from socket\n"));
+			free(ifc.ifc_buf);	
+			close(s);
+			return NULL;
+		}
+	}
+
+	for (ptr =(char *)ifc.ifc_buf; ptr < ((char *)ifc.ifc_buf) + ifc.ifc_len; ) {
+		char *ifname;
+		struct ifreq *ifr;
+
+		ifr = (struct ifreq *)ptr;
+
+#ifdef HAVE_SOCKADDR_LEN
+		if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) {
+			ptr += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
+		} else {
+			ptr += sizeof(ifr->ifr_name) + sizeof(struct sockaddr);
+		}
+#else
+		ptr += sizeof(struct ifreq);
+#endif
+
+		if (ifr->ifr_addr.sa_family != addr->sa.sa_family) {
+			continue;
+		}
+
+		switch (addr->sa.sa_family) {
+		case AF_INET:
+
+
+			if (memcmp(&addr->ip.sin_addr, &((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr, sizeof(addr->ip.sin_addr))) {
+				continue;
+			}
+			break;
+		case AF_INET6:
+			if (memcmp(&addr->ip6.sin6_addr, &((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_addr, sizeof(addr->ip6.sin6_addr))) {
+				continue;
+			}
+			break;
+		}
+
+		ifname = strdup(ifr->ifr_name);
+		free(ifc.ifc_buf);	
+		close(s);
+		return ifname;
+	}
+
+
+	free(ifc.ifc_buf);	
+	close(s);
+
+	return NULL;
+}
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index e3b5a20..3a5d3cf 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -1126,6 +1126,7 @@ int ctdb_ctrl_set_iface_link(struct ctdb_context *ctdb,
 uint32_t uint16_checksum(uint16_t *data, size_t n);
 int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface);
 bool ctdb_sys_have_ip(ctdb_sock_addr *addr);
+char *ctdb_sys_find_ifname(ctdb_sock_addr *addr);
 int ctdb_sys_send_tcp(const ctdb_sock_addr *dest, 
 		      const ctdb_sock_addr *src,
 		      uint32_t seq, uint32_t ack, int rst);
diff --git a/packaging/RPM/ctdb.spec.in b/packaging/RPM/ctdb.spec.in
index 575872c..ee25a0c 100644
--- a/packaging/RPM/ctdb.spec.in
+++ b/packaging/RPM/ctdb.spec.in
@@ -3,7 +3,7 @@ Name: ctdb
 Summary: Clustered TDB
 Vendor: Samba Team
 Packager: Samba Team <samba at samba.org>
-Version: 1.2.44
+Version: 1.2.45
 Release: 1GITHASH
 Epoch: 0
 License: GNU GPL version 3
@@ -144,6 +144,8 @@ development libraries for ctdb
 %{_libdir}/libctdb.a
 
 %changelog
+* Thu Jul 12 2012 : Version 1.2.45
+ - Robust removal of rogue public IPs
 * Fri Jun 29 2012 : Version 1.2.44
  - improvements to the policy routing support
 * Thu Mar 29 2012 : Version 1.2.43
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index bf19089..a6a748e 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -2659,9 +2659,13 @@ static int verify_local_ip_allocation(struct ctdb_context *ctdb, struct ctdb_rec
 				}
 			} else {
 				if (ctdb_sys_have_ip(&ips->ips[j].addr)) {
-					DEBUG(DEBUG_CRIT,("We are still serving a public address '%s' that we should not be serving.\n", 
+
+					DEBUG(DEBUG_CRIT,("We are still serving a public address '%s' that we should not be serving. Removing it.\n", 
 						ctdb_addr_to_str(&ips->ips[j].addr)));
-					need_takeover_run = true;
+
+					if (ctdb_ctrl_release_ip(ctdb, CONTROL_TIMEOUT(), CTDB_CURRENT_NODE, &ips->ips[j]) != 0) {
+						DEBUG(DEBUG_ERR,("Failed to release local ip address\n"));
+					}
 				}
 			}
 		}
diff --git a/server/ctdb_takeover.c b/server/ctdb_takeover.c
index 3dc1e46..e04ea6a 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -784,6 +784,7 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
 	struct takeover_callback_state *state;
 	struct ctdb_public_ip *pip = (struct ctdb_public_ip *)indata.dptr;
 	struct ctdb_vnn *vnn;
+	char *iface;
 
 	/* update our vnn list */
 	vnn = find_public_ip_vnn(ctdb, &pip->addr);
@@ -807,17 +808,16 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
 		return 0;
 	}
 
-	if (vnn->iface == NULL) {
-		DEBUG(DEBUG_ERR,(__location__ " release_ip of IP %s is known to the kernel, "
-				 "but we have no interface assigned, has someone manually configured it? Ignore for now.\n",
-				 ctdb_addr_to_str(&vnn->public_address)));
+	iface = ctdb_sys_find_ifname(&pip->addr);
+	if (iface == NULL) {
+		DEBUG(DEBUG_ERR, ("Could not find which interface the ip address is hosted on. can not release it\n"));
 		return 0;
 	}
 
 	DEBUG(DEBUG_NOTICE,("Release of IP %s/%u on interface %s  node:%d\n",
 		ctdb_addr_to_str(&pip->addr),
-		vnn->public_netmask_bits, 
-		ctdb_vnn_iface_string(vnn),
+		vnn->public_netmask_bits,
+		iface,
 		pip->pnn));
 
 	state = talloc(ctdb, struct takeover_callback_state);
@@ -834,9 +834,10 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
 					 false,
 					 CTDB_EVENT_RELEASE_IP,
 					 "%s %s %u",
-					 ctdb_vnn_iface_string(vnn),
+					 iface,
 					 ctdb_addr_to_str(&pip->addr),
 					 vnn->public_netmask_bits);
+	free(iface);
 	if (ret != 0) {
 		DEBUG(DEBUG_ERR,(__location__ " Failed to release IP %s on interface %s\n",
 			ctdb_addr_to_str(&pip->addr),
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 2c7fdc3..03373a2 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -1812,6 +1812,27 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
 	return 0;
 }
 
+/*
+  add a public ip address to a node
+ */
+static int control_ipiface(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+	ctdb_sock_addr addr;
+
+	if (argc != 1) {
+		usage();
+	}
+
+	if (!parse_ip(argv[0], NULL, 0, &addr)) {
+		printf("Badly formed ip : %s\n", argv[0]);
+		return -1;
+	}
+
+	printf("IP on interface %s\n", ctdb_sys_find_ifname(&addr));
+
+	return 0;
+}
+
 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv);
 
 static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **argv, ctdb_sock_addr *addr)
@@ -5178,6 +5199,7 @@ static const struct {
 	{ "writekey", 	     control_writekey,      	true,	false,  "write to a database key", "<tdb-file> <key> <value>" },
 	{ "checktcpport",    control_chktcpport,      	false,	true,  "check if a service is bound to a specific tcp port or not", "<port>" },
 	{ "rebalancenode",     control_rebalancenode,	false,	false, "release a node by allowing it to takeover ips", "<pnn>"},
+	{ "ipiface",         control_ipiface,           true,	true,  "Find which interface an ip address is hsoted on", "<ip>" },
 };
 
 /*


-- 
CTDB repository


More information about the samba-cvs mailing list