[Openais] [PATCH]: openais/trunk: Skip callbacks if resource handle does not exist

Ryan O'Hara rohara at redhat.com
Mon Jun 29 09:20:36 PDT 2009


Here is a patch that effectively cancels any pending callbacks if the
resource handle no longer exists.

In saLckDispatch, we check that the resource handle associated with
the callback exists in the handle database. If not, we skip it. This
requires that we pass the resource handle in the callback request,
which is not much of an issue. It also requires that we pass the have
the resource handle available in any call that generates a callback.

Ryan

-------------- next part --------------
Index: include/ipc_lck.h
===================================================================
--- include/ipc_lck.h	(revision 2010)
+++ include/ipc_lck.h	(working copy)
@@ -183,13 +183,14 @@
 
 struct res_lib_lck_resourceopen_callback {
 	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_uint64_t resource_handle __attribute__((aligned(8)));
 	mar_invocation_t invocation __attribute__((aligned(8)));
-	mar_uint64_t resource_handle __attribute__((aligned(8)));
 	mar_uint32_t lock_status __attribute__((aligned(8)));
 } __attribute__((aligned(8)));
 
 struct res_lib_lck_lockgrant_callback {
 	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_uint64_t resource_handle __attribute__((aligned(8)));
 	mar_invocation_t invocation __attribute__((aligned(8)));
 	mar_uint32_t lock_status __attribute__((aligned(8)));
 	mar_uint64_t lock_id __attribute__((aligned(8)));
@@ -197,6 +198,7 @@
 
 struct res_lib_lck_lockwaiter_callback {
 	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_uint64_t resource_handle __attribute__((aligned(8)));
 	mar_uint64_t waiter_signal __attribute__((aligned(8)));
 	mar_uint64_t lock_id __attribute__((aligned(8)));
 	mar_uint32_t mode_held __attribute__((aligned(8)));
@@ -205,6 +207,7 @@
 
 struct res_lib_lck_resourceunlock_callback {
 	coroipc_response_header_t header __attribute__((aligned(8)));
+	mar_uint64_t resource_handle __attribute__((aligned(8)));
 	mar_invocation_t invocation __attribute__((aligned(8)));
 	mar_uint64_t lock_id __attribute__((aligned(8)));
 } __attribute__((aligned(8)));
Index: lib/lck.c
===================================================================
--- lib/lck.c	(revision 2010)
+++ lib/lck.c	(working copy)
@@ -288,14 +288,18 @@
 {
 	struct lckInstance *lckInstance;
 	struct lckLockIdInstance *lckLockIdInstance;
+	struct lckResourceInstance *lckResourceInstance;
+
 	struct res_lib_lck_resourceopen_callback *res_lib_lck_resourceopen_callback;
 	struct res_lib_lck_lockgrant_callback *res_lib_lck_lockgrant_callback;
 	struct res_lib_lck_lockwaiter_callback *res_lib_lck_lockwaiter_callback;
 	struct res_lib_lck_resourceunlock_callback *res_lib_lck_resourceunlock_callback;
+
 	SaLckCallbacksT callbacks;
 	SaAisErrorT error = SA_AIS_OK;
 
 	coroipc_response_header_t *dispatch_data;
+
 	int timeout = 1;
 	int cont = 1;
 
@@ -349,6 +353,21 @@
 			res_lib_lck_resourceopen_callback =
 				(struct res_lib_lck_resourceopen_callback *)dispatch_data;
 
+			/*
+			 * Check that the resource handle is still valid before
+			 * invoking the callback. If the resource handle does not
+			 * exist, we skip this callback.
+			 */
+			error = hdb_error_to_sa (hdb_handle_get (&lckResourceHandleDatabase,
+				res_lib_lck_resourceopen_callback->resource_handle,
+				(void *)&lckResourceInstance));
+			if (error != SA_AIS_OK) {
+				break;
+			}
+
+			hdb_handle_put (&lckResourceHandleDatabase,
+				res_lib_lck_resourceopen_callback->resource_handle);
+
 			callbacks.saLckResourceOpenCallback (
 				res_lib_lck_resourceopen_callback->invocation,
 				res_lib_lck_resourceopen_callback->resource_handle,
@@ -364,6 +383,21 @@
 				(struct res_lib_lck_lockgrant_callback *)dispatch_data;
 
 			/*
+			 * Check that the resource handle is still valid before
+			 * invoking the callback. If the resource handle does not
+			 * exist, we skip this callback.
+			 */
+			error = hdb_error_to_sa (hdb_handle_get (&lckResourceHandleDatabase,
+				res_lib_lck_lockgrant_callback->resource_handle,
+				(void *)&lckResourceInstance));
+			if (error != SA_AIS_OK) {
+				break;
+			}
+
+			hdb_handle_put (&lckResourceHandleDatabase,
+				res_lib_lck_lockgrant_callback->resource_handle);
+
+			/*
 			 * Check that the lock_id is still valid before invoking
 			 * the callback. This is needed to handle the case where
 			 * a lock was unlocked before the callback was processed.
@@ -395,6 +429,21 @@
 			res_lib_lck_lockwaiter_callback =
 				(struct res_lib_lck_lockwaiter_callback *)dispatch_data;
 
+			/*
+			 * Check that the resource handle is still valid before
+			 * invoking the callback. If the resource handle does not
+			 * exist, we skip this callback.
+			 */
+			error = hdb_error_to_sa (hdb_handle_get (&lckResourceHandleDatabase,
+				res_lib_lck_lockwaiter_callback->resource_handle,
+				(void *)&lckResourceInstance));
+			if (error != SA_AIS_OK) {
+				break;
+			}
+
+			hdb_handle_put (&lckResourceHandleDatabase,
+				res_lib_lck_lockwaiter_callback->resource_handle);
+
 			callbacks.saLckLockWaiterCallback (
 				res_lib_lck_lockwaiter_callback->waiter_signal,
 				res_lib_lck_lockwaiter_callback->lock_id,
@@ -411,6 +460,20 @@
 				(struct res_lib_lck_resourceunlock_callback *)dispatch_data;
 
 			/*
+			 * Check that the resource handle is still valid before
+			 * invoking the callback.
+			 */
+			error = hdb_error_to_sa (hdb_handle_get (&lckResourceHandleDatabase,
+				res_lib_lck_resourceunlock_callback->resource_handle,
+				(void *)&lckResourceInstance));
+			if (error != SA_AIS_OK) {
+				break;
+			}
+
+			hdb_handle_put (&lckResourceHandleDatabase,
+				res_lib_lck_resourceunlock_callback->resource_handle);
+
+			/*
 			 * Check that the lock_id is still valid before invoking
 			 * the callback. This is needed to handle the case where
 			 * a lock was unlocked before the callback was processed.
@@ -428,10 +491,9 @@
 				res_lib_lck_resourceunlock_callback->header.error);
 
 			if (error == SA_AIS_OK) {
+				lckLockIdInstanceFinalize (lckLockIdInstance);
 				hdb_handle_put (&lckLockIdHandleDatabase,
 					res_lib_lck_resourceunlock_callback->lock_id);
-
-				lckLockIdInstanceFinalize (lckLockIdInstance);
 			}
 
 			break;
Index: services/lck.c
===================================================================
--- services/lck.c	(revision 2010)
+++ services/lck.c	(working copy)
@@ -532,6 +532,7 @@
 struct req_exec_lck_resourceunlock {
 	coroipc_request_header_t header __attribute__((aligned(8)));
 	mar_message_source_t source __attribute__((aligned(8)));
+	mar_uint64_t resource_handle __attribute__((aligned(8)));
 	mar_name_t resource_name __attribute__((aligned(8)));
 	mar_uint64_t lock_id __attribute__((aligned(8)));
 };
@@ -539,6 +540,7 @@
 struct req_exec_lck_resourceunlockasync {
 	coroipc_request_header_t header __attribute__((aligned(8)));
 	mar_message_source_t source __attribute__((aligned(8)));
+	mar_uint64_t resource_handle __attribute__((aligned(8)));
 	mar_name_t resource_name __attribute__((aligned(8)));
 	mar_uint64_t lock_id __attribute__((aligned(8)));
 	mar_invocation_t invocation __attribute__((aligned(8)));
@@ -1645,8 +1647,9 @@
 		res_lib_lck_lockwaiter_callback.header.error = SA_AIS_OK;
 
 		res_lib_lck_lockwaiter_callback.waiter_signal = request_lock->waiter_signal;
-		res_lib_lck_lockwaiter_callback.lock_id = grant_lock->lock_id; /* ? */
+		res_lib_lck_lockwaiter_callback.lock_id = grant_lock->lock_id;
 		res_lib_lck_lockwaiter_callback.mode_requested = request_lock->lock_mode;
+		res_lib_lck_lockwaiter_callback.resource_handle = grant_lock->resource_handle;
 
 		if (grant_lock->resource->ex_lock_granted != NULL) {
 			res_lib_lck_lockwaiter_callback.mode_held = SA_LCK_EX_LOCK_MODE;
@@ -1692,6 +1695,9 @@
 			MESSAGE_RES_LCK_LOCKGRANT_CALLBACK;
 		res_lib_lck_lockgrant_callback.header.error = error;
 
+		res_lib_lck_lockgrant_callback.resource_handle =
+			resource_lock->resource_handle;
+
 		if (resource_lock != NULL) {
 			res_lib_lck_lockgrant_callback.lock_status =
 				resource_lock->lock_status;
@@ -2351,7 +2357,7 @@
 	lock->lock_flags = req_exec_lck_resourcelock->lock_flags;
 	lock->waiter_signal = req_exec_lck_resourcelock->waiter_signal;
 	/* lock->resource_id = req_exec_lck_resourcelock->resource_id; */
-	/* lock->resource_handle = req_exec_lck_resourcelock->resource_handle; */
+	lock->resource_handle = req_exec_lck_resourcelock->resource_handle;
 
 	list_init (&lock->list);
 	list_init (&lock->resource_lock_list);
@@ -2445,7 +2451,7 @@
 	lock->lock_flags = req_exec_lck_resourcelockasync->lock_flags;
 	lock->waiter_signal = req_exec_lck_resourcelockasync->waiter_signal;
 	/* lock->resource_id = req_exec_lck_resourcelockasync->resource_id; */
-	/* lock->resource_handle = req_exec_lck_resourcelockasync->resource_handle; */
+	lock->resource_handle = req_exec_lck_resourcelockasync->resource_handle;
 
 	list_init (&lock->list);
 	list_init (&lock->resource_lock_list);
@@ -2600,6 +2606,8 @@
 
 		res_lib_lck_resourceunlock_callback.invocation =
 			req_exec_lck_resourceunlockasync->invocation;
+		res_lib_lck_resourceunlock_callback.resource_handle =
+			req_exec_lck_resourceunlockasync->resource_handle;
 		res_lib_lck_resourceunlock_callback.lock_id =
 			req_exec_lck_resourceunlockasync->lock_id;
 
@@ -3175,6 +3183,8 @@
 		&req_lib_lck_resourceunlock->resource_name,
 		sizeof (mar_name_t));
 
+	req_exec_lck_resourceunlock.resource_handle =
+		req_lib_lck_resourceunlock->resource_handle;
 	req_exec_lck_resourceunlock.lock_id =
 		req_lib_lck_resourceunlock->lock_id;
 
@@ -3206,6 +3216,8 @@
 		&req_lib_lck_resourceunlockasync->resource_name,
 		sizeof (mar_name_t));
 
+	req_exec_lck_resourceunlockasync.resource_handle =
+		req_lib_lck_resourceunlockasync->resource_handle;	
 	req_exec_lck_resourceunlockasync.lock_id =
 		req_lib_lck_resourceunlockasync->lock_id;
 	req_exec_lck_resourceunlockasync.invocation =


More information about the Openais mailing list