[Openais] [PATCH]: openais/trunk: Remove resource from cleanup list on close

Ryan O'Hara rohara at redhat.com
Tue Jul 7 20:25:44 PDT 2009


When calling saLckResourceClose, we must remove that resource from the
cleanup list for the process calling saLckResourceClose. Without this,
it is possible that when the process exits and calls lck_lib_exit_fn,
the resource will have its reference count decremented again. This can
result in a resource not being removed correctly, since reference
count would be corrupt and would fail the the check we make before
removing a resource.

Once the details of the problem (and test case) are sorted out, the
fix is obvious: remove the resource from the cleanup list for every
close.

Thanks for Honza for finding this and Steve for his help diagnosing
the problem.

Ryan

-------------- next part --------------
Index: services/lck.c
===================================================================
--- services/lck.c	(revision 2025)
+++ services/lck.c	(working copy)
@@ -1593,6 +1593,28 @@
 	return (0);
 }
 
+static struct resource_cleanup *lck_resource_cleanup_find (
+	void *conn,
+	const mar_name_t *resource_name)
+{
+	struct lck_pd *lck_pd = (struct lck_pd *)api->ipc_private_data_get (conn);
+
+	struct resource_cleanup *cleanup;
+	struct list_head *cleanup_list;
+
+	for (cleanup_list = lck_pd->resource_cleanup_list.next;
+	     cleanup_list != &lck_pd->resource_cleanup_list;
+	     cleanup_list = cleanup_list->next)
+	{
+		cleanup = list_entry (cleanup_list, struct resource_cleanup, cleanup_list);
+
+		if (mar_name_match (resource_name, &cleanup->resource_name)) {
+			return (cleanup);
+		}
+	}
+	return (0);
+}
+
 static void lck_resourcelock_response_send (
 	struct resource_lock *resource_lock,
 	SaAisErrorT error)
@@ -2240,6 +2262,7 @@
 	SaAisErrorT error = SA_AIS_OK;
 
 	struct resource *resource = NULL;
+	struct resource_cleanup *cleanup = NULL;
 
 	/* DEBUG */
 	log_printf (LOGSYS_LEVEL_DEBUG, "EXEC request: saLckResourceClose\n");
@@ -2259,6 +2282,10 @@
 		req_exec_lck_resourceclose->exit_flag,
 		&req_exec_lck_resourceclose->source);
 
+	/*
+	 * If reference count is zero and there are no granted locks,
+	 * we can remove this resource.
+	 */
 	if ((resource->refcount == 0) &&
 	    (resource->ex_lock_granted == NULL) &&
 	    (list_empty (&resource->pr_lock_granted_list_head)))
@@ -2267,6 +2294,18 @@
 		free (resource);
 	}
 
+	/*
+	 * Remove the cleanup entry for this resource.
+	 */
+	cleanup = lck_resource_cleanup_find (
+		req_exec_lck_resourceclose->source.conn,
+		&req_exec_lck_resourceclose->resource_name);
+
+	assert (cleanup != NULL);
+
+	list_del (&cleanup->cleanup_list);
+	free (cleanup);
+
 error_exit:
 	if (api->ipc_source_is_local (&req_exec_lck_resourceclose->source))
 	{


More information about the Openais mailing list