[asterisk-commits] mmichelson: branch group/CCSS r227680 - in /team/group/CCSS: include/asterisk...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Nov 4 11:46:51 CST 2009


Author: mmichelson
Date: Wed Nov  4 11:46:48 2009
New Revision: 227680

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=227680
Log:
Create a bottom-up monitor destruction mechanism, as well as a public
function to trigger it.

When a specific monitor fails for some reason, it may call ast_cc_monitor_failed in
order to start the bottom-up destruction process, which works essentially in the opposite
direction of prune_links. This way, we destroy the individual faulty monitor instead of
destroying everything just because one has failed. The logic works such that the failure
may propagate up the tree if necessary.

The next step will be to analyze my usage of ast_cc_failed in the core to be ensure that
I should not actually be using ast_cc_monitor_failed in those circumstances.


Modified:
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/main/ccss.c

Modified: team/group/CCSS/include/asterisk/ccss.h
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/include/asterisk/ccss.h?view=diff&rev=227680&r1=227679&r2=227680
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Wed Nov  4 11:46:48 2009
@@ -988,7 +988,7 @@
  * \param debug A debug message to print to the CC log
  * \return void
  */
-void ast_cc_monitor_failed(int core_id, const char * const monitor_name, const char * const debug);
+int ast_cc_monitor_failed(int core_id, const char * const monitor_name, const char * const monitor_type);
 
 /* END STATE CHANGE API */
 

Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=227680&r1=227679&r2=227680
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Wed Nov  4 11:46:48 2009
@@ -2904,6 +2904,111 @@
 	return cc_request_state_change(CC_FAILED, core_id, debug);
 }
 
+struct cc_monitor_failure_data {
+	struct ast_cc_monitor *monitor;
+	int core_id;
+};
+
+static int pass_failure_up(struct ast_cc_monitor *monitor, struct ast_cc_monitor_link *parent_link, const int core_id)
+{
+	struct ast_cc_monitor *parent_monitor = cc_ref(parent_link->parent, "Ref parent monitor");
+	struct ast_cc_monitor_link *link_iter;
+
+	/* First things first, kill the link */
+	destroy_link(parent_link);
+
+	/* Next determine if the parent monitor also needs to pass info up. If the parent monitor
+	 * has no more links left with this core ID, then it means that it should also pass the
+	 * failure up.
+	 */
+	AST_LIST_TRAVERSE(&parent_monitor->child_links, link_iter, next_child) {
+		if (link_iter->core_id == core_id) {
+			break;
+		}
+	}
+
+	cc_unref(monitor, "Killed the link to the failed monitor. Unref it");
+
+	if (link_iter) {
+		/* There are still child links with this core ID, so this
+		 * monitor should not pass a failure up the tree
+		 */
+		cc_unref(parent_monitor, "Still child links available. Unref our local reference");
+		return 0;
+	}
+
+	if (parent_monitor->interface->monitor_class == AST_CC_ROOT_MONITOR) {
+		/* We've reached the top of the tree, which means that what may have
+		 * started as a localized failure has progressed to a global one instead.
+		 */
+		cc_unref(parent_monitor, "Parent is the root. Unref our local reference");
+		return ast_cc_failed(core_id, "All monitors have failed");
+	}
+
+	/* The parent monitor is an extension monitor who no longer has any children with
+	 * this core_id. We need to pass the failure up to the next parent monitor in the tree.
+	 */
+	AST_LIST_TRAVERSE(&parent_monitor->parent_links, link_iter, next_parent) {
+		if (link_iter->core_id == core_id) {
+			break;
+		}
+	}
+
+	if (!link_iter) {
+		/* The parent monitor doesn't have a parent link with our core_id? WHAT?! */
+		cc_unref(parent_monitor, "Parent didn't have an upstream link with proper core ID. Unref");
+		return -1;
+	}
+
+	pass_failure_up(parent_monitor, link_iter, core_id);
+
+	return 0;
+}
+
+static int cc_monitor_failed(void *data)
+{
+	struct cc_monitor_failure_data *failure_data = data;
+	int core_id = failure_data->core_id;
+	struct ast_cc_monitor *monitor = failure_data->monitor;
+	struct ast_cc_monitor_link *parent_link;
+
+	ast_free(failure_data);
+
+	AST_LIST_TRAVERSE(&monitor->parent_links, parent_link, next_parent) {
+		if (parent_link->core_id == core_id) {
+			break;
+		}
+	}
+
+	if (!parent_link) {
+		cc_unref(monitor, "Can't find a parent link to report failure on. Unref monitor.");
+		return -1;
+	}
+
+	return pass_failure_up(monitor, parent_link, core_id);
+}
+
+int ast_cc_monitor_failed(int core_id, const char *const monitor_name, const char * const monitor_type)
+{
+	struct ast_cc_monitor *monitor = find_monitor(monitor_name, monitor_type);
+	struct cc_monitor_failure_data *failure_data = ast_calloc(1, sizeof(*failure_data));
+
+	if (!monitor) {
+		ast_log(LOG_WARNING, "Couldn't find a monitor with name %s and type %s\n", monitor_name, monitor_type);
+		return -1;
+	}
+
+	if (!failure_data) {
+		cc_unref(monitor, "Failed to allocate failure data, unref monitor that we found");
+		return -1;
+	}
+
+	failure_data->monitor = monitor; /* No need to ref since find_monitor already did that */
+	failure_data->core_id = core_id;
+
+	return ast_taskprocessor_push(cc_core_taskprocessor, cc_monitor_failed, failure_data);
+}
+
 static int cc_status_request(void *data)
 {
 	struct cc_core_instance *core_instance= data;




More information about the asterisk-commits mailing list