Attached is a patch that adds synchronization support for the LCK
service. Some minor code cleanup is included, as well as basic test
code (test/testlck2.c).

The LCK service is still in development. Specifically, lock stripping
and orphans are not implemented at this time.

Ryan

Index: test/Makefile
===================================================================
--- test/Makefile       (revision 1683)
+++ test/Makefile       (working copy)
@@ -40,9 +40,9 @@
        override LDFLAGS += -lnsl -lsocket -lrt
 endif
 
-LIBRARIES= ../lib/libSaCkpt.a ../lib/libSaMsg.a ../lib/libSaEvt.a sa_error.o
+LIBRARIES= ../lib/libSaCkpt.a ../lib/libSaLck.a ../lib/libSaMsg.a 
../lib/libSaEvt.a sa_error.o
 LIBS = $(LIBRARIES) 
-BINARIES= testckpt testmsg testmsg2 testmsg3 testevt
+BINARIES= testckpt testlck testlck2 testmsg testmsg2 testmsg3 testevt
 
 override CFLAGS += -I../include
 override LDFLAGS += -L../lib
@@ -55,6 +55,12 @@
 testckpt: testckpt.o $(LIBRARIES)
        $(CC) $(LDFLAGS) -o testckpt testckpt.o $(LIBS)
 
+testlck: testlck.o $(LIBRARIES)
+       $(CC) $(LDFLAGS) -o testlck testlck.o $(LIBS)
+
+testlck2: testlck2.o $(LIBRARIES)
+       $(CC) $(LDFLAGS) -o testlck2 testlck2.o $(LIBS)
+
 testmsg: testmsg.o $(LIBRARIES)
        $(CC) $(LDFLAGS) -o testmsg testmsg.o $(LIBS)
 
Index: test/testlck2.c
===================================================================
--- test/testlck2.c     (revision 0)
+++ test/testlck2.c     (revision 0)
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2008 Red Hat Software, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Ryan O'Hara ([email protected])
+ *
+ * This software licensed under BSD license, the text of which follows:
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+
+#include "saAis.h"
+#include "saLck.h"
+
+void testLckResourceOpenCallback (
+       SaInvocationT invocation,
+       SaLckResourceHandleT lockResourceHandle,
+       SaAisErrorT error)
+{
+       printf ("testLckResourceOpenCallback\n");
+}
+
+void testLckLockGrantCallback (
+       SaInvocationT invocation,
+       SaLckLockStatusT lockStatus,
+       SaAisErrorT error)
+{
+       printf ("testLckLockGrantCallback\n");
+}
+
+void testLckLockWaiterCallback (
+       SaLckWaiterSignalT waiterSignal,
+        SaLckLockIdT lockId,
+        SaLckLockModeT modeHeld,
+        SaLckLockModeT modeRequested)
+{
+       printf ("testLckLockWaiterCallback\n");
+}
+
+void testLckResourceUnlockCallback (
+       SaInvocationT invocation,
+        SaAisErrorT error)
+{
+       printf ("testLckResourceUnlockCallback\n");
+}
+
+SaLckCallbacksT callbacks = {
+       .saLckResourceOpenCallback      = testLckResourceOpenCallback,
+       .saLckLockGrantCallback         = testLckLockGrantCallback,
+       .saLckLockWaiterCallback        = testLckLockWaiterCallback,
+       .saLckResourceUnlockCallback    = testLckResourceUnlockCallback
+};
+
+SaVersionT version = { 'B', 1, 1 };
+
+void setSaNameT (SaNameT *name, char *str) {
+       strncpy ((char *)name->value, str, SA_MAX_NAME_LENGTH);
+       if (strlen ((char *)name->value) > SA_MAX_NAME_LENGTH) {
+               name->length = SA_MAX_NAME_LENGTH;
+       } else {
+               name->length = strlen (str);
+       }
+}
+
+void sigintr_handler (int signum) {
+       exit (0);
+}
+
+int main (void)
+{
+       int result;
+
+       SaLckHandleT handle;
+       SaLckLockIdT lock_id;
+       SaLckLockStatusT status;
+
+       SaLckResourceHandleT resource_handle_a;
+       SaLckResourceHandleT resource_handle_b;
+       SaLckResourceHandleT resource_handle_c;
+
+       SaNameT resource_name_a;
+       SaNameT resource_name_b;
+       SaNameT resource_name_c;
+
+       result = saLckInitialize (&handle, &callbacks, &version);
+
+       if (result != SA_AIS_OK) {
+               printf ("[ERROR]: (%d) saLckInitialize\n", result);
+               exit (1);
+       }
+
+       setSaNameT (&resource_name_a, "test_resource_a");
+       setSaNameT (&resource_name_b, "test_resource_b");
+       setSaNameT (&resource_name_c, "test_resource_c");
+
+       /*
+        * Open resources
+        */
+       result = saLckResourceOpen (handle, &resource_name_a,
+                                   SA_LCK_RESOURCE_CREATE, SA_TIME_ONE_SECOND,
+                                   &resource_handle_a);
+       printf ("[DEBUG]: (%d) saLckResourceOpen { %s }\n",
+               result, (char *)(resource_name_a.value));
+
+       result = saLckResourceOpen (handle, &resource_name_b,
+                                   SA_LCK_RESOURCE_CREATE, SA_TIME_ONE_SECOND,
+                                   &resource_handle_b);
+       printf ("[DEBUG]: (%d) saLckResourceOpen { %s }\n",
+               result, (char *)(resource_name_b.value));
+
+       result = saLckResourceOpen (handle, &resource_name_c,
+                                   SA_LCK_RESOURCE_CREATE, SA_TIME_ONE_SECOND,
+                                   &resource_handle_c);
+       printf ("[DEBUG]: (%d) saLckResourceOpen { %s }\n",
+               result, (char *)(resource_name_c.value));
+
+       /*
+        * Add resource locks to resource "A"
+        */
+       result = saLckResourceLock (resource_handle_a, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_a.value), lock_id, status);
+
+       result = saLckResourceLock (resource_handle_a, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_a.value), lock_id, status);
+
+       result = saLckResourceLock (resource_handle_a, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_a.value), lock_id, status);
+
+       /*
+        * Add resource locks to resource "B"
+        */
+       result = saLckResourceLock (resource_handle_b, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_b.value), lock_id, status);
+
+       result = saLckResourceLock (resource_handle_b, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_b.value), lock_id, status);
+
+       result = saLckResourceLock (resource_handle_b, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_b.value), lock_id, status);
+
+       /*
+        * Add resource locks to resource "C"
+        */
+       result = saLckResourceLock (resource_handle_c, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_c.value), lock_id, status);
+
+       result = saLckResourceLock (resource_handle_c, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_c.value), lock_id, status);
+
+       result = saLckResourceLock (resource_handle_c, &lock_id,
+                                  SA_LCK_PR_LOCK_MODE, SA_LCK_LOCK_ORPHAN,
+                                  55, SA_TIME_END, &status);
+       printf ("[DEBUG]: (%d) saLckResourceLock { %s } [ id=%x status=%d ]\n",
+               result, (char *)(resource_name_c.value), lock_id, status);
+
+       sleep (30);
+
+       return (0);
+}
Index: services/lck.c
===================================================================
--- services/lck.c      (revision 1683)
+++ services/lck.c      (working copy)
@@ -55,6 +55,7 @@
 #include <corosync/swab.h>
 #include <corosync/engine/coroapi.h>
 #include <corosync/engine/logsys.h>
+
 #include "../include/saAis.h"
 #include "../include/saAis.h"
 #include "../include/saLck.h"
@@ -68,10 +69,13 @@
        MESSAGE_REQ_EXEC_LCK_RESOURCELOCK = 2,
        MESSAGE_REQ_EXEC_LCK_RESOURCEUNLOCK = 3,
        MESSAGE_REQ_EXEC_LCK_RESOURCELOCKORPHAN = 4,
-       MESSAGE_REQ_EXEC_LCK_LOCKPURGE = 5
+       MESSAGE_REQ_EXEC_LCK_LOCKPURGE = 5,
+       MESSAGE_REQ_EXEC_LCK_SYNC_RESOURCE = 6,
+       MESSAGE_REQ_EXEC_LCK_SYNC_RESOURCE_LOCK = 7,
 };
 
 struct resource;
+
 struct resource_lock {
        SaLckLockModeT lock_mode;
        SaLckLockIdT lock_id;
@@ -84,9 +88,8 @@
        SaInvocationT invocation;
        mar_message_source_t callback_source;
        mar_message_source_t response_source;
-       struct list_head list; /* locked resource lock list */
-       struct list_head resource_list; /* resource locks on a resource */
-       struct list_head resource_cleanup_list; /* cleanup data for resource 
locks */
+       struct list_head list;
+       struct list_head resource_list;
 };
 
 struct resource {
@@ -101,7 +104,7 @@
 };
 
 struct resource_cleanup {
-       struct resource *resource;
+       mar_name_t name;
        SaLckResourceHandleT resource_handle;
        struct list_head resource_lock_list_head;
        struct list_head list;
@@ -109,12 +112,24 @@
 
 DECLARE_LIST_INIT(resource_list_head);
 
+DECLARE_LIST_INIT(sync_resource_list_head);
+
+static struct corosync_api_v1 *api;
+
+/* static int lck_dump_fn (void); */
+
 static int lck_exec_init_fn (struct corosync_api_v1 *);
 
 static int lck_lib_exit_fn (void *conn);
 
 static int lck_lib_init_fn (void *conn);
 
+static unsigned int my_member_list[PROCESSOR_COUNT_MAX];
+
+static unsigned int my_member_list_entries = 0;
+
+static unsigned int my_lowest_nodeid = 0;
+
 static void message_handler_req_exec_lck_resourceopen (
        void *message,
        unsigned int nodeid);
@@ -139,6 +154,14 @@
        void *message,
        unsigned int nodeid);
 
+static void message_handler_req_exec_lck_sync_resource (
+       void *message,
+       unsigned int nodeid);
+
+static void message_handler_req_exec_lck_sync_resource_lock (
+       void *message,
+       unsigned int nodeid);
+
 static void message_handler_req_lib_lck_resourceopen (
        void *conn,
        void *msg);
@@ -172,25 +195,23 @@
        void *msg);
 
 static void exec_lck_resourceopen_endian_convert (void *msg);
-
 static void exec_lck_resourceclose_endian_convert (void *msg);
-
 static void exec_lck_resourcelock_endian_convert (void *msg);
-
 static void exec_lck_resourceunlock_endian_convert (void *msg);
-
 static void exec_lck_resourcelockorphan_endian_convert (void *msg);
-
 static void exec_lck_lockpurge_endian_convert (void *msg);
+static void exec_lck_resource_endian_convert (void *msg);
+static void exec_lck_resource_lock_endian_convert (void *msg);
+static void exec_lck_sync_resource_endian_convert (void *msg);
+static void exec_lck_sync_resource_lock_endian_convert (void *msg);
 
-#ifdef TODO
 static void lck_sync_init (void);
-#endif
-static int lck_sync_process (void);
+static int  lck_sync_process (void);
 static void lck_sync_activate (void);
 static void lck_sync_abort (void);
 
 void resource_release (struct resource *resource);
+void resource_lock_release (struct resource_lock *resource_lock);
 
 /*
 static struct list_head *recovery_lck_next = 0;
@@ -198,10 +219,9 @@
 static int recovery_section_data_offset = 0;
 static int recovery_section_send_flag = 0;
 static int recovery_abort = 0;
-//static struct memb_ring_id saved_ring_id;
 */
 
-static struct corosync_api_v1 *api;
+static struct memb_ring_id my_saved_ring_id;
 
 static void lck_confchg_fn (
        enum totem_configuration_type configuration_type,
@@ -215,7 +235,6 @@
        struct list_head resource_cleanup_list;
 };
 
-
 /*
  * Executive Handler Definition
  */
@@ -296,7 +315,15 @@
        {
                .exec_handler_fn        = 
message_handler_req_exec_lck_lockpurge,
                .exec_endian_convert_fn = exec_lck_lockpurge_endian_convert
-       }
+       },
+       {
+               .exec_handler_fn        = 
message_handler_req_exec_lck_sync_resource,
+               .exec_endian_convert_fn = exec_lck_sync_resource_endian_convert
+       },
+       {
+               .exec_handler_fn        = 
message_handler_req_exec_lck_sync_resource_lock,
+               .exec_endian_convert_fn = 
exec_lck_sync_resource_lock_endian_convert
+       },
 };
 
 struct corosync_service_engine lck_service_engine = {
@@ -309,12 +336,11 @@
        .lib_engine                     = lck_lib_engine,
        .lib_engine_count               = sizeof (lck_lib_engine) / sizeof 
(struct corosync_lib_handler),
        .exec_init_fn                   = lck_exec_init_fn,
+       .exec_dump_fn                   = NULL,
        .exec_engine                    = lck_exec_engine,
        .exec_engine_count              = sizeof (lck_exec_engine) / sizeof 
(struct corosync_exec_handler),
-       .exec_dump_fn                   = NULL,
        .confchg_fn                     = lck_confchg_fn,
-       .sync_init                      = NULL,
-//     .sync_init                      = lck_sync_init,
+       .sync_init                      = lck_sync_init,
        .sync_process                   = lck_sync_process,
        .sync_activate                  = lck_sync_activate,
        .sync_abort                     = lck_sync_abort,
@@ -490,20 +516,334 @@
        swab_req_lib_lck_lockpurge (&to_swab->req_lib_lck_lockpurge);
 }
 
