[PATCH] Support dynamic UDPU membership

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Anton Jouline <anton.jouline@xxxxxxxxxxxxxxxxxx>

We are using a new db object to keep track of dynamic members, called
"totem.interface.dynamic". You create and delete child objects of that object,
using corosync-objctl utility:

to add new member:
corosync-objctl -c totem.interface.dynamic.10-211-55-12

to delete an existing member:
corosync-objctl -d totem.interface.dynamic.10-211-55-12

Then the logic in main.c reacts to those events accordingly, by adding a member
to the member list, or removing an existing one from it. (The object names are
basically IP addresses with dots replaced by dashes, because the dot is used as
separator in object hierarchy.)

The patch was successfully tested with Corosync versions 1.4.1 and 1.4.2.

Signed-off-by: Steven Dake <sdake@xxxxxxxxxx>
---
 exec/main.c      |  107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 exec/totempg.c   |   14 +++++++
 exec/totemudpu.c |   53 +++++++++++++++++++++++++++
 3 files changed, 174 insertions(+), 0 deletions(-)

diff --git a/exec/main.c b/exec/main.c
index aacdc2f..3f40efc 100644
--- a/exec/main.c
+++ b/exec/main.c
@@ -680,6 +680,112 @@ static void corosync_totem_stats_updater (void *data)
 		&corosync_stats_timer_handle);
 }
 
