Просмотр исходного кода

defect 796
fix saClmClusterTrack to operate according to specs.


git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@786 fd59a12c-fef9-0310-b244-a6a79926bd2f

Steven Dake 20 лет назад
Родитель
Сommit
d1d04c7806
4 измененных файлов с 176 добавлено и 183 удалено
  1. 57 75
      exec/clm.c
  2. 9 12
      include/ipc_clm.h
  3. 104 95
      lib/clm.c
  4. 6 1
      test/testclm.c

+ 57 - 75
exec/clm.c

@@ -121,16 +121,16 @@ static int clm_exit_fn (struct conn_info *conn_info);
 static int message_handler_req_exec_clm_nodejoin (void *message, struct in_addr source_addr,
 	int endian_conversion_required);
 
-static int message_handler_req_clm_clustertrack (struct conn_info *conn_info,
+static int message_handler_req_lib_clm_clustertrack (struct conn_info *conn_info,
 	void *message);
 
 static int message_handler_req_lib_clm_trackstop (struct conn_info *conn_info,
 	void *message);
 
-static int message_handler_req_clm_nodeget (struct conn_info *conn_info,
+static int message_handler_req_lib_clm_nodeget (struct conn_info *conn_info,
 	void *message);
 
-static int message_handler_req_clm_nodegetasync (struct conn_info *conn_info,
+static int message_handler_req_lib_clm_nodegetasync (struct conn_info *conn_info,
 	void *message);
 
 static int clm_exit_fn (struct conn_info *conn_info);
@@ -141,8 +141,8 @@ static int clm_exit_fn (struct conn_info *conn_info);
 struct libais_handler clm_libais_handlers[] =
 {
 	{ /* 0 */
-		.libais_handler_fn			= message_handler_req_clm_clustertrack,
-		.response_size				= sizeof (struct res_clm_clustertrack),
+		.libais_handler_fn			= message_handler_req_lib_clm_clustertrack,
+		.response_size				= sizeof (struct res_lib_clm_clustertrack),
 		.response_id				= MESSAGE_RES_CLM_TRACKSTART, // TODO RESPONSE
 		.flow_control				= FLOW_CONTROL_NOT_REQUIRED
 	},
@@ -153,13 +153,13 @@ struct libais_handler clm_libais_handlers[] =
 		.flow_control				= FLOW_CONTROL_NOT_REQUIRED
 	},
 	{ /* 2 */
-		.libais_handler_fn			= message_handler_req_clm_nodeget,
+		.libais_handler_fn			= message_handler_req_lib_clm_nodeget,
 		.response_size				= sizeof (struct res_clm_nodeget),
 		.response_id				= MESSAGE_RES_CLM_NODEGET, // TODO RESPONSE
 		.flow_control				= FLOW_CONTROL_NOT_REQUIRED
 	},
 	{ /* 3 */
-		.libais_handler_fn			= message_handler_req_clm_nodegetasync,
+		.libais_handler_fn			= message_handler_req_lib_clm_nodegetasync,
 		.response_size				= sizeof (struct res_clm_nodegetasync),
 		.response_id				= MESSAGE_RES_CLM_NODEGETCALLBACK, // TODO RESPONSE
 		.flow_control				= FLOW_CONTROL_NOT_REQUIRED
@@ -234,49 +234,10 @@ static int clm_exit_fn (struct conn_info *conn_info)
 	return (0);
 }
 
-static void libraryNotificationCurrentState (struct conn_info *conn_info)
-{
-	struct res_clm_trackcallback res_clm_trackcallback;
-	SaClmClusterNotificationT clusterNotification[NODE_MAX];
-	int i;
-
-	if ((conn_info->ais_ci.u.libclm_ci.trackFlags & SA_TRACK_CURRENT) == 0) {
-		return;
-	}
-	/*
-	 * Turn off track current
-	 */
-	conn_info->ais_ci.u.libclm_ci.trackFlags &= ~SA_TRACK_CURRENT;
-
-	/*
-	 * Build notification list
-	 */
-	for (i = 0; i < clusterNodeEntries; i++) {
-		clusterNotification[i].clusterChange = SA_CLM_NODE_NO_CHANGE;
-
-		memcpy (&clusterNotification[i].clusterNode, &clusterNodes[i],
-			sizeof (SaClmClusterNodeT));
-	}
-
-	/*
-	 * Send track response
-	 */
-	res_clm_trackcallback.header.size = sizeof (struct res_clm_trackcallback) +
-		sizeof (SaClmClusterNotificationT) * i;
-	res_clm_trackcallback.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
-	res_clm_trackcallback.header.error = SA_OK;
-	res_clm_trackcallback.viewNumber = 0;
-	res_clm_trackcallback.numberOfItems = i;
-	res_clm_trackcallback.numberOfMembers = i;
-	libais_send_response (conn_info, &res_clm_trackcallback, sizeof (struct res_clm_trackcallback));
-	libais_send_response (conn_info, clusterNotification, sizeof (SaClmClusterNotificationT) * i);
-}
-
-
 void library_notification_send (SaClmClusterNotificationT *cluster_notification_entries,
 	int notify_entries)
 {
-	struct res_clm_trackcallback res_clm_trackcallback;
+	struct res_lib_clm_clustertrack res_lib_clm_clustertrack;
 	struct conn_info *conn_info;
 	struct list_head *list;
 
@@ -290,15 +251,14 @@ void library_notification_send (SaClmClusterNotificationT *cluster_notification_
 		 * Send notifications to all CLM listeners
 		 */
 		if (notify_entries) {
-			res_clm_trackcallback.header.size = sizeof (struct res_clm_trackcallback) +
+			res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack) +
 				(notify_entries * sizeof (SaClmClusterNotificationT));
-			res_clm_trackcallback.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
-			res_clm_trackcallback.header.error = SA_OK;
-			res_clm_trackcallback.viewNumber = 0;
-			res_clm_trackcallback.numberOfItems = notify_entries;
-			res_clm_trackcallback.numberOfMembers = notify_entries;
-			libais_send_response (conn_info, &res_clm_trackcallback,
-				sizeof (struct res_clm_trackcallback));
+			res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
+			res_lib_clm_clustertrack.header.error = SA_OK;
+			res_lib_clm_clustertrack.viewNumber = 0;
+			res_lib_clm_clustertrack.numberOfItems = notify_entries;
+			libais_send_response (conn_info, &res_lib_clm_clustertrack,
+				sizeof (struct res_lib_clm_clustertrack));
 			libais_send_response (conn_info, cluster_notification_entries,
 				sizeof (SaClmClusterNotificationT) * notify_entries);
         }
@@ -452,7 +412,6 @@ static int clm_sync_process (void)
 	 * Send node information to other nodes
 	 */
 	return (clm_nodejoin_send ());
-	return (0);
 }
 
 /*
@@ -535,20 +494,44 @@ static int clm_init_two_fn (struct conn_info *conn_info)
 	return (0);
 }
 
-int message_handler_req_clm_clustertrack (struct conn_info *conn_info, void *message)
+int message_handler_req_lib_clm_clustertrack (struct conn_info *conn_info, void *message)
 {
-	struct req_clm_clustertrack *req_clm_clustertrack = (struct req_clm_clustertrack *)message;
+	struct req_lib_clm_clustertrack *req_lib_clm_clustertrack = (struct req_lib_clm_clustertrack *)message;
+	struct res_lib_clm_clustertrack res_lib_clm_clustertrack;
+	int i;
 
+	conn_info->conn_info_partner->ais_ci.u.libclm_ci.trackFlags = req_lib_clm_clustertrack->trackFlags;
 
-	conn_info->conn_info_partner->ais_ci.u.libclm_ci.trackFlags = req_clm_clustertrack->trackFlags;
-	if (req_clm_clustertrack->trackFlags != SA_TRACK_CURRENT) {
+	list_add (&conn_info->conn_info_partner->conn_list, &library_notification_send_listhead);
+
+	res_lib_clm_clustertrack.header.size = sizeof (struct res_lib_clm_clustertrack);
+	res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKSTART;
+	res_lib_clm_clustertrack.header.error = SA_AIS_OK;
+	res_lib_clm_clustertrack.viewNumber = 0;
+		res_lib_clm_clustertrack.numberOfItems = 0;
+
+	if (req_lib_clm_clustertrack->trackFlags & SA_TRACK_CURRENT) {
+		for (i = 0; i < clusterNodeEntries; i++) {
+			res_lib_clm_clustertrack.notification[i].clusterChange = SA_CLM_NODE_NO_CHANGE;
+
+			memcpy (&res_lib_clm_clustertrack.notification[i].clusterNode,
+				&clusterNodes[i], sizeof (SaClmClusterNodeT));
+		}
+		res_lib_clm_clustertrack.numberOfItems = clusterNodeEntries;
+	} else {
 		conn_info->conn_info_partner->ais_ci.u.libclm_ci.tracking_enabled = 1;
 	}
 
-	list_add (&conn_info->conn_info_partner->conn_list, &library_notification_send_listhead);
+	libais_send_response (conn_info, &res_lib_clm_clustertrack,
+		sizeof (struct res_lib_clm_clustertrack));
 
-	libraryNotificationCurrentState (conn_info->conn_info_partner);
+	if (req_lib_clm_clustertrack->return_in_callback) {
+		res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK;
 
+		libais_send_response (conn_info->conn_info_partner,
+			&res_lib_clm_clustertrack,
+			sizeof (struct res_lib_clm_clustertrack));
+	}
 	return (0);
 }
 
@@ -577,22 +560,22 @@ static int message_handler_req_lib_clm_trackstop (struct conn_info *conn_info, v
 	return (0);
 }
 
-static int message_handler_req_clm_nodeget (struct conn_info *conn_info, void *message)
+static int message_handler_req_lib_clm_nodeget (struct conn_info *conn_info, void *message)
 {
-	struct req_clm_nodeget *req_clm_nodeget = (struct req_clm_nodeget *)message;
+	struct req_lib_clm_nodeget *req_lib_clm_nodeget = (struct req_lib_clm_nodeget *)message;
 	struct res_clm_nodeget res_clm_nodeget;
 	SaClmClusterNodeT *clusterNode = 0;
 	int valid = 0;
 	int i;
 
-	log_printf (LOG_LEVEL_DEBUG, "nodeget: trying to find node %x\n", (int)req_clm_nodeget->nodeId);
+	log_printf (LOG_LEVEL_NOTICE, "nodeget: trying to find node %x\n", (int)req_lib_clm_nodeget->nodeId);
 
-	if (req_clm_nodeget->nodeId == SA_CLM_LOCAL_NODE_ID) {
+	if (req_lib_clm_nodeget->nodeId == SA_CLM_LOCAL_NODE_ID) {
 		clusterNode = &clusterNodes[0];
 		valid = 1;
 	} else 
 	for (i = 0; i < clusterNodeEntries; i++) {
-		if (clusterNodes[i].nodeId == req_clm_nodeget->nodeId) {
+		if (clusterNodes[i].nodeId == req_lib_clm_nodeget->nodeId) {
 			log_printf (LOG_LEVEL_DEBUG, "found host that matches one desired in nodeget.\n");
 			clusterNode = &clusterNodes[i];
 			valid = 1;
@@ -603,9 +586,8 @@ static int message_handler_req_clm_nodeget (struct conn_info *conn_info, void *m
 	res_clm_nodeget.header.size = sizeof (struct res_clm_nodeget);
 	res_clm_nodeget.header.id = MESSAGE_RES_CLM_NODEGET;
 	res_clm_nodeget.header.error = SA_OK;
-	res_clm_nodeget.invocation = req_clm_nodeget->invocation;
+	res_clm_nodeget.invocation = req_lib_clm_nodeget->invocation;
 	res_clm_nodeget.valid = valid;
-	printf ("valid is %d\n", res_clm_nodeget.valid);
 	if (valid) {
 		memcpy (&res_clm_nodeget.clusterNode, clusterNode, sizeof (SaClmClusterNodeT));
 	}
@@ -614,23 +596,23 @@ static int message_handler_req_clm_nodeget (struct conn_info *conn_info, void *m
 	return (0);
 }
 
-static int message_handler_req_clm_nodegetasync (struct conn_info *conn_info, void *message)
+static int message_handler_req_lib_clm_nodegetasync (struct conn_info *conn_info, void *message)
 {
-	struct req_clm_nodegetasync *req_clm_nodegetasync = (struct req_clm_nodegetasync *)message;
+	struct req_lib_clm_nodegetasync *req_lib_clm_nodegetasync = (struct req_lib_clm_nodegetasync *)message;
 	struct res_clm_nodegetasync res_clm_nodegetasync;
 	struct res_clm_nodegetcallback res_clm_nodegetcallback;
 	SaClmClusterNodeT *clusterNode = 0;
 	int error = SA_AIS_ERR_INVALID_PARAM;
 	int i;
 
-	log_printf (LOG_LEVEL_DEBUG, "nodeget: trying to find node %x\n", (int)req_clm_nodegetasync->nodeId);
+	log_printf (LOG_LEVEL_DEBUG, "nodeget: trying to find node %x\n", (int)req_lib_clm_nodegetasync->nodeId);
 
-	if (req_clm_nodegetasync->nodeId == SA_CLM_LOCAL_NODE_ID) {
+	if (req_lib_clm_nodegetasync->nodeId == SA_CLM_LOCAL_NODE_ID) {
 		clusterNode = &clusterNodes[0];
 		error = SA_AIS_OK;
 	} else 
 	for (i = 0; i < clusterNodeEntries; i++) {
-		if (clusterNodes[i].nodeId == req_clm_nodegetasync->nodeId) {
+		if (clusterNodes[i].nodeId == req_lib_clm_nodegetasync->nodeId) {
 			log_printf (LOG_LEVEL_DEBUG, "found host that matches one desired in nodeget.\n");
 			clusterNode = &clusterNodes[i];
 			error = SA_AIS_OK;
@@ -653,7 +635,7 @@ static int message_handler_req_clm_nodegetasync (struct conn_info *conn_info, vo
 	res_clm_nodegetcallback.header.size = sizeof (struct res_clm_nodegetcallback);
 	res_clm_nodegetcallback.header.id = MESSAGE_RES_CLM_NODEGETCALLBACK;
 	res_clm_nodegetcallback.header.error = error;
-	res_clm_nodegetcallback.invocation = req_clm_nodegetasync->invocation;
+	res_clm_nodegetcallback.invocation = req_lib_clm_nodegetasync->invocation;
 	if (error == SA_AIS_OK) {
 		memcpy (&res_clm_nodegetcallback.clusterNode, clusterNode,
 			sizeof (SaClmClusterNodeT));

+ 9 - 12
include/ipc_clm.h

@@ -55,14 +55,19 @@ enum res_clm_types {
 	MESSAGE_RES_CLM_NODEGETCALLBACK = 5
 };
 
-struct req_clm_clustertrack {
+struct req_lib_clm_clustertrack {
 	struct req_header header;
 	SaUint8T trackFlags;
+	int return_in_callback;
 };
 
-struct res_clm_clustertrack {
+struct res_lib_clm_clustertrack {
 	struct res_header header;
+	SaUint64T viewNumber;
+	SaUint32T numberOfItems;
+	SaClmClusterNotificationT notification[32]; /* should be PROCESSOR_COUNT_MAX */
 };
+
 struct req_lib_clm_trackstop {
 	struct req_header header;
 	SaSizeT dataRead;
@@ -73,15 +78,7 @@ struct res_lib_clm_trackstop {
 	struct res_header header;
 };
 
-struct res_clm_trackcallback {
-	struct res_header header;
-	SaUint64T viewNumber;
-	SaUint32T numberOfItems;
-	SaUint32T numberOfMembers;
-	SaClmClusterNotificationT notification[0];
-};
-
-struct req_clm_nodeget {
+struct req_lib_clm_nodeget {
 	struct req_header header;
 	SaInvocationT invocation;
 	SaClmNodeIdT nodeId;
@@ -94,7 +91,7 @@ struct res_clm_nodeget {
 	int valid;
 };
 
-struct req_clm_nodegetasync {
+struct req_lib_clm_nodegetasync {
 	struct req_header header;
 	SaInvocationT invocation;
 	SaClmNodeIdT nodeId;

+ 104 - 95
lib/clm.c

@@ -61,7 +61,6 @@ struct clmInstance {
 	int dispatch_fd;
 	SaClmCallbacksT callbacks;
 	int finalize;
-	SaClmClusterNotificationBufferT notificationBuffer;
 	pthread_mutex_t response_mutex;
 	pthread_mutex_t dispatch_mutex;
 };
@@ -99,7 +98,7 @@ saClmInitialize (
 	SaVersionT *version)
 {
 	struct clmInstance *clmInstance;
-	SaAisErrorT error = SA_OK;
+	SaAisErrorT error = SA_AIS_OK;
 
 
 	if (clmHandle == NULL) {
@@ -110,19 +109,19 @@ saClmInitialize (
 	}
 
 	error = saVersionVerify (&clmVersionDatabase, version);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		goto error_no_destroy;
 	}
 
 	error = saHandleCreate (&clmHandleDatabase, sizeof (struct clmInstance),
 		clmHandle);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		goto error_no_destroy;
 	}
 
 	error = saHandleInstanceGet (&clmHandleDatabase, *clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		goto error_destroy;
 	}
 
@@ -132,7 +131,7 @@ saClmInitialize (
 
 	error = saServiceConnectTwo (&clmInstance->response_fd,
 		&clmInstance->dispatch_fd, CLM_SERVICE);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		goto error_put_destroy;
 	}
 
@@ -146,11 +145,9 @@ saClmInitialize (
 
 	pthread_mutex_init (&clmInstance->dispatch_mutex, NULL);
 
-	clmInstance->notificationBuffer.notification = 0;
-
 	saHandleInstancePut (&clmHandleDatabase, *clmHandle);
 
-	return (SA_OK);
+	return (SA_AIS_OK);
 
 error_put_destroy:
 	saHandleInstancePut (&clmHandleDatabase, *clmHandle);
@@ -173,14 +170,14 @@ saClmSelectionObjectGet (
 	}
 	error = saHandleInstanceGet (&clmHandleDatabase, clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		return (error);
 	}
 
 	*selectionObject = clmInstance->dispatch_fd;
 
 	saHandleInstancePut (&clmHandleDatabase, clmHandle);
-	return (SA_OK);
+	return (SA_AIS_OK);
 }
 
 SaAisErrorT
@@ -194,12 +191,13 @@ saClmDispatch (
 	int cont = 1; /* always continue do loop except when set to 0 */
 	int dispatch_avail;
 	struct clmInstance *clmInstance;
-	struct res_clm_trackcallback *res_clm_trackcallback;
+	struct res_lib_clm_clustertrack *res_lib_clm_clustertrack;
 	struct res_clm_nodegetcallback *res_clm_nodegetcallback;
 	SaClmCallbacksT callbacks;
 	struct res_overlay dispatch_data;
 	SaClmClusterNotificationBufferT notificationBuffer;
-	int copy_items;
+	SaClmClusterNotificationT notification[32];
+	int items_to_copy;
 
 	if (dispatchFlags != SA_DISPATCH_ONE &&
 		dispatchFlags != SA_DISPATCH_ALL &&
@@ -210,7 +208,7 @@ saClmDispatch (
 
 	error = saHandleInstanceGet (&clmHandleDatabase, clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		return (error);
 	}
 
@@ -230,7 +228,7 @@ saClmDispatch (
 		pthread_mutex_lock (&clmInstance->dispatch_mutex);
 
 		error = saPollRetry (&ufds, 1, timeout);
-		if (error != SA_OK) {
+		if (error != SA_AIS_OK) {
 			goto error_unlock;
 		}
 
@@ -238,7 +236,7 @@ saClmDispatch (
 		 * Handle has been finalized in another thread
 		 */
 		if (clmInstance->finalize == 1) {
-			error = SA_OK;
+			error = SA_AIS_OK;
 			goto error_unlock;
 		}
 
@@ -255,14 +253,14 @@ saClmDispatch (
 		if (ufds.revents & POLLIN) {
 			error = saRecvRetry (clmInstance->dispatch_fd, &dispatch_data.header,
 				sizeof (struct res_header), MSG_WAITALL | MSG_NOSIGNAL);
-			if (error != SA_OK) {
+			if (error != SA_AIS_OK) {
 				goto error_unlock;
 			}
 			if (dispatch_data.header.size > sizeof (struct res_header)) {
 				error = saRecvRetry (clmInstance->dispatch_fd, &dispatch_data.data,
 					dispatch_data.header.size - sizeof (struct res_header),
 					MSG_WAITALL | MSG_NOSIGNAL);
-				if (error != SA_OK) {
+				if (error != SA_AIS_OK) {
 					goto error_unlock;
 				}
 			}
@@ -277,9 +275,6 @@ saClmDispatch (
 		 * operate at the same time that clmFinalize has been called in another thread.
 		 */
 		memcpy (&callbacks, &clmInstance->callbacks, sizeof (SaClmCallbacksT));
-		memcpy (&notificationBuffer, &clmInstance->notificationBuffer,
-			sizeof (SaClmClusterNotificationBufferT));
-
 		pthread_mutex_unlock (&clmInstance->dispatch_mutex);
 
 		/*
@@ -291,38 +286,26 @@ saClmDispatch (
 			if (callbacks.saClmClusterTrackCallback == NULL) {
 				continue;
 			}
-			res_clm_trackcallback = (struct res_clm_trackcallback *)&dispatch_data;
+			res_lib_clm_clustertrack = (struct res_lib_clm_clustertrack *)&dispatch_data;
 			error = SA_AIS_OK;
 
-			/*
-			 * If buffer is not specified, allocate one
-			 */
-			if (notificationBuffer.notification == 0) {
-				notificationBuffer.notification = malloc (
-					res_clm_trackcallback->numberOfItems *
-					sizeof (SaClmClusterNotificationT));
-				if (notificationBuffer.notification) {
-					notificationBuffer.numberOfItems =
-						res_clm_trackcallback->numberOfItems;
-				} else {
-					error = SA_AIS_ERR_NO_MEMORY;
-				}
-			}
+			notificationBuffer.notification = notification;
+			notificationBuffer.numberOfItems =
+				res_lib_clm_clustertrack->numberOfItems;
 
-			copy_items = res_clm_trackcallback->numberOfItems;
-			if (copy_items > notificationBuffer.numberOfItems) {
-				copy_items = notificationBuffer.numberOfItems;
-				error = SA_AIS_ERR_NO_SPACE;
-			}
+			items_to_copy = notificationBuffer.numberOfItems
+				< res_lib_clm_clustertrack->numberOfItems ?
+				notificationBuffer.numberOfItems :
+				res_lib_clm_clustertrack->numberOfItems;
 
 			memcpy (notificationBuffer.notification, 
-				&res_clm_trackcallback->notification,
-				copy_items *
-					sizeof (SaClmClusterNotificationT));
+				&res_lib_clm_clustertrack->notification,
+				items_to_copy * sizeof (SaClmClusterNotificationT));
 
 			callbacks.saClmClusterTrackCallback (
 				(const SaClmClusterNotificationBufferT *)&notificationBuffer,
-				res_clm_trackcallback->numberOfMembers, error);
+				res_lib_clm_clustertrack->numberOfItems, error);
+
 			break;
 
 		case MESSAGE_RES_CLM_NODEGETCALLBACK:
@@ -376,7 +359,7 @@ saClmFinalize (
 
 	error = saHandleInstanceGet (&clmHandleDatabase, clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		return (error);
 	}
 
@@ -417,51 +400,79 @@ saClmClusterTrack (
 	SaUint8T trackFlags,
 	SaClmClusterNotificationBufferT *notificationBuffer)
 {
-	struct req_clm_clustertrack req_clustertrack;
+	struct req_lib_clm_clustertrack req_lib_clm_clustertrack;
+	struct res_lib_clm_clustertrack res_lib_clm_clustertrack;
 	struct clmInstance *clmInstance;
-	SaAisErrorT error = SA_OK;
+	SaAisErrorT error = SA_AIS_OK;
+	int items_to_copy;
 
-	/*
-	 * Parameter checking
-	 */
-	if (notificationBuffer == 0) {
-		return (SA_AIS_ERR_INVALID_PARAM);
+	if ((trackFlags & SA_TRACK_CHANGES) && (trackFlags & SA_TRACK_CHANGES_ONLY)) {
+		return (SA_AIS_ERR_BAD_FLAGS);
+	}
+
+	if (trackFlags & ~(SA_TRACK_CURRENT | SA_TRACK_CHANGES | SA_TRACK_CHANGES_ONLY)) {
+		return (SA_AIS_ERR_BAD_FLAGS);
 	}
 
-	if (notificationBuffer->notification &&
-		notificationBuffer->numberOfItems == 0) {
+	if ((notificationBuffer != NULL) &&
+		(notificationBuffer->notification != NULL) &&
+		(notificationBuffer->numberOfItems == 0)) {
 
 		return (SA_AIS_ERR_INVALID_PARAM);
 	}
-	if ((trackFlags & SA_TRACK_CHANGES) && (trackFlags & SA_TRACK_CHANGES_ONLY)) {
-		return (SA_AIS_ERR_BAD_FLAGS);
-	}
 		
-	/*
-	 * Request service
-	 */
-	req_clustertrack.header.size = sizeof (struct req_clm_clustertrack);
-	req_clustertrack.header.id = MESSAGE_REQ_CLM_TRACKSTART;
-	req_clustertrack.trackFlags = trackFlags;
-
 	error = saHandleInstanceGet (&clmHandleDatabase, clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		return (error);
 	}
 
+	req_lib_clm_clustertrack.header.size = sizeof (struct req_lib_clm_clustertrack);
+	req_lib_clm_clustertrack.header.id = MESSAGE_REQ_CLM_TRACKSTART;
+	req_lib_clm_clustertrack.trackFlags = trackFlags;
+	req_lib_clm_clustertrack.return_in_callback = 0;
+	if ((trackFlags & SA_TRACK_CURRENT) && (notificationBuffer == NULL)) {
+		req_lib_clm_clustertrack.return_in_callback = 1;
+	}
+
 	pthread_mutex_lock (&clmInstance->response_mutex);
 
-	if (clmInstance->callbacks.saClmClusterTrackCallback == 0) {
+	if ((clmInstance->callbacks.saClmClusterTrackCallback == 0) &&
+		((notificationBuffer == NULL) ||
+		(trackFlags & (SA_TRACK_CHANGES | SA_TRACK_CHANGES_ONLY)))) {
+
 		error = SA_AIS_ERR_INIT;
 		goto error_exit;
 	}
 
-	error = saSendRetry (clmInstance->response_fd, &req_clustertrack,
-		sizeof (struct req_clm_clustertrack), MSG_NOSIGNAL);
+	error = saSendReceiveReply (clmInstance->response_fd,
+		&req_lib_clm_clustertrack,
+		sizeof (struct req_lib_clm_clustertrack),
+		&res_lib_clm_clustertrack,
+		sizeof (struct res_lib_clm_clustertrack));
+
+	if ((trackFlags & SA_TRACK_CURRENT) && (notificationBuffer != NULL)) {
+		if (notificationBuffer->notification == 0) {
+			notificationBuffer->notification =
+				malloc (res_lib_clm_clustertrack.numberOfItems *
+				sizeof (SaClmClusterNotificationT));
+
+			notificationBuffer->numberOfItems =
+				res_lib_clm_clustertrack.numberOfItems;
+		}
+
+		items_to_copy = notificationBuffer->numberOfItems <
+			res_lib_clm_clustertrack.numberOfItems ?
+			notificationBuffer->numberOfItems :
+			res_lib_clm_clustertrack.numberOfItems;
 
-	memcpy (&clmInstance->notificationBuffer, notificationBuffer,
-		sizeof (SaClmClusterNotificationBufferT));
+		memcpy (notificationBuffer->notification,
+			res_lib_clm_clustertrack.notification,
+			items_to_copy * sizeof (SaClmClusterNotificationT));
+
+		notificationBuffer->viewNumber = res_lib_clm_clustertrack.viewNumber;
+		notificationBuffer->numberOfItems = items_to_copy;
+	}
 
 // TODO get response packet with saRecvRetry, but need to implement that 
 // in executive service
@@ -470,7 +481,7 @@ error_exit:
 
 	saHandleInstancePut (&clmHandleDatabase, clmHandle);
 
-	return (error);
+        return (error == SA_AIS_OK ? res_lib_clm_clustertrack.header.error : error);
 }
 
 SaAisErrorT
@@ -480,14 +491,14 @@ saClmClusterTrackStop (
 	struct clmInstance *clmInstance;
 	struct req_lib_clm_trackstop req_lib_clm_trackstop;
 	struct res_lib_clm_trackstop res_lib_clm_trackstop;
-	SaAisErrorT error = SA_OK;
+	SaAisErrorT error = SA_AIS_OK;
 
 	req_lib_clm_trackstop.header.size = sizeof (struct req_lib_clm_trackstop);
 	req_lib_clm_trackstop.header.id = MESSAGE_REQ_CLM_TRACKSTOP;
 
 	error = saHandleInstanceGet (&clmHandleDatabase, clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		return (error);
 	}
 
@@ -501,8 +512,6 @@ saClmClusterTrackStop (
 
 	pthread_mutex_unlock (&clmInstance->response_mutex);
 
-	clmInstance->notificationBuffer.notification = 0;
-
 	saHandleInstancePut (&clmHandleDatabase, clmHandle);
 
         return (error == SA_AIS_OK ? res_lib_clm_trackstop.header.error : error);
@@ -516,9 +525,9 @@ saClmClusterNodeGet (
 	SaClmClusterNodeT *clusterNode)
 {
 	struct clmInstance *clmInstance;
-	struct req_clm_nodeget req_clm_nodeget;
+	struct req_lib_clm_nodeget req_lib_clm_nodeget;
 	struct res_clm_nodeget res_clm_nodeget;
-	SaAisErrorT error = SA_OK;
+	SaAisErrorT error = SA_AIS_OK;
 
 	if (clusterNode == NULL) {
 		return (SA_AIS_ERR_INVALID_PARAM);
@@ -530,7 +539,7 @@ saClmClusterNodeGet (
 
 	error = saHandleInstanceGet (&clmHandleDatabase, clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		return (error);
 	}
 
@@ -539,13 +548,13 @@ saClmClusterNodeGet (
 	/*
 	 * Send request message
 	 */
-	req_clm_nodeget.header.size = sizeof (struct req_clm_nodeget);
-	req_clm_nodeget.header.id = MESSAGE_REQ_CLM_NODEGET;
-	req_clm_nodeget.nodeId = nodeId;
+	req_lib_clm_nodeget.header.size = sizeof (struct req_lib_clm_nodeget);
+	req_lib_clm_nodeget.header.id = MESSAGE_REQ_CLM_NODEGET;
+	req_lib_clm_nodeget.nodeId = nodeId;
 
-	error = saSendReceiveReply (clmInstance->response_fd, &req_clm_nodeget,
-		sizeof (struct req_clm_nodeget), &res_clm_nodeget, sizeof (res_clm_nodeget));
-	if (error != SA_OK) {
+	error = saSendReceiveReply (clmInstance->response_fd, &req_lib_clm_nodeget,
+		sizeof (struct req_lib_clm_nodeget), &res_clm_nodeget, sizeof (res_clm_nodeget));
+	if (error != SA_AIS_OK) {
 		goto error_exit;
 	}
 
@@ -569,19 +578,19 @@ saClmClusterNodeGetAsync (
 	SaClmNodeIdT nodeId)
 {
 	struct clmInstance *clmInstance;
-	struct req_clm_nodegetasync req_clm_nodegetasync;
+	struct req_lib_clm_nodegetasync req_lib_clm_nodegetasync;
 	struct res_clm_nodegetasync res_clm_nodegetasync;
-	SaAisErrorT error = SA_OK;
+	SaAisErrorT error = SA_AIS_OK;
 
-	req_clm_nodegetasync.header.size = sizeof (struct req_clm_nodegetasync);
-	req_clm_nodegetasync.header.id = MESSAGE_REQ_CLM_NODEGETASYNC;
-	memcpy (&req_clm_nodegetasync.invocation, &invocation,
+	req_lib_clm_nodegetasync.header.size = sizeof (struct req_lib_clm_nodegetasync);
+	req_lib_clm_nodegetasync.header.id = MESSAGE_REQ_CLM_NODEGETASYNC;
+	memcpy (&req_lib_clm_nodegetasync.invocation, &invocation,
 		sizeof (SaInvocationT));
-	memcpy (&req_clm_nodegetasync.nodeId, &nodeId, sizeof (SaClmNodeIdT));
+	memcpy (&req_lib_clm_nodegetasync.nodeId, &nodeId, sizeof (SaClmNodeIdT));
 
 	error = saHandleInstanceGet (&clmHandleDatabase, clmHandle,
 		(void *)&clmInstance);
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		return (error);
 	}
 
@@ -592,10 +601,10 @@ saClmClusterNodeGetAsync (
 		goto error_exit;
 	}
 
-	error = saSendReceiveReply (clmInstance->response_fd, &req_clm_nodegetasync,
-		sizeof (struct req_clm_nodegetasync),
+	error = saSendReceiveReply (clmInstance->response_fd, &req_lib_clm_nodegetasync,
+		sizeof (struct req_lib_clm_nodegetasync),
 		&res_clm_nodegetasync, sizeof (struct res_clm_nodegetasync));
-	if (error != SA_OK) {
+	if (error != SA_AIS_OK) {
 		goto error_exit;
 	}
 

+ 6 - 1
test/testclm.c

@@ -144,6 +144,7 @@ int main (void) {
 	SaClmClusterNotificationT clusterNotification[64];
 	SaClmClusterNotificationBufferT clusterNotificationBuffer;
 	SaClmClusterNodeT clusterNode;
+	int i;
 
 	clusterNotificationBuffer.notification = clusterNotification;
 	clusterNotificationBuffer.numberOfItems = 64;
@@ -156,7 +157,7 @@ int main (void) {
 		exit (1);
 	}
 
-	result = saClmClusterNodeGet (handle, SA_CLM_LOCAL_NODE_ID, 0, &clusterNode);
+	result = saClmClusterNodeGet (handle, SA_CLM_LOCAL_NODE_ID, SA_TIME_END, &clusterNode);
 
 	printf ("Result of saClmClusterNodeGet %d\n", result);
 
@@ -180,6 +181,10 @@ int main (void) {
 	result = saClmClusterTrack (handle, SA_TRACK_CURRENT | SA_TRACK_CHANGES,
 		&clusterNotificationBuffer);
 	printf ("track result is %d\n", result);
+	for (i = 0; i < clusterNotificationBuffer.numberOfItems; i++) {
+		printSaClmClusterNodeT ("Results from SA_TRACK_CURRENT:",
+			&clusterNotificationBuffer.notification[i].clusterNode);
+	}
 
 	saClmSelectionObjectGet (handle, &select_fd);