-#ifdef TODO
+struct req_exec_lck_sync_resource {
+       mar_req_header_t header;
+       struct memb_ring_id ring_id;
+       mar_name_t resource_name;
+};
+
+static void exec_lck_sync_resource_endian_convert (void *msg)
+{
+       struct req_exec_lck_sync_resource *to_swab =
+               (struct req_exec_lck_sync_resource *)msg;
+
+       swab_mar_req_header_t (&to_swab->header);
+       /* swab_mar_memb_ring_id_t (&to_swab->memb_ring_id); */
+       swab_mar_name_t (&to_swab->resource_name);
+}
+
+struct req_exec_lck_sync_resource_lock {
+       mar_req_header_t header;
+       struct memb_ring_id ring_id;
+       mar_name_t resource_name;
+       SaLckLockIdT lock_id;
+       SaLckLockModeT lock_mode;
+       SaLckLockFlagsT lock_flags;
+       SaLckWaiterSignalT waiter_signal;
+       SaLckLockStatusT lock_status;
+       SaTimeT timeout;
+};
+
+static void exec_lck_sync_resource_lock_endian_convert (void *msg)
+{
+       struct req_exec_lck_sync_resource_lock *to_swab =
+               (struct req_exec_lck_sync_resource_lock *)msg;
+
+       swab_mar_req_header_t (&to_swab->header);
+       /* swab_mar_memb_ring_id_t (&to_swab->memb_ring_id); */
+       swab_mar_name_t (&to_swab->resource_name);
+       to_swab->lock_id = swab64 (to_swab->lock_id);
+       to_swab->lock_mode = swab64 (to_swab->lock_mode);
+       to_swab->lock_flags = swab32 (to_swab->lock_flags);
+       to_swab->waiter_signal = swab32 (to_swab->waiter_signal);
+       to_swab->lock_status = swab64 (to_swab->lock_status);
+       to_swab->timeout = swab64 (to_swab->timeout);
+}
+
+static void print_resource_lock_list (struct resource *resource)
+{
+       struct list_head *list;
+       struct resource_lock *resource_lock;
+
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: resource_lock_list ...\n");
+
+       for (list = resource->resource_lock_list_head.next;
+            list != &resource->resource_lock_list_head;
+            list = list->next)
+       {
+               resource_lock = list_entry (list, struct resource_lock, 
resource_list);
+
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]:\t id=%u mode=%u 
status=%u addr=%p\n",
+                           (unsigned int)(resource_lock->lock_id),
+                           (unsigned int)(resource_lock->lock_mode),
+                           (unsigned int)(resource_lock->lock_status),
+                           (void *)(resource_lock));
+       }
+}
+
+static void print_pr_pending_list (struct resource *resource)
+{
+       struct list_head *list;
+       struct resource_lock *resource_lock;
+
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: pr_pending_list ...\n");
+
+       for (list = resource->pr_pending_list_head.next;
+            list != &resource->pr_pending_list_head;
+            list = list->next)
+       {
+               resource_lock = list_entry (list, struct resource_lock, list);
+
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]:\t id=%u mode=%u 
status=%u addr=%p\n",
+                           (unsigned int)(resource_lock->lock_id),
+                           (unsigned int)(resource_lock->lock_mode),
+                           (unsigned int)(resource_lock->lock_status),
+                           (void *)(resource_lock));
+       }
+}
+
+static void print_pr_granted_list (struct resource *resource)
+{
+       struct list_head *list;
+       struct resource_lock *resource_lock;
+
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: pr_granted_list ...\n");
+
+       for (list = resource->pr_granted_list_head.next;
+            list != &resource->pr_granted_list_head;
+            list = list->next)
+       {
+               resource_lock = list_entry (list, struct resource_lock, list);
+
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]:\t id=%u mode=%u 
status=%u addr=%p\n",
+                           (unsigned int)(resource_lock->lock_id),
+                           (unsigned int)(resource_lock->lock_mode),
+                           (unsigned int)(resource_lock->lock_status),
+                           (void *)(resource_lock));
+       }
+}
+
+static void print_ex_pending_list (struct resource *resource)
+{
+       struct list_head *list;
+       struct resource_lock *resource_lock;
+
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: ex_pending_list ...\n");
+
+       for (list = resource->ex_pending_list_head.next;
+            list != &resource->ex_pending_list_head;
+            list = list->next)
+       {
+               resource_lock = list_entry (list, struct resource_lock, list);
+
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]:\t id=%u mode=%u 
status=%u addr=%p\n",
+                           (unsigned int)(resource_lock->lock_id),
+                           (unsigned int)(resource_lock->lock_mode),
+                           (unsigned int)(resource_lock->lock_status),
+                           (void *)(resource_lock));
+       }
+}
+
+static void print_resource_list (struct list_head *head)
+{
+       struct list_head *list;
+       struct resource *resource;
+
+       for (list = head->next;
+            list != head;
+            list = list->next)
+       {
+               resource = list_entry (list, struct resource, list);
+
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: print_resource_list { 
name=%s addr=%p }\n",
+                           get_mar_name_t (&resource->name), (void 
*)(resource));
+
+               print_resource_lock_list (resource);
+       }
+}
+
+void resource_release (struct resource *resource)
+{
+       struct resource_lock *resource_lock;
+       struct list_head *list;
+
+       /* DEBUG */
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: resource_release { name=%s 
addr=%p }\n",
+                   get_mar_name_t (&resource->name), (void *)(resource));
+
+       for (list = resource->resource_lock_list_head.next;
+            list != &resource->resource_lock_list_head;)
+       {
+               resource_lock = list_entry (list, struct resource_lock, 
resource_list);
+
+               list = list->next;
+
+               resource_lock_release (resource_lock);
+       }
+
+       list_del (&resource->list);
+}
+
+void resource_lock_release (struct resource_lock *resource_lock)
+{
+       /* DEBUG */
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: resource_lock_release { id=%u 
addr=%p }\n",
+                   (unsigned int)(resource_lock->lock_id), (void 
*)(resource_lock));
+
+       list_del (&resource_lock->list);
+       free (resource_lock);
+}
+
+static inline void sync_resource_free (struct list_head *head)
+{
+       struct resource *resource;
+       struct list_head *list;
+
+       list = head->next;
+
+       while (list != head) {
+               resource = list_entry (list, struct resource, list);
+
+               list = list->next;
+
+               resource_release (resource);
+       }
+
+       list_init (head);
+
+       return;
+}
+
+static inline void sync_resource_lock_free (struct list_head *head)
+{
+       return;
+}
+
+static int sync_resource_transmit (
+       struct resource *resource)
+{
+       struct req_exec_lck_sync_resource req_exec_lck_sync_resource;
+       struct iovec iovec;
+
+       memset (&req_exec_lck_sync_resource, 0,
+               sizeof (struct req_exec_lck_sync_resource));
+
+       req_exec_lck_sync_resource.header.size =
+               sizeof (struct req_exec_lck_sync_resource);
+       req_exec_lck_sync_resource.header.id =
+               SERVICE_ID_MAKE (LCK_SERVICE, 
MESSAGE_REQ_EXEC_LCK_SYNC_RESOURCE);
+
+       memcpy (&req_exec_lck_sync_resource.ring_id,
+               &my_saved_ring_id, sizeof (struct memb_ring_id));
+       memcpy (&req_exec_lck_sync_resource.resource_name,
+               &resource->name, sizeof (mar_name_t));
+
+       iovec.iov_base = (char *)&req_exec_lck_sync_resource;
+       iovec.iov_len = sizeof (req_exec_lck_sync_resource);
+
+       return (api->totem_mcast (&iovec, 1, TOTEM_AGREED));
+}
+
+static int sync_resource_lock_transmit (
+       struct resource *resource,
+       struct resource_lock *resource_lock)
+{
+       struct req_exec_lck_sync_resource_lock req_exec_lck_sync_resource_lock;
+       struct iovec iovec;
+
+       memset (&req_exec_lck_sync_resource_lock, 0,
+               sizeof (struct req_exec_lck_sync_resource_lock));
+
+       req_exec_lck_sync_resource_lock.header.size =
+               sizeof (struct req_exec_lck_sync_resource_lock);
+       req_exec_lck_sync_resource_lock.header.id =
+               SERVICE_ID_MAKE (LCK_SERVICE, 
MESSAGE_REQ_EXEC_LCK_SYNC_RESOURCE_LOCK);
+
+       memcpy (&req_exec_lck_sync_resource_lock.ring_id,
+               &my_saved_ring_id, sizeof (struct memb_ring_id));
+       memcpy (&req_exec_lck_sync_resource_lock.resource_name,
+               &resource->name, sizeof (mar_name_t));
+
+       req_exec_lck_sync_resource_lock.lock_id = resource_lock->lock_id;
+       req_exec_lck_sync_resource_lock.lock_mode = resource_lock->lock_mode;
+       req_exec_lck_sync_resource_lock.lock_flags = resource_lock->lock_flags;
+       req_exec_lck_sync_resource_lock.waiter_signal = 
resource_lock->waiter_signal;
+       req_exec_lck_sync_resource_lock.lock_status = 
resource_lock->lock_status;
+       req_exec_lck_sync_resource_lock.timeout = resource_lock->timeout;
+
+       iovec.iov_base = (char *)&req_exec_lck_sync_resource_lock;
+       iovec.iov_len = sizeof (req_exec_lck_sync_resource_lock);
+
+       return (api->totem_mcast (&iovec, 1, TOTEM_AGREED));
+}
+
+static int sync_resource_iterate (void)
+{
+       struct resource *resource;
+       struct resource_lock *resource_lock;
+       struct list_head *resource_list;
+       struct list_head *resource_lock_list;
+       unsigned int res = 0;
+
+       for (resource_list = resource_list_head.next;
+            resource_list != &resource_list_head;
+            resource_list = resource_list->next)
+       {
+               resource = list_entry (resource_list, struct resource, list);
+
+               res = sync_resource_transmit (resource);
+               if (res != 0) {
+                       break;
+               }
+
+               for (resource_lock_list = 
resource->resource_lock_list_head.next;
+                    resource_lock_list != &resource->resource_lock_list_head;
+                    resource_lock_list = resource_lock_list->next)
+               {
+                       resource_lock = list_entry (resource_lock_list,
+                                                   struct resource_lock,
+                                                   resource_list);
+
+                       res = sync_resource_lock_transmit (resource, 
resource_lock);
+                       if (res != 0) {
+                               break;
+                       }
+               }
+       }
+
+       return (res);
+}
+
 static void lck_sync_init (void)
 {
        return;
 }