+
+static void totem_dynamic_create_notify_fn(hdb_handle_t parent_object_handle,
+	hdb_handle_t object_handle,
+	const void *name_pt, size_t name_len,
+	void *priv_data_pt)
+{
+	struct totem_ip_address member;
+	int ring_no; 
+	int numbers[4];
+	int i;
+	char *object_name;
+
+	object_name = strndup(name_pt, name_len);
+	log_printf(LOGSYS_LEVEL_DEBUG, 
+		"create_object: %s\n", object_name);
+
+	memset(numbers, 0, sizeof numbers);
+	if (sscanf(object_name, "%d-%d-%d-%d",
+		&numbers[0], &numbers[1], &numbers[2], &numbers[3]) == 4) {
+		/*
+		 * prepare totem_ip_address struct
+		 */
+		ring_no = 0;
+		member.family = AF_INET;
+		for (i=0;i<4;i++) {
+			member.addr[i] = numbers[i];
+		}
+
+		/*
+		 * add new member
+		 */
+		totempg_member_add (&member, ring_no);
+	}
+
+	free(object_name);
+}
+
+static void totem_dynamic_destroy_notify_fn(hdb_handle_t parent_object_handle,
+	const void *name_pt, size_t name_len,
+	void *priv_data_pt)
+{
+	struct totem_ip_address member;
+	int ring_no; 
+	int numbers[4];
+	int i;
+	char *object_name;
+
+	object_name = strndup(name_pt, name_len);
+	log_printf(LOGSYS_LEVEL_DEBUG, 
+		"destroy_object: %s\n", object_name);
+
+	memset(numbers, 0, sizeof numbers);
+	if (sscanf(object_name, "%d-%d-%d-%d",
+			&numbers[0], &numbers[1], &numbers[2], &numbers[3]) == 4) {
+		/* prepare totem_ip_address struct */
+		ring_no = 0;
+		member.family = AF_INET;
+		for (i=0;i<4;i++) {
+			member.addr[i] = numbers[i];
+		}
+
+		/*
+		 * add new member
+		 */
+		totempg_member_remove(&member, ring_no);
+	}
+
+	free(object_name);
+
+}
+
+static void corosync_totem_dynamic_init (void)
+{
+	hdb_handle_t object_find_handle;
+	hdb_handle_t object_totem_handle;
+	hdb_handle_t object_interface_handle;
+
+	if (objdb->object_find_create(OBJECT_PARENT_HANDLE,
+			"totem", strlen("totem"), &object_find_handle) != 0) {
+		log_printf(LOGSYS_LEVEL_NOTICE, 
+			"corosync_totem_dynamic_init:: FAILED to find totem!\n");
+		return;
+	}
+	if (objdb->object_find_next (object_find_handle,
+			&object_totem_handle) != 0) {
+		return;
+	}
+
+	if (objdb->object_find_create(object_totem_handle,
+			"interface", strlen("interface"), &object_find_handle) != 0) {
+		log_printf(LOGSYS_LEVEL_NOTICE, 
+			"corosync_totem_dynamic_init:: FAILED to find totem.interface!\n");
+		return;
+	}
+	if (objdb->object_find_next (object_find_handle,
+			&object_interface_handle) != 0) {
+		return;
+	}
+
+	objdb->object_track_start (object_interface_handle,
+		OBJECT_TRACK_DEPTH_RECURSIVE,
+		NULL,
+		totem_dynamic_create_notify_fn,
+		totem_dynamic_destroy_notify_fn,
+		NULL, NULL);
+}
 static void corosync_totem_stats_init (void)
 {
 	totempg_stats_t * stats;
@@ -1128,6 +1234,7 @@ static void main_service_ready (void)
 	cs_ipcs_init();
 	corosync_totem_stats_init ();
 	corosync_fplay_control_init ();
+	corosync_totem_dynamic_init ();
 	if (minimum_sync_mode == CS_SYNC_V2) {
 		log_printf (LOGSYS_LEVEL_NOTICE, "Compatibility mode set to none.  Using V2 of the synchronization engine.\n");
 		sync_v2_init (
diff --git a/exec/totempg.c b/exec/totempg.c
index 9e88104..99a80e9 100644
--- a/exec/totempg.c
+++ b/exec/totempg.c
@@ -1444,6 +1444,20 @@ void totempg_queue_level_register_callback (totem_queue_level_changed_fn fn)
 	totem_queue_level_changed = fn;
 }
 
+ extern int totempg_member_add (
+ 	const struct totem_ip_address *member,
+	int ring_no)
+{
+	return totemmrp_member_add (member, ring_no);
+}
+ 
+ extern int totempg_member_remove (
+ 	const struct totem_ip_address *member,
+	int ring_no)
+{
+	return totemmrp_member_remove (member, ring_no);
+}
+
 extern int totempg_member_add (
 	const struct totem_ip_address *member,
 	int ring_no);
diff --git a/exec/totemudpu.c b/exec/totemudpu.c
index 21e57c7..86e84e8 100644
--- a/exec/totemudpu.c
+++ b/exec/totemudpu.c
@@ -1677,6 +1677,9 @@ int totemudpu_member_add (
 	if (new_member == NULL) {
 		return (-1);
 	}
+	log_printf(LOGSYS_LEVEL_NOTICE, "totemudpu_member_add:: adding new member {%d.%d.%d.%d}\n", 
+		member->addr[0], member->addr[1], 
+		member->addr[2], member->addr[3]);
 	list_init (&new_member->list);
 	list_add_tail (&new_member->list, &instance->member_list);
 	memcpy (&new_member->member, member, sizeof (struct totem_ip_address));
@@ -1708,12 +1711,62 @@ int totemudpu_member_add (
 	return (0);
 }
 
+int _same_ip(const struct totem_ip_address *a, const struct totem_ip_address *b);
+
+int _same_ip(const struct totem_ip_address *a, const struct totem_ip_address *b)
+{
+	return a->addr[0] == b->addr[0]
+		&& a->addr[1] == b->addr[1]
+		&& a->addr[2] == b->addr[2]
+		&& a->addr[3] == b->addr[3];
+		
+}
+
 int totemudpu_member_remove (
 	void *udpu_context,
 	const struct totem_ip_address *token_target)
 {
+	int found = 0;
+	struct list_head *list;
+	struct totemudpu_member *member;
+
 	struct totemudpu_instance *instance = (struct totemudpu_instance *)udpu_context;
 
+	/*
+	 * Find the member to remove and close its socket
+	 */
+	for (list = instance->member_list.next;
+		list != &instance->member_list;
+		list = list->next) {
+
+		member = list_entry (list,
+			struct totemudpu_member,
+			list);
+
+		if (_same_ip(token_target, &member->member)) {
+			log_printf(LOGSYS_LEVEL_NOTICE, "totemudpu_member_remove:: removing member {%d.%d.%d.%d}\n", 
+				member->member.addr[0], member->member.addr[1], 
+				member->member.addr[2], member->member.addr[3]);
+
+			if (member->fd > 0) {
+				log_printf(LOGSYS_LEVEL_NOTICE, "Closing socket to: {%d.%d.%d.%d}\n",
+					member->member.addr[0], member->member.addr[1],
+					member->member.addr[2], member->member.addr[3]);
+				close (member->fd);
+				cs_poll_dispatch_delete (instance->totemudpu_poll_handle,
+					member->fd);
+			}
+			found = 1;
+			break;
+		}
+	}
+
+	/*
+	 * Delete the member from the list
+	 */
+	if (found)
+		list_del(list);
+
 	instance = NULL;
 	return (0);
 }
-- 
1.7.6.4

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux