[SCM] CTDB repository - branch master updated - ctdb-1.13-205-g9a806de

Ronnie Sahlberg sahlberg at samba.org
Tue Jun 19 23:18:01 MDT 2012


The branch, master has been updated
       via  9a806dec8687e2ec08a308853b61af6aed5e5d1e (commit)
       via  c6bf22ba5c01001b7febed73dd16a03bd3fd2bed (commit)
       via  f07376309e70f5ccdb7de8453caacc71b451ab48 (commit)
      from  8307c70ed98996b430c470e9641a09fdeeb81bd8 (commit)

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


- Log -----------------------------------------------------------------
commit 9a806dec8687e2ec08a308853b61af6aed5e5d1e
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 c6bf22ba5c01001b7febed73dd16a03bd3fd2bed
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 f07376309e70f5ccdb7de8453caacc71b451ab48
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 |   82 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/ctdb_private.h |    1 +
 server/ctdb_recoverd.c |    8 +++-
 server/ctdb_takeover.c |   22 +++++-------
 tools/ctdb.c           |   22 +++++++++++++
 5 files changed, 120 insertions(+), 15 deletions(-)


Changeset truncated at 500 lines:

diff --git a/common/system_common.c b/common/system_common.c
index 3fe90e6..6ee615f 100644
--- a/common/system_common.c
+++ b/common/system_common.c
@@ -75,3 +75,85 @@ bool ctdb_sys_have_ip(ctdb_sock_addr *_addr)
 }
 
 
+/* 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 7c3fdf0..0f9da36 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -1144,6 +1144,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);
 bool ctdb_sys_check_iface_exists(const char *iface);
 int ctdb_get_peer_pid(const int fd, pid_t *peer_pid);
 int ctdb_sys_send_tcp(const ctdb_sock_addr *dest, 
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index b380746..7b7435c 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -2864,9 +2864,13 @@ static int verify_local_ip_allocation(struct ctdb_context *ctdb, struct ctdb_rec
 				}
 			} else {
 				if (ctdb->do_checkpublicip && 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 0ba12b1..cb6aa83 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -794,6 +794,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);
@@ -818,24 +819,18 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
 			ctdb_vnn_unassign_iface(ctdb, vnn);
 			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)));
-			return 0;
-		}
-
-	} else if (vnn->iface == NULL) {
-		DEBUG(DEBUG_ERR, ("No interface found for IP %s.\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);
@@ -852,9 +847,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 07a47db..b806d2b 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -2077,6 +2077,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)
@@ -5792,6 +5813,7 @@ static const struct {
 	{ "nodestatus",      control_nodestatus,        true,   false,  "show and return node status" },
 	{ "dbstatistics",    control_dbstatistics,      false,	false, "show db statistics", "<db>" },
 	{ "reloadips",       control_reloadips,         false,	false, "reload the public addresses file on a node" },
+	{ "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