-#endif
 
 static int lck_sync_process (void)
 {
+       unsigned int res = 0;
+
+       if (my_lowest_nodeid == api->totem_nodeid_get ()) {
+               TRACE1 ("transmit resources because lowest member in old 
configuration.\n");
+
+               res = sync_resource_iterate ();
+       }
+
        return (0);
 }
 
 static void lck_sync_activate (void)
 {
+       sync_resource_free (&resource_list_head);
+
+       list_init (&resource_list_head);
+
+       if (!list_empty (&sync_resource_list_head)) {
+               list_splice (&sync_resource_list_head, &resource_list_head);
+       }
+
+       list_init (&sync_resource_list_head);
+
        return;
 }
 
@@ -519,20 +859,55 @@
        unsigned int *joined_list, int joined_list_entries,
        struct memb_ring_id *ring_id)
 {
+       unsigned int i, j;
+
+       /*
+        * Determine lowest nodeid in old regular configuration for the
+        * purpose of executing the synchronization algorithm
+        */
+       if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) {
+               for (i = 0; i < left_list_entries; i++) {
+                       for (j = 0; j < my_member_list_entries; j++) {
+                               if (left_list[i] == my_member_list[j]) {
+                                       my_member_list[j] = 0;
+                               }
+                       }
+               }
+       }
+
+       my_lowest_nodeid = 0xffffffff;
+
+       /*
+        * Handle regular configuration
+        */
+       if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
+               memcpy (my_member_list, member_list,
+                       sizeof (unsigned int) * member_list_entries);
+               my_member_list_entries = member_list_entries;
+               memcpy (&my_saved_ring_id, ring_id,
+                       sizeof (struct memb_ring_id));
+               for (i = 0; i < my_member_list_entries; i++) {
+                       if ((my_member_list[i] != 0) &&
+                           (my_member_list[i] < my_lowest_nodeid)) {
+                               my_lowest_nodeid = my_member_list[i];
+                       }
+               }
+       }
 }
 
-static struct resource *resource_find (mar_name_t *name)
+static struct resource *lck_resource_find (
+       struct list_head *head,
+       mar_name_t *name)
 {
        struct list_head *resource_list;
        struct resource *resource;
 
-   for (resource_list = resource_list_head.next;
-        resource_list != &resource_list_head;
-        resource_list = resource_list->next) {
+       for (resource_list = head->next;
+            resource_list != head;
+            resource_list = resource_list->next)
+       {
+               resource = list_entry (resource_list, struct resource, list);
 
-        resource = list_entry (resource_list,
-            struct resource, list);
-
                if (mar_name_match (name, &resource->name)) {
                        return (resource);
                }
@@ -540,7 +915,7 @@
        return (0);
 }
 
-static struct resource_lock *resource_lock_find (
+static struct resource_lock *lck_resource_lock_find (
        struct resource *resource,
        mar_message_source_t *source,
        SaLckLockIdT lock_id)
@@ -549,15 +924,14 @@
        struct resource_lock *resource_lock;
 
        for (list = resource->resource_lock_list_head.next;
-               list != &resource->resource_lock_list_head;
-               list = list->next) {
-
+            list != &resource->resource_lock_list_head;
+            list = list->next)
+       {
                resource_lock = list_entry (list, struct resource_lock, 
resource_list);
 
                if ((memcmp (&resource_lock->callback_source,
-                       source, sizeof (mar_message_source_t)) == 0) &&
-                       (lock_id == resource_lock->lock_id)) {
-
+                            source, sizeof (mar_message_source_t)) == 0) &&
+                   (lock_id == resource_lock->lock_id)) {
                        return (resource_lock);
                }
        }
@@ -573,9 +947,11 @@
        struct lck_pd *lck_pd = (struct lck_pd *)api->ipc_private_data_get 
(conn);
 
        for (list = lck_pd->resource_cleanup_list.next;
-               list != &lck_pd->resource_cleanup_list; list = list->next) {
+            list != &lck_pd->resource_cleanup_list;
+            list = list->next)
+       {
+               resource_cleanup = list_entry (list, struct resource_cleanup, 
list);
 
-               resource_cleanup = list_entry (list, struct resource_cleanup, 
list);
                if (resource_cleanup->resource_handle == resource_handle) {
                        return (resource_cleanup);
                }
@@ -583,8 +959,7 @@
        return (0);
 }
 
-
-int lck_resource_close (struct resource *resource)
+int lck_resource_close (mar_name_t *resource_name)
 {
        struct req_exec_lck_resourceclose req_exec_lck_resourceclose;
        struct iovec iovec;
@@ -595,7 +970,7 @@
                SERVICE_ID_MAKE (LCK_SERVICE, 
MESSAGE_REQ_EXEC_LCK_RESOURCECLOSE);
 
        memcpy (&req_exec_lck_resourceclose.lockResourceName,
-               &resource->name, sizeof (mar_name_t));
+               resource_name, sizeof (mar_name_t));
 
        iovec.iov_base = (char *)&req_exec_lck_resourceclose;
        iovec.iov_len = sizeof (req_exec_lck_resourceclose);
@@ -604,7 +979,6 @@
                assert (api->totem_mcast (&iovec, 1, TOTEM_AGREED) == 0);
                return (0);
        }
-
        return (-1);
 }
 
@@ -638,31 +1012,52 @@
        struct resource_cleanup *resource_cleanup)
 {
        struct list_head *list;
+       struct resource *resource;
        struct resource_lock *resource_lock;
 
-       for (list = resource_cleanup->resource_lock_list_head.next;
-               list != &resource_cleanup->resource_lock_list_head;
-               list = list->next) {
+       /* DEBUG */
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: resource_cleanup_lock_remove { 
%s }\n",
+                   get_mar_name_t (&resource_cleanup->name));
 
-               resource_lock = list_entry (list, struct resource_lock, 
resource_cleanup_list);
+       resource = lck_resource_find (&resource_list_head,
+               &resource_cleanup->name);
+
+       assert (resource != NULL);
+
+       for (list = resource->resource_lock_list_head.next;
+            list != &resource->resource_lock_list_head;
+            list = list->next)
+       {
+               resource_lock = list_entry (list, struct resource_lock, 
resource_list);
+
+               /* DEBUG */
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]:\t lock_id=%u addr=%p\n",
+                           (unsigned int)(resource_lock->lock_id),
+                           (void *)(resource_lock));
+
                resource_lock_orphan (resource_lock);
        }
