[SCM] CTDB repository - branch master updated - ctdb-1.11-8-ga3e8784

Ronnie Sahlberg sahlberg at samba.org
Wed Sep 7 17:57:01 MDT 2011


The branch, master has been updated
       via  a3e8784bb107f7acd2a95913c1e6def52ce96105 (commit)
       via  9abf9c919a7e6789695490e2c3de56c21b63fa57 (commit)
       via  cd33bbe6454b7b0316bdfffbd06c67b29779e873 (commit)
      from  32320ee278d1eec9aef18b400c0ddaa445d4211e (commit)

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


- Log -----------------------------------------------------------------
commit a3e8784bb107f7acd2a95913c1e6def52ce96105
Merge: 32320ee278d1eec9aef18b400c0ddaa445d4211e 9abf9c919a7e6789695490e2c3de56c21b63fa57
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Tue Sep 6 17:29:30 2011 +1000

    Merge branch 'master' of 10.1.1.27:/shared/ctdb/ctdb-master

commit 9abf9c919a7e6789695490e2c3de56c21b63fa57
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Tue Sep 6 17:02:19 2011 +1000

    Interface monitoring: add a event to trigger every 30 seconds to check that all interfaces referenced by the public address list actually exists.
    
    This will make it much easier to root-cause problems such as
    S1029023
    when an external application deleted the interface while it is still is in use by ctdbd.

commit cd33bbe6454b7b0316bdfffbd06c67b29779e873
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Tue Sep 6 16:11:00 2011 +1000

    Check interfaces:  when reading the public addresses file to create the vnn list
    check that the actual interface exist, print error and fail startup if the interface does not exist.

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

Summary of changes:
 common/system_aix.c    |    4 +++
 common/system_common.c |    2 +
 common/system_linux.c  |   22 ++++++++++++++++++
 include/ctdb_private.h |    2 +
 server/ctdb_takeover.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 88 insertions(+), 0 deletions(-)


Changeset truncated at 500 lines:

diff --git a/common/system_aix.c b/common/system_aix.c
index 5fe5413..1404a82 100644
--- a/common/system_aix.c
+++ b/common/system_aix.c
@@ -357,4 +357,8 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
 }
 
 
+bool ctdb_sys_check_iface_exists(const char *iface)
+{
+	return true;
+}
 
diff --git a/common/system_common.c b/common/system_common.c
index f28045f..3fe90e6 100644
--- a/common/system_common.c
+++ b/common/system_common.c
@@ -73,3 +73,5 @@ bool ctdb_sys_have_ip(ctdb_sock_addr *_addr)
 	close(s);
 	return ret == 0;
 }
+
+
diff --git a/common/system_linux.c b/common/system_linux.c
index a498ab2..2dcdffb 100644
--- a/common/system_linux.c
+++ b/common/system_linux.c
@@ -537,3 +537,25 @@ int ctdb_sys_read_tcp_packet(int s, void *private_data,
 }
 
 
+bool ctdb_sys_check_iface_exists(const char *iface)
+{
+	int s;
+	struct ifreq ifr;
+
+	s = socket(PF_PACKET, SOCK_RAW, 0);
+	if (s == -1){
+		/* We dont know if the interface exists, so assume yes */
+		DEBUG(DEBUG_CRIT,(__location__ " failed to open raw socket\n"));
+		return true;
+	}
+
+	strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
+	if (ioctl(s, SIOCGIFINDEX, &ifr) < 0 && errno == ENODEV) {
+		DEBUG(DEBUG_CRIT,(__location__ " interface '%s' not found\n", iface));
+		close(s);
+		return false;
+	}
+	close(s);
+	
+	return true;
+}
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index b24efcc..b74cbcf 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -414,6 +414,7 @@ struct ctdb_context {
 	uint32_t recovery_mode;
 	TALLOC_CTX *tickle_update_context;
 	TALLOC_CTX *keepalive_ctx;
+	TALLOC_CTX *check_public_ifaces_ctx;
 	struct ctdb_tunable tunable;
 	enum ctdb_freeze_mode freeze_mode[NUM_DB_PRIORITIES+1];
 	struct ctdb_freeze_handle *freeze_handles[NUM_DB_PRIORITIES+1];
@@ -1111,6 +1112,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);
+bool ctdb_sys_check_iface_exists(const char *iface);
 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/server/ctdb_takeover.c b/server/ctdb_takeover.c
index 1e2e829..4114b40 100644
--- a/server/ctdb_takeover.c
+++ b/server/ctdb_takeover.c
@@ -880,6 +880,16 @@ static int ctdb_add_public_address(struct ctdb_context *ctdb,
 	int i;
 	int ret;
 
+	tmp = talloc_strdup(vnn, ifaces);
+	for (iface = strtok(tmp, ","); iface; iface = strtok(NULL, ",")) {
+		if (!ctdb_sys_check_iface_exists(iface)) {
+			DEBUG(DEBUG_CRIT,("Interface %s does not exist. Can not add public-address : %s\n", iface, ctdb_addr_to_str(addr)));
+			talloc_free(tmp);
+			return -1;
+		}
+	}
+	talloc_free(tmp);
+
 	/* Verify that we dont have an entry for this ip yet */
 	for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
 		if (ctdb_same_sockaddr(addr, &vnn->public_address)) {
@@ -941,6 +951,51 @@ int ctdb_set_event_script_dir(struct ctdb_context *ctdb, const char *script_dir)
 	return 0;
 }
 
+static void ctdb_check_interfaces_event(struct event_context *ev, struct timed_event *te, 
+				  struct timeval t, void *private_data)
+{
+	struct ctdb_context *ctdb = talloc_get_type(private_data, 
+							struct ctdb_context);
+	struct ctdb_vnn *vnn;
+
+	for (vnn=ctdb->vnn;vnn;vnn=vnn->next) {
+		int i;
+
+		for (i=0; vnn->ifaces[i] != NULL; i++) {
+			if (!ctdb_sys_check_iface_exists(vnn->ifaces[i])) {
+				DEBUG(DEBUG_CRIT,("Interface %s does not exist but is used by public ip %s\n",
+					vnn->ifaces[i],
+					ctdb_addr_to_str(&vnn->public_address)));
+			}
+		}
+	}
+
+	event_add_timed(ctdb->ev, ctdb->check_public_ifaces_ctx, 
+		timeval_current_ofs(30, 0), 
+		ctdb_check_interfaces_event, ctdb);
+}
+
+
+static int ctdb_start_monitoring_interfaces(struct ctdb_context *ctdb)
+{
+	if (ctdb->check_public_ifaces_ctx != NULL) {
+		talloc_free(ctdb->check_public_ifaces_ctx);
+		ctdb->check_public_ifaces_ctx = NULL;
+	}
+
+	ctdb->check_public_ifaces_ctx = talloc_new(ctdb);
+	if (ctdb->check_public_ifaces_ctx == NULL) {
+		ctdb_fatal(ctdb, "failed to allocate context for checking interfaces");
+	}
+
+	event_add_timed(ctdb->ev, ctdb->check_public_ifaces_ctx, 
+		timeval_current_ofs(30, 0), 
+		ctdb_check_interfaces_event, ctdb);
+
+	return 0;
+}
+
+
 /*
   setup the public address lists from a file
 */
@@ -1003,6 +1058,9 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist)
 		}
 	}
 
+
+	ctdb_start_monitoring_interfaces(ctdb);
+
 	talloc_free(lines);
 	return 0;
 }


-- 
CTDB repository


More information about the samba-cvs mailing list