+
 }
 
 void lck_resource_cleanup_remove (
        void *conn,
        SaLckResourceHandleT resource_handle)
 {
-
        struct list_head *list;
        struct resource_cleanup *resource_cleanup;
        struct lck_pd *lck_pd = (struct lck_pd *)api->ipc_private_data_get 
(conn);
 
+       /* DEBUG */
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: resource_cleanup_remove { %s 
}\n",
+                   get_mar_name_t (&resource_cleanup->name));
+
        for (list = lck_pd->resource_cleanup_list.next;
-               list != &lck_pd->resource_cleanup_list;
-               list = list->next) {
+            list != &lck_pd->resource_cleanup_list;
+            list = list->next) {
 
                resource_cleanup = list_entry (list, struct resource_cleanup, 
list);
+
                if (resource_cleanup->resource_handle == resource_handle) {
                        list_del (&resource_cleanup->list);
                        free (resource_cleanup);
@@ -671,7 +1066,6 @@
        }
 }
 
-
 static int lck_exec_init_fn (struct corosync_api_v1 *corosync_api)
 {
        api = corosync_api;
@@ -688,21 +1082,28 @@
        struct list_head *cleanup_list;
        struct lck_pd *lck_pd = (struct lck_pd *)api->ipc_private_data_get 
(conn);
 
-       log_printf(LOG_LEVEL_NOTICE, "lck_exit_fn conn_info %p\n", conn);
+       log_printf (LOG_LEVEL_DEBUG, "lck_exit_fn conn_info %p\n", conn);
 
-       /*
-        * close all resources opened on this fd
-        */
        cleanup_list = lck_pd->resource_cleanup_list.next;
-       while (!list_empty(cleanup_list)) {
 
+       while (!list_empty(&lck_pd->resource_cleanup_list)) {
+
                resource_cleanup = list_entry (cleanup_list, struct 
resource_cleanup, list);
 
-               if (resource_cleanup->resource->name.length > 0) {
+               /* if (resource_cleanup->resource->name.length > 0) {
                        lck_resource_cleanup_lock_remove (resource_cleanup);
                        lck_resource_close (resource_cleanup->resource);
-               }
+               }*/
 
+               assert (resource_cleanup->name.length != 0);
+
+               /* DEBUG */
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: resource_cleanup { %s 
}\n",
+                           get_mar_name_t (&resource_cleanup->name));
+
+               lck_resource_cleanup_lock_remove (resource_cleanup);
+               lck_resource_close (&resource_cleanup->name);
+
                list_del (&resource_cleanup->list);
                free (resource_cleanup);
 
@@ -712,12 +1113,42 @@
        return (0);
 }
 
+#if 0
+static int lck_lib_exit_fn (void *conn)
+{
+       struct resource_cleanup *resource_cleanup;
+       struct list_head *cleanup_list;
+       struct lck_pd *lck_pd = (struct lck_pd *)api->ipc_private_data_get 
(conn);
+
+       log_printf (LOG_LEVEL_DEBUG, "lck_exit_fn conn_info %p\n", conn);
+
+       for (cleanup_list = lck_pd->resource_cleanup_list.next;
+            cleanup_list != &lck_pd->resource_cleanup_list;
+            cleanup_list = cleanup_list->next)
+       {
+               resource_cleanup = list_entry (cleanup_list, struct 
resource_cleanup, list);
+
+               /* DEBUG */
+               log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: resource_cleanup { %s 
}\n",
+                           get_mar_name_t (&resource_cleanup->name));
+
+               lck_resource_cleanup_lock_remove (resource_cleanup);
+               lck_resource_close (resource_cleanup->name);
+       }
+
+       return (0);
+}
+#endif
+
 static int lck_lib_init_fn (void *conn)
 {
-    struct lck_pd *lck_pd = (struct lck_pd *)api->ipc_private_data_get (conn);
+       struct lck_pd *lck_pd = (struct lck_pd *)api->ipc_private_data_get 
(conn);
 
+       log_printf (LOG_LEVEL_DEBUG, "lck_init_fn conn_info %p\n", conn);
+
        list_init (&lck_pd->resource_list);
        list_init (&lck_pd->resource_cleanup_list);
+
        return (0);
 }
 
@@ -725,7 +1156,8 @@
        void *message,
        unsigned int nodeid)
 {
-       struct req_exec_lck_resourceopen *req_exec_lck_resourceopen = (struct 
req_exec_lck_resourceopen *)message;
+       struct req_exec_lck_resourceopen *req_exec_lck_resourceopen =
+               (struct req_exec_lck_resourceopen *)message;
        struct res_lib_lck_resourceopen res_lib_lck_resourceopen;
        struct res_lib_lck_resourceopenasync res_lib_lck_resourceopenasync;
        struct resource *resource;
@@ -741,71 +1173,60 @@
                goto error_exit;
        }
 
-       resource = resource_find (&req_exec_lck_resourceopen->resource_name);
+       resource = lck_resource_find (&resource_list_head,
+               &req_exec_lck_resourceopen->resource_name);
 
-       /*
-        * If resource doesn't exist, create one
-        */
-       if (resource == 0) {
+       if (resource == NULL) {
                if ((req_exec_lck_resourceopen->open_flags & 
SA_LCK_RESOURCE_CREATE) == 0) {
                        error = SA_AIS_ERR_NOT_EXIST;
                        goto error_exit;
                }
                resource = malloc (sizeof (struct resource));
-               if (resource == 0) {
+               if (resource == NULL) {
                        error = SA_AIS_ERR_NO_MEMORY;
                        goto error_exit;
                }
                memset (resource, 0, sizeof (struct resource));
-
                memcpy (&resource->name,
                        &req_exec_lck_resourceopen->resource_name,
                        sizeof (mar_name_t));
+
                list_init (&resource->list);
                list_init (&resource->resource_lock_list_head);
-               list_add (&resource->list, &resource_list_head);
+               /* list_add (&resource->list, &resource_list_head); */
+               list_add_tail (&resource->list, &resource_list_head);
                list_init (&resource->pr_granted_list_head);
                list_init (&resource->pr_pending_list_head);
                list_init (&resource->ex_pending_list_head);
+
                resource->refcount = 0;
                resource->ex_granted = NULL;
        }
 
-       /*
-        * Setup connection information and mark resource as referenced
-        */
        if (api->ipc_source_is_local (&req_exec_lck_resourceopen->source)) {
-               log_printf (LOG_LEVEL_DEBUG, "Lock resource opened is %p\n", 
resource);
                resource_cleanup = malloc (sizeof (struct resource_cleanup));
-               if (resource_cleanup == 0) {
+               if (resource_cleanup == NULL) {
                        free (resource);
                        error = SA_AIS_ERR_NO_MEMORY;
-               } else { 
+               } else {
                        lck_pd = (struct lck_pd *)api->ipc_private_data_get 
(req_exec_lck_resourceopen->source.conn);
                        list_init (&resource_cleanup->list);
                        list_init (&resource_cleanup->resource_lock_list_head);
-                       resource_cleanup->resource = resource;
-                       log_printf (LOG_LEVEL_DEBUG, "resource is %p\n", 
resource);
+                       /* resource_cleanup->resource = resource; */
                        resource_cleanup->resource_handle = 
req_exec_lck_resourceopen->resource_handle;
-                       list_add (
-                               &resource_cleanup->list,
-                               &lck_pd->resource_cleanup_list);
+
+                       memcpy (&resource_cleanup->name,
+                               &req_exec_lck_resourceopen->resource_name,
+                               sizeof (mar_name_t));
+
+                       /* list_add (&resource_cleanup->list, 
&lck_pd->resource_cleanup_list); */
+                       list_add_tail (&resource_cleanup->list, 
&lck_pd->resource_cleanup_list);
                }
                resource->refcount += 1;
        }
 
-
-       /*
-        * Send error result to LCK library
-        */
 error_exit:
-       /*
-        * If this node was the source of the message, respond to this node
-        */
        if (api->ipc_source_is_local (&req_exec_lck_resourceopen->source)) {
-               /*
-                * If its an async call respond with the invocation and handle
-                */
                if (req_exec_lck_resourceopen->async_call) {
                        res_lib_lck_resourceopenasync.header.size = sizeof 
(struct res_lib_lck_resourceopenasync);
                        res_lib_lck_resourceopenasync.header.id = 
MESSAGE_RES_LCK_RESOURCEOPENASYNC;
@@ -825,9 +1246,6 @@
                                &res_lib_lck_resourceopenasync,
                                sizeof (struct res_lib_lck_resourceopenasync));
                } else {
-                       /*
-                        * otherwise respond with the normal resourceopen 
response
-                        */
                        res_lib_lck_resourceopen.header.size = sizeof (struct 
res_lib_lck_resourceopen);
                        res_lib_lck_resourceopen.header.id = 
MESSAGE_RES_LCK_RESOURCEOPEN;
                        res_lib_lck_resourceopen.header.error = error;
@@ -846,7 +1264,8 @@
        void *message,
        unsigned int nodeid)
 {
-       struct req_exec_lck_resourceclose *req_exec_lck_resourceclose = (struct 
req_exec_lck_resourceclose *)message;
+       struct req_exec_lck_resourceclose *req_exec_lck_resourceclose =
+               (struct req_exec_lck_resourceclose *)message;
        struct res_lib_lck_resourceclose res_lib_lck_resourceclose;
        struct resource *resource = 0;
        SaAisErrorT error = SA_AIS_OK;
@@ -854,14 +1273,19 @@
        log_printf (LOG_LEVEL_NOTICE, "EXEC request: saLckResourceClose %s\n",
                get_mar_name_t (&req_exec_lck_resourceclose->lockResourceName));
 
-       resource = resource_find 
(&req_exec_lck_resourceclose->lockResourceName);
-       if (resource == 0) {
+       resource = lck_resource_find (&resource_list_head,
+               &req_exec_lck_resourceclose->lockResourceName);
+
+       if (resource == NULL) {
                goto error_exit;
        }
 
        resource->refcount -= 1;
+
        if (resource->refcount == 0) {
+               /* TODO */
        }
+
 error_exit:
        if (api->ipc_source_is_local(&req_exec_lck_resourceclose->source)) {
                lck_resource_cleanup_remove (
@@ -871,6 +1295,7 @@
                res_lib_lck_resourceclose.header.size = sizeof (struct 
res_lib_lck_resourceclose);
                res_lib_lck_resourceclose.header.id = 
MESSAGE_RES_LCK_RESOURCECLOSE;
                res_lib_lck_resourceclose.header.error = error;
+
                api->ipc_conn_send_response (
                        req_exec_lck_resourceclose->source.conn,
                        &res_lib_lck_resourceclose, sizeof (struct 
res_lib_lck_resourceclose));
@@ -934,6 +1359,7 @@
                        res_lib_lck_resourcelockasync.lockStatus = 
resource_lock->lock_status;
                        res_lib_lck_resourcelockasync.invocation = 
resource_lock->invocation;
                        res_lib_lck_resourcelockasync.lockId = 
resource_lock->lock_id;
+
                        api->ipc_conn_send_response (
                                api->ipc_conn_partner_get (source->conn),
                                &res_lib_lck_resourcelockasync,
@@ -958,6 +1384,7 @@
                        res_lib_lck_resourcelock.header.error = error;
                        res_lib_lck_resourcelock.resource_lock = (void 
*)resource_lock;
                        res_lib_lck_resourcelock.lockStatus = 
resource_lock->lock_status;
+
                        api->ipc_conn_send_response (source->conn,
                                &res_lib_lck_resourcelock,
                                sizeof (struct res_lib_lck_resourcelock));
@@ -1036,8 +1463,8 @@
                        /*
                         * grant all pr pending locks to pr granted list
                         */
-                       list_add (&resource_lock->list,
-                               &resource->pr_granted_list_head);
+                       /* list_add (&resource_lock->list, 
&resource->pr_granted_list_head); */
+                       list_add_tail (&resource_lock->list, 
&resource->pr_granted_list_head);
                        resource_lock->lock_status = SA_LCK_LOCK_GRANTED;
                }
        }
@@ -1127,8 +1554,7 @@
                        list_p = resource->pr_pending_list_head.next;
                        list_del (&resource->pr_pending_list_head);
                        list_init (&resource->pr_pending_list_head);
-                       list_add_tail (list_p,
-                               &resource->pr_granted_list_head);
+                       list_add_tail (list_p, &resource->pr_granted_list_head);
                }
        }
 }
@@ -1137,7 +1563,8 @@
        void *message,
        unsigned int nodeid)
 {
-       struct req_exec_lck_resourcelock *req_exec_lck_resourcelock = (struct 
req_exec_lck_resourcelock *)message;
+       struct req_exec_lck_resourcelock *req_exec_lck_resourcelock =
+               (struct req_exec_lck_resourcelock *)message;
        struct resource *resource = 0;
        struct resource_lock *resource_lock = 0;
        struct resource_cleanup *resource_cleanup = 0;
@@ -1145,30 +1572,29 @@
        log_printf (LOG_LEVEL_NOTICE, "EXEC request: saLckResourceLock %s\n",
                get_mar_name_t 
(&req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockResourceName));
 
-       resource = resource_find 
(&req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockResourceName);
-       if (resource == 0) {
+       resource = lck_resource_find (&resource_list_head,
+               
&req_exec_lck_resourcelock->req_lib_lck_resourcelock.lockResourceName);
+
+       if (resource == NULL) {
                goto error_exit;
        }
        resource->refcount += 1;
 
        resource_lock = malloc (sizeof (struct resource_lock));
-       if (resource_lock == 0) {
+       if (resource_lock == NULL) {
                lock_response_deliver (&req_exec_lck_resourcelock->source,
                        resource_lock,
                        SA_AIS_ERR_NO_MEMORY);
                goto error_exit;
        }
 
-       /*
-        * Build resource lock structure
-        */
        memset (resource_lock, 0, sizeof (struct resource_lock));
 
        list_init (&resource_lock->list);
        list_init (&resource_lock->resource_list);
-       list_init (&resource_lock->resource_cleanup_list);
+       /* list_init (&resource_lock->resource_cleanup_list); */
 
-       list_add (&resource_lock->resource_list, 
&resource->resource_lock_list_head);
+       list_add_tail (&resource_lock->resource_list, 
&resource->resource_lock_list_head);
 
        resource_lock->resource = resource;
 
@@ -1187,6 +1613,11 @@
        resource_lock->invocation =
                req_exec_lck_resourcelock->req_lib_lck_resourcelock.invocation;
 
+       /* DEBUG */
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]:\t lock_id=%u addr=%p\n",
+                   (unsigned int)(resource_lock->lock_id),
+                   (void *)(resource_lock));
+
        /*
         * Waiter callback source
         */
@@ -1204,10 +1635,12 @@
                        resource_lock->callback_source.conn,
                        req_exec_lck_resourcelock->resource_handle);
 
-               assert (resource_cleanup);
+               assert (resource_cleanup != NULL);
 
-               list_add (&resource_lock->resource_cleanup_list,
-                       &resource_cleanup->resource_lock_list_head);
+               /* list_add (&resource_lock->resource_cleanup_list,
+                  &resource_cleanup->resource_lock_list_head); */
+               /* list_add_tail (&resource_lock->resource_cleanup_list,
+                  &resource_cleanup->resource_lock_list_head); */
 
                /*
                 * If lock queued by lock algorithm, dont send response to 
library now
@@ -1236,9 +1669,6 @@
                        &req_exec_lck_resourcelock->source,
                        resource_lock,
                        SA_AIS_OK);
-// TODO why is this twice ?
-               req_exec_lck_resourcelock->source.conn =
-                       api->ipc_conn_partner_get 
(req_exec_lck_resourcelock->source.conn);
        }
 
 error_exit:
@@ -1249,7 +1679,8 @@
        void *message,
        unsigned int nodeid)
 {
-       struct req_exec_lck_resourceunlock *req_exec_lck_resourceunlock = 
(struct req_exec_lck_resourceunlock *)message;
+       struct req_exec_lck_resourceunlock *req_exec_lck_resourceunlock =
+               (struct req_exec_lck_resourceunlock *)message;
        struct res_lib_lck_resourceunlock res_lib_lck_resourceunlock;
        struct res_lib_lck_resourceunlockasync res_lib_lck_resourceunlockasync;
        struct resource *resource = NULL;
@@ -1259,18 +1690,23 @@
        log_printf (LOG_LEVEL_NOTICE, "EXEC request: saLckResourceUnlock %s\n",
                get_mar_name_t (&req_exec_lck_resourceunlock->resource_name));
 
-       resource = resource_find (&req_exec_lck_resourceunlock->resource_name);
-       if (resource == 0) {
+       resource = lck_resource_find (&resource_list_head,
+               &req_exec_lck_resourceunlock->resource_name);
+
+       if (resource == NULL) {
                goto error_exit;
-       }
+       }
+
        resource->refcount -= 1;
 
-       resource_lock = resource_lock_find (resource,
+       resource_lock = lck_resource_lock_find (resource,
                &req_exec_lck_resourceunlock->source,
                req_exec_lck_resourceunlock->lock_id);
-       assert (resource_lock);
 
-       list_del (&resource_lock->resource_cleanup_list);
+       assert (resource_lock != NULL);
+
+       /* list_del (&resource_lock->resource_cleanup_list); */
+
        unlock_algorithm (resource, resource_lock);
 
 error_exit:
@@ -1287,6 +1723,7 @@
                                req_exec_lck_resourceunlock->source.conn,
                                &res_lib_lck_resourceunlockasync,
                                sizeof (struct 
res_lib_lck_resourceunlockasync));
+
                        api->ipc_conn_send_response (
                                
api->ipc_conn_partner_get(req_exec_lck_resourceunlock->source.conn),
                                &res_lib_lck_resourceunlockasync,
@@ -1305,25 +1742,29 @@
        void *message,
        unsigned int nodeid)
 {
-       struct req_exec_lck_resourcelockorphan *req_exec_lck_resourcelockorphan 
= (struct req_exec_lck_resourcelockorphan *)message;
+       struct req_exec_lck_resourcelockorphan *req_exec_lck_resourcelockorphan 
=
+               (struct req_exec_lck_resourcelockorphan *)message;
        struct resource *resource = 0;
        struct resource_lock *resource_lock = 0;
 
-       log_printf (LOG_LEVEL_NOTICE, "EXEC request: Orphan resource locks for 
resource %s\n",
+       log_printf (LOG_LEVEL_NOTICE, "EXEC request: orphan locks for resource 
%s\n",
                get_mar_name_t 
(&req_exec_lck_resourcelockorphan->resource_name));
 
-       resource = resource_find 
(&req_exec_lck_resourcelockorphan->resource_name);
-       if (resource == 0) {
-               assert (0);
-       }
+       resource = lck_resource_find (&resource_list_head,
+               &req_exec_lck_resourcelockorphan->resource_name);
+
+       assert (resource != NULL);
+
        resource->refcount -= 1;
 
-       resource_lock = resource_lock_find (resource,
+       resource_lock = lck_resource_lock_find (resource,
                &req_exec_lck_resourcelockorphan->source,
                req_exec_lck_resourcelockorphan->lock_id);
-       assert (resource_lock);
 
-       list_del (&resource_lock->resource_cleanup_list);
+       assert (resource_lock != NULL);
+
+       /* list_del (&resource_lock->resource_cleanup_list); */
+
        unlock_algorithm (resource, resource_lock);
 }
 
@@ -1331,7 +1772,8 @@
        void *msg,
        unsigned int nodeid)
 {
-       struct req_exec_lck_lockpurge *req_exec_lck_lockpurge = (struct 
req_exec_lck_lockpurge *)msg;
+       struct req_exec_lck_lockpurge *req_exec_lck_lockpurge =
+               (struct req_exec_lck_lockpurge *)msg;
        struct res_lib_lck_lockpurge res_lib_lck_lockpurge;
        struct resource *resource = 0;
        SaAisErrorT error = SA_AIS_OK;
@@ -1339,8 +1781,10 @@
        log_printf (LOG_LEVEL_DEBUG, "EXEC request: saLckLockPurge %s\n",
                get_mar_name_t 
(&req_exec_lck_lockpurge->req_lib_lck_lockpurge.lockResourceName));
 
-       resource = resource_find 
(&req_exec_lck_lockpurge->req_lib_lck_lockpurge.lockResourceName);
-       if (resource == 0) {
+       resource = lck_resource_find (&resource_list_head,
+               
&req_exec_lck_lockpurge->req_lib_lck_lockpurge.lockResourceName);
+
+       if (resource == NULL) {
                goto error_exit;
        }
 
@@ -1352,16 +1796,135 @@
                res_lib_lck_lockpurge.header.size = sizeof (struct 
res_lib_lck_lockpurge);
                res_lib_lck_lockpurge.header.id = MESSAGE_RES_LCK_LOCKPURGE;
                res_lib_lck_lockpurge.header.error = error;
+
                api->ipc_conn_send_response 
(req_exec_lck_lockpurge->source.conn,
                        &res_lib_lck_lockpurge, sizeof (struct 
res_lib_lck_lockpurge));
        }
 }
 
+static void message_handler_req_exec_lck_sync_resource (
+       void *msg,
+       unsigned int nodeid)
+{
+       struct req_exec_lck_sync_resource *req_exec_lck_sync_resource =
+               (struct req_exec_lck_sync_resource *)msg;
+       struct resource *resource;
+
+       log_printf (LOG_LEVEL_NOTICE, "EXEC request: sync resource %s\n",
+                   get_mar_name_t 
(&req_exec_lck_sync_resource->resource_name));
+
+       /*
+        * Ignore message from previous ring
+        */
+       if (memcmp (&req_exec_lck_sync_resource->ring_id,
+                   &my_saved_ring_id, sizeof (struct memb_ring_id)) != 0)
+       {
+               return;
+       }
+
+       resource = lck_resource_find (&sync_resource_list_head,
+               &req_exec_lck_sync_resource->resource_name);
+
+       if (resource == NULL) {
+               resource = malloc (sizeof (struct resource));
+               if (resource == NULL) {
+                       api->error_memory_failure ();
+               }
+
+               memset (resource, 0, sizeof (struct resource));
+               memcpy (&resource->name,
+                       &req_exec_lck_sync_resource->resource_name,
+                       sizeof (mar_name_t));
+
+               list_init (&resource->list);
+               list_init (&resource->resource_lock_list_head);
+               /* list_add  (&resource->list, &sync_resource_list_head); */
+               list_add_tail  (&resource->list, &sync_resource_list_head);
+               list_init (&resource->pr_granted_list_head);
+               list_init (&resource->pr_pending_list_head);
+               list_init (&resource->ex_pending_list_head);
+       }
+}
+
+static void message_handler_req_exec_lck_sync_resource_lock (
+       void *msg,
+       unsigned int nodeid)
+{
+       struct req_exec_lck_sync_resource_lock *req_exec_lck_sync_resource_lock 
=
+               (struct req_exec_lck_sync_resource_lock *)msg;
+       struct resource_lock *resource_lock;
+       struct resource *resource;
+
+       log_printf (LOG_LEVEL_NOTICE, "EXEC request: sync resource lock %u\n",
+                   (unsigned int)(req_exec_lck_sync_resource_lock->lock_id));
+
+       /*
+        * Ignore message from previous ring
+        */
+       if (memcmp (&req_exec_lck_sync_resource_lock->ring_id,
+                   &my_saved_ring_id, sizeof (struct memb_ring_id)) != 0)
+       {
+               return;
+       }
+
+       resource = lck_resource_find (&sync_resource_list_head,
+               &req_exec_lck_sync_resource_lock->resource_name);
+
+       assert (resource != NULL);
+
+       /* FIXME: check to make sure the lock doesn't already exist */
+
+       resource_lock = malloc (sizeof (struct resource_lock));
+       if (resource_lock == NULL) {
+               api->error_memory_failure ();
+       }
+       memset (resource_lock, 0, sizeof (struct resource_lock));
+
+       list_init (&resource_lock->list);
+       list_init (&resource_lock->resource_list);
+       /* list_init (&resource_lock->resource_cleanup_list); */
+
+       list_add_tail (&resource_lock->resource_list, 
&resource->resource_lock_list_head);
+
+       resource_lock->lock_id = req_exec_lck_sync_resource_lock->lock_id;
+       resource_lock->lock_mode = req_exec_lck_sync_resource_lock->lock_mode;
+       resource_lock->lock_flags = req_exec_lck_sync_resource_lock->lock_flags;
+       resource_lock->waiter_signal = 
req_exec_lck_sync_resource_lock->waiter_signal;
+       resource_lock->lock_status = 
req_exec_lck_sync_resource_lock->lock_status;
+       resource_lock->timeout = req_exec_lck_sync_resource_lock->timeout;
+
+       /* DEBUG */
+       log_printf (LOG_LEVEL_NOTICE, "[DEBUG]: lock_id=%u lock_mode=%u 
lock_status=%u\n",
+                   (unsigned int)(resource_lock->lock_id),
+                   (unsigned int)(resource_lock->lock_mode),
+                   (unsigned int)(resource_lock->lock_status));
+
+       /*
+        * Determine the list that this lock should be added to
+        */
+       if (resource_lock->lock_mode == SA_LCK_PR_LOCK_MODE) {
+               if (resource_lock->lock_status == SA_LCK_LOCK_GRANTED) {
+                       list_add_tail (&resource_lock->list, 
&resource->pr_granted_list_head);
+               } else {
+                       list_add_tail (&resource_lock->list, 
&resource->pr_pending_list_head);
+               }
+       }
+
+       if (resource_lock->lock_mode == SA_LCK_EX_LOCK_MODE) {
+               if (resource_lock->lock_status == SA_LCK_LOCK_GRANTED) {
+                       resource->ex_granted = resource_lock;
+               } else {
+                       list_add_tail (&resource_lock->list, 
&resource->ex_pending_list_head);
+               }
+       }
+}
+
 static void message_handler_req_lib_lck_resourceopen (
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_resourceopen *req_lib_lck_resourceopen = (struct 
req_lib_lck_resourceopen *)msg;
+       struct req_lib_lck_resourceopen *req_lib_lck_resourceopen
+               = (struct req_lib_lck_resourceopen *)msg;
        struct req_exec_lck_resourceopen req_exec_lck_resourceopen;
        struct iovec iovec;
 
@@ -1395,7 +1958,8 @@
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_resourceopen *req_lib_lck_resourceopen = (struct 
req_lib_lck_resourceopen *)msg;
+       struct req_lib_lck_resourceopen *req_lib_lck_resourceopen
+               = (struct req_lib_lck_resourceopen *)msg;
        struct req_exec_lck_resourceopen req_exec_lck_resourceopen;
        struct iovec iovec;
 
@@ -1430,7 +1994,8 @@
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_resourceclose *req_lib_lck_resourceclose = (struct 
req_lib_lck_resourceclose *)msg;
+       struct req_lib_lck_resourceclose *req_lib_lck_resourceclose
+               = (struct req_lib_lck_resourceclose *)msg;
        struct req_exec_lck_resourceclose req_exec_lck_resourceclose;
        struct iovec iovecs[2];
        struct resource *resource;
@@ -1439,8 +2004,10 @@
        log_printf (LOG_LEVEL_NOTICE, "LIB request: saLckResourceClose %s\n",
                get_mar_name_t (&req_lib_lck_resourceclose->lockResourceName));
 
-       resource = resource_find (&req_lib_lck_resourceclose->lockResourceName);
-       if (resource) {
+       resource = lck_resource_find (&resource_list_head,
+               &req_lib_lck_resourceclose->lockResourceName);
+
+       if (resource != NULL) {
                req_exec_lck_resourceclose.header.size =
                        sizeof (struct req_exec_lck_resourceclose);
                req_exec_lck_resourceclose.header.id =
@@ -1460,8 +2027,6 @@
                }
        }
        else {
-               log_printf (LOG_LEVEL_ERROR, "#### LCK: Could Not Find the 
Checkpoint to close so Returning Error. ####\n");
-
                res_lib_lck_resourceclose.header.size = sizeof (struct 
res_lib_lck_resourceclose);
                res_lib_lck_resourceclose.header.id = 
MESSAGE_RES_LCK_RESOURCECLOSE;
                res_lib_lck_resourceclose.header.error = SA_AIS_ERR_NOT_EXIST;
@@ -1476,7 +2041,8 @@
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_resourcelock *req_lib_lck_resourcelock = (struct 
req_lib_lck_resourcelock *)msg;
+       struct req_lib_lck_resourcelock *req_lib_lck_resourcelock
+               = (struct req_lib_lck_resourcelock *)msg;
        struct req_exec_lck_resourcelock req_exec_lck_resourcelock;
        struct iovec iovecs[2];
 
@@ -1509,7 +2075,8 @@
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_resourcelock *req_lib_lck_resourcelock = (struct 
req_lib_lck_resourcelock *)msg;
+       struct req_lib_lck_resourcelock *req_lib_lck_resourcelock
+               = (struct req_lib_lck_resourcelock *)msg;
        struct req_exec_lck_resourcelock req_exec_lck_resourcelock;
        struct iovec iovecs[2];
 
@@ -1542,7 +2109,8 @@
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_resourceunlock *req_lib_lck_resourceunlock = (struct 
req_lib_lck_resourceunlock *)msg;
+       struct req_lib_lck_resourceunlock *req_lib_lck_resourceunlock
+               = (struct req_lib_lck_resourceunlock *)msg;
        struct req_exec_lck_resourceunlock req_exec_lck_resourceunlock;
        struct iovec iovec;
 
@@ -1574,7 +2142,8 @@
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_resourceunlock *req_lib_lck_resourceunlock = (struct 
req_lib_lck_resourceunlock *)msg;
+       struct req_lib_lck_resourceunlock *req_lib_lck_resourceunlock
+               = (struct req_lib_lck_resourceunlock *)msg;
        struct req_exec_lck_resourceunlock req_exec_lck_resourceunlock;
        struct iovec iovec;
 
@@ -1606,7 +2175,8 @@
        void *conn,
        void *msg)
 {
-       struct req_lib_lck_lockpurge *req_lib_lck_lockpurge = (struct 
req_lib_lck_lockpurge *)msg;
+       struct req_lib_lck_lockpurge *req_lib_lck_lockpurge
+               = (struct req_lib_lck_lockpurge *)msg;
        struct req_exec_lck_lockpurge req_exec_lck_lockpurge;
        struct iovec iovecs[2];
 
@@ -1629,4 +2199,3 @@
 
        assert (api->totem_mcast (iovecs, 1, TOTEM_AGREED) == 0);
 }
-
Index: services/msg.c
===================================================================
--- services/msg.c      (revision 1683)
+++ services/msg.c      (working copy)
@@ -317,8 +317,8 @@
        void *msg);
 
 static void msg_sync_init (void);
+static int  msg_sync_process (void);
 static void msg_sync_activate (void);
-static int  msg_sync_process (void);
 static void msg_sync_abort(void);
 
 void queue_entry_release (struct message_entry *entry);
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to