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

performance loading service engine first implementation.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1682 fd59a12c-fef9-0310-b244-a6a79926bd2f
Steven Dake 17 лет назад
Родитель
Сommit
6198080084

+ 1 - 0
exec/apidef.c

@@ -91,6 +91,7 @@ static struct corosync_api_v1 apidef_corosync_api_v1 = {
 	.totem_ifaces_get = totempg_ifaces_get,
 	.totem_ifaces_print = totempg_ifaces_print,
 	.totem_ip_print = totemip_print,
+	.totem_callback_token_create = totempg_callback_token_create,
 	.tpg_init = totempg_groups_initialize,
 	.tpg_exit = NULL, /* missing from totempg api */
 	.tpg_join = (typedef_tpg_join)totempg_groups_join,

+ 4 - 0
exec/service.c

@@ -78,6 +78,10 @@ static struct default_service default_services[] = {
 		.name			 = "corosync_confdb",
 		.ver			 = 0,
 	},
+	{
+		.name			 = "corosync_pload",
+		.ver			 = 0,
+	},
 };
 
 struct corosync_service_engine *ais_service[SERVICE_HANDLER_MAXIMUM_COUNT];

+ 15 - 0
include/corosync/engine/coroapi.h

@@ -88,6 +88,13 @@ enum totem_configuration_type {
 };
 #endif
 
+#if !defined(TOTEM_CALLBACK_TOKEN_TYPE)
+enum totem_callback_token_type {
+	TOTEM_CALLBACK_TOKEN_RECEIVED = 1,
+	TOTEM_CALLBACK_TOKEN_SENT = 2
+};
+#endif
+
 enum corosync_lib_flow_control {
 	COROSYNC_LIB_FLOW_CONTROL_REQUIRED = 1,
 	COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED = 2
@@ -409,6 +416,14 @@ struct corosync_api_v1 {
 
 	char *(*totem_ip_print) (struct totem_ip_address *addr);
 
+
+	int (*totem_callback_token_create) (
+		void **handle_out,
+		enum totem_callback_token_type type,
+		int delete,
+		int (*callback_fn) (enum totem_callback_token_type type, void *),
+		void *data);
+
 	/*
 	 * Totem open process groups API for those service engines
 	 * wanting their own groups

+ 1 - 0
include/corosync/ipc_gen.h

@@ -48,6 +48,7 @@ enum service_types {
 	CPG_SERVICE = 8,
 	CONFDB_SERVICE = 10,
 	QUORUM_SERVICE = 11,
+	PLOAD_SERVICE = 12
 };
 
 enum req_init_types {

+ 71 - 0
include/corosync/ipc_pload.h

@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * 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.
+ */
+#ifndef IPC_PLOAD_H_DEFINED
+#define IPC_PLOAD_H_DEFINED
+
+#include "saAis.h"
+#include "pload.h"
+#include "ipc_gen.h"
+
+enum req_lib_evs_types {
+	MESSAGE_REQ_PLOAD_START = 0,
+};
+
+enum res_lib_evs_types {
+	MESSAGE_RES_PLOAD_START = 0,
+};
+
+struct res_lib_pload_start {
+	mar_res_header_t header;
+	unsigned int dataset[1024];
+};
+
+struct res_lib_pload_mcast {
+	mar_res_header_t header;
+};
+
+struct req_lib_pload_start {
+	mar_req_header_t header;
+	unsigned int msg_code;
+	unsigned int msg_size;
+	unsigned int msg_count;
+	unsigned int time_interval;
+};
+
+struct req_lib_pload_mcast {
+	mar_req_header_t header;
+	unsigned int code;
+};
+
+#endif /* IPC_PLOAD_H_DEFINED */

+ 100 - 0
include/corosync/pload.h

@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * 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.
+ */
+#ifndef COROSYNC_PLOAD_H_DEFINED
+#define COROSYNC_PLOAD_H_DEFINED
+
+#include <sys/types.h>
+#include <netinet/in.h>
+
+/**
+ * @defgroup corosync Other API services provided by corosync
+ */
+/**
+ * @addtogroup pload_corosync
+ *
+ * @{
+ */
+
+typedef uint64_t pload_handle_t;
+
+typedef enum {
+	PLOAD_OK = 1,
+	PLOAD_ERR_LIBRARY = 2,
+	PLOAD_ERR_TIMEOUT = 5,
+	PLOAD_ERR_TRY_AGAIN = 6,
+	PLOAD_ERR_INVALID_PARAM = 7,
+	PLOAD_ERR_NO_MEMORY = 8,
+	PLOAD_ERR_BAD_HANDLE = 9,
+	PLOAD_ERR_ACCESS = 11,
+	PLOAD_ERR_NOT_EXIST = 12,
+	PLOAD_ERR_EXIST = 14,
+	PLOAD_ERR_NOT_SUPPORTED = 20,
+	PLOAD_ERR_SECURITY = 29,
+	PLOAD_ERR_TOO_MANY_GROUPS=30
+} pload_error_t;
+
+typedef struct {
+	int callback;
+} pload_callbacks_t;
+
+/** @} */
+
+/*
+ * Create a new pload connection
+ */
+pload_error_t pload_initialize (
+	pload_handle_t *handle,
+	pload_callbacks_t *callbacks);
+
+/*
+ * Close the pload handle
+ */
+pload_error_t pload_finalize (
+	pload_handle_t handle);
+
+/*
+ * Get a file descriptor on which to poll.  pload_handle_t is NOT a
+ * file descriptor and may not be used directly.
+ */
+pload_error_t pload_fd_get (
+	pload_handle_t handle,
+	int *fd);
+
+unsigned int pload_start (
+        pload_handle_t handle,
+        unsigned int code,
+        unsigned int msg_count,
+        unsigned int msg_size);
+
+#endif /* COROSYNC_PLOAD_H_DEFINED */

+ 1 - 0
include/corosync/totem/totem.h

@@ -150,6 +150,7 @@ enum totem_configuration_type {
 	TOTEM_CONFIGURATION_TRANSITIONAL	
 };
 
+#define TOTEM_CALLBACK_TOKEN_TYPE
 enum totem_callback_token_type {
 	TOTEM_CALLBACK_TOKEN_RECEIVED = 1,
 	TOTEM_CALLBACK_TOKEN_SENT = 2

+ 10 - 0
lib/Makefile

@@ -42,6 +42,7 @@ all: libcpg.a libcpg.so.2.0.0 \
 	libevs.a libevs.so.2.0.0 \
 	libcfg.a libcfg.so.2.0.0 \
 	libquorum.a libquorum.so.2.0.0 \
+	libpload.a libpload.so.2.0.0 \
 	libcoroutil.a libcoroutil.so.2.0.0
 
 libcoroutil.a: util.o
@@ -68,6 +69,9 @@ libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o
 libcfg.so.2.0.0: util.o cfg.o
 	$(CC) $(DARWIN_OPTS) util.o cfg.o -o $@
 
+libpload.so.2.0.0: util.o pload.o
+	$(CC) $(DARWIN_OPTS) util.o pload.o -o $@
+
 else
 
 libcoroutil.so.2.0.0: util.o
@@ -88,6 +92,9 @@ libconfdb.so.2.0.0: util.o confdb.o sa-confdb.o
 libcfg.so.2.0.0: util.o cfg.o
 	$(CC) -shared -Wl,-soname,libcfg.so.2,-version-script=$(srcdir)$(subdir)libcfg.versions util.o cfg.o -o $@
 
+libpload.so.2.0.0: util.o pload.o
+	$(CC) -shared -Wl,-soname,libpload.so.2,-version-script=$(srcdir)$(subdir)libpload.versions util.o cfg.o -o $@
+
 endif
 
 libevs.a: util.o evs.o
@@ -105,6 +112,9 @@ libconfdb.a: util.o confdb.o sa-confdb.o
 libcfg.a: util.o cfg.o
 	$(AR) -rc libcfg.a util.o cfg.o
 
+libpload.a: util.o pload.o
+	$(AR) -rc libpload.a util.o pload.o
+
 clean:
 	rm -f *.o libcfg.so* libcoroutil.so* libcoroutil.a \
 		libevs.so* libevs.a libcpg.so* libcpg.a libcfg.a libconfdb.so* \

+ 21 - 0
lib/libpload.versions

@@ -0,0 +1,21 @@
+# Version and symbol export for libSaClm.so
+
+COROSYNC_PLOAD_1.0 {
+	global:
+		pload_start;
+
+	local:
+		saHandleCreate;
+		saHandleDestroy;
+		saHandleInstanceGet;
+		saHandleInstancePut;
+		saRecvRetry;
+		saSelectRetry;
+		saSendMsgReceiveReply;
+		saSendMsgRetry;
+		saSendReceiveReply;
+		saSendRetry;
+		saServiceConnect;
+		saVersionVerify;
+		clustTimeNow;
+};

+ 238 - 0
lib/pload.c

@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#include <corosync/swab.h>
+#include <corosync/totem/totem.h>
+#include <corosync/saAis.h>
+#include <corosync/ipc_pload.h>
+#include <corosync/pload.h>
+#include <corosync/ais_util.h>
+
+static void pload_instance_destructor (void *instance);
+
+struct pload_inst {
+	int dispatch_fd;
+	int response_fd;
+	pthread_mutex_t response_mutex;
+	pthread_mutex_t dispatch_mutex;
+	unsigned int finalize;
+};
+
+static struct saHandleDatabase pload_handle_t_db = {
+	.handleCount			= 0,
+	.handles			= 0,
+	.mutex				= PTHREAD_MUTEX_INITIALIZER,
+	.handleInstanceDestructor	= pload_instance_destructor
+};
+
+/*
+ * Clean up function for an evt instance (saEvtInitialize) handle
+ */
+static void pload_instance_destructor (void *instance)
+{
+	struct pload_inst *pload_inst = instance;
+
+	pthread_mutex_destroy (&pload_inst->response_mutex);
+	pthread_mutex_destroy (&pload_inst->dispatch_mutex);
+}
+
+
+/**
+ * @defgroup pload_corosync The extended virtual synchrony passthrough API
+ * @ingroup corosync
+ *
+ * @{
+ */
+/**
+ * test
+ * @param handle The handle of pload initialize
+ * @param callbacks The callbacks for pload_initialize
+ * @returns PLOAD_OK
+ */
+unsigned int pload_initialize (
+	pload_handle_t *handle,
+	pload_callbacks_t *callbacks)
+{
+	SaAisErrorT error;
+	struct pload_inst *pload_inst;
+
+	error = saHandleCreate (&pload_handle_t_db, sizeof (struct pload_inst), handle);
+	if (error != SA_AIS_OK) {
+		goto error_no_destroy;
+	}
+
+	error = saHandleInstanceGet (&pload_handle_t_db, *handle, (void *)&pload_inst);
+	if (error != SA_AIS_OK) {
+		goto error_destroy;
+	}
+
+	error = saServiceConnect (&pload_inst->response_fd,
+		&pload_inst->dispatch_fd,
+		PLOAD_SERVICE);
+	if (error != SA_AIS_OK) {
+		goto error_put_destroy;
+	}
+
+	pthread_mutex_init (&pload_inst->response_mutex, NULL);
+
+	pthread_mutex_init (&pload_inst->dispatch_mutex, NULL);
+
+	saHandleInstancePut (&pload_handle_t_db, *handle);
+
+	return (SA_AIS_OK);
+
+error_put_destroy:
+	saHandleInstancePut (&pload_handle_t_db, *handle);
+error_destroy:
+	saHandleDestroy (&pload_handle_t_db, *handle);
+error_no_destroy:
+	return (error);
+}
+
+unsigned int pload_finalize (
+	pload_handle_t handle)
+{
+	struct pload_inst *pload_inst;
+	SaAisErrorT error;
+
+	error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst);
+	if (error != SA_AIS_OK) {
+		return (error);
+	}
+//	  TODO is the locking right here
+	pthread_mutex_lock (&pload_inst->response_mutex);
+
+	/*
+	 * Another thread has already started finalizing
+	 */
+	if (pload_inst->finalize) {
+		pthread_mutex_unlock (&pload_inst->response_mutex);
+		saHandleInstancePut (&pload_handle_t_db, handle);
+		return (PLOAD_ERR_BAD_HANDLE);
+	}
+
+	pload_inst->finalize = 1;
+
+	pthread_mutex_unlock (&pload_inst->response_mutex);
+
+	saHandleDestroy (&pload_handle_t_db, handle);
+    /*
+     * Disconnect from the server
+     */
+    if (pload_inst->response_fd != -1) {
+        shutdown(pload_inst->response_fd, 0);
+        close(pload_inst->response_fd);
+    }
+    if (pload_inst->dispatch_fd != -1) {
+        shutdown(pload_inst->dispatch_fd, 0);
+        close(pload_inst->dispatch_fd);
+    }
+	saHandleInstancePut (&pload_handle_t_db, handle);
+
+
+	return (PLOAD_OK);
+}
+
+unsigned int pload_fd_get (
+	pload_handle_t handle,
+	int *fd)
+{
+	SaAisErrorT error;
+	struct pload_inst *pload_inst;
+
+	error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst);
+	if (error != SA_AIS_OK) {
+		return (error);
+	}
+
+	*fd = pload_inst->dispatch_fd; 
+
+	saHandleInstancePut (&pload_handle_t_db, handle);
+
+	return (SA_AIS_OK);
+}
+
+unsigned int pload_start (
+	pload_handle_t handle,
+	unsigned int code,
+	unsigned int msg_count,
+	unsigned int msg_size)
+{
+	unsigned int error;
+	struct pload_inst *pload_inst;
+	struct iovec iov;
+	struct req_lib_pload_start req_lib_pload_start;
+	struct res_lib_pload_start res_lib_pload_start;
+
+	error = saHandleInstanceGet (&pload_handle_t_db, handle, (void *)&pload_inst);
+	if (error != SA_AIS_OK) {
+		return (error);
+	}
+
+	req_lib_pload_start.header.size = sizeof (struct req_lib_pload_start);
+	req_lib_pload_start.header.id = MESSAGE_REQ_PLOAD_START;
+	req_lib_pload_start.msg_code = code;
+	req_lib_pload_start.msg_count = msg_count;
+	req_lib_pload_start.msg_size = msg_size;
+
+	iov.iov_base = (char *)&req_lib_pload_start;
+	iov.iov_len = sizeof (struct req_lib_pload_start);
+	
+	pthread_mutex_lock (&pload_inst->response_mutex);
+
+	error = saSendMsgReceiveReply (pload_inst->response_fd, &iov, 1,
+		&res_lib_pload_start, sizeof (struct res_lib_pload_start));
+
+	pthread_mutex_unlock (&pload_inst->response_mutex);
+
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+
+	error = res_lib_pload_start.header.error;
+
+error_exit:
+	saHandleInstancePut (&pload_handle_t_db, handle);
+
+	return (error);
+}
+
+/** @} */

+ 9 - 3
services/Makefile

@@ -50,12 +50,12 @@ ifeq (${COROSYNC_COMPAT}, SOLARIS)
 endif
 
 # LCR objects
-LCR_SRC = evs.c cfg.c cpg.c confdb.c
-LCR_OBJS = evs.o cfg.o cpg.o confdb.o $(AMF_OBJS)
+LCR_SRC = evs.c cfg.c cpg.c confdb.c pload.c
+LCR_OBJS = evs.o cfg.o cpg.o confdb.o $(AMF_OBJS) pload.o
 
 override CFLAGS += -fPIC
 
-all: service_evs.lcrso service_cfg.lcrso service_cpg.lcrso service_confdb.lcrso
+all: service_evs.lcrso service_cfg.lcrso service_cpg.lcrso service_confdb.lcrso service_pload.lcrso
 
 ifeq (${COROSYNC_COMPAT}, DARWIN)
 
@@ -71,6 +71,9 @@ service_confdb.lcrso: confdb.o
 service_cpg.lcrso: cpg.o
 	$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load cpg.o -o $@
 
+service_pload.lcrso: pload.o
+	$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ../exec/corosync -bind_at_load pload.o -o $@
+
 else
 
 service_evs.lcrso: evs.o
@@ -85,6 +88,9 @@ service_confdb.lcrso: confdb.o
 service_cpg.lcrso: cpg.o
 	$(CC) -shared -Wl,-soname,service_cpg.lcrso cpg.o -o $@
 
+service_pload.lcrso: pload.o
+	$(CC) -shared -Wl,-soname,service_pload.lcrso pload.o -o $@
+
 endif
 
 clean:

+ 356 - 0
services/pload.c

@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include <corosync/swab.h>
+#include <corosync/saAis.h>
+#include <corosync/ipc_gen.h>
+#include <corosync/lcr/lcr_comp.h>
+#include <corosync/engine/coroapi.h>
+#include <corosync/ipc_pload.h>
+#include <corosync/list.h>
+#include <corosync/engine/logsys.h>
+
+LOGSYS_DECLARE_SUBSYS ("PLOAD", LOG_INFO);
+
+enum pload_exec_message_req_types {
+	MESSAGE_REQ_EXEC_PLOAD_START = 0,
+	MESSAGE_REQ_EXEC_PLOAD_MCAST = 1
+};
+
+/*
+ * Service Interfaces required by service_message_handler struct
+ */
+static int pload_exec_init_fn (
+	struct corosync_api_v1 *corosync_api);
+
+static void pload_confchg_fn (
+	enum totem_configuration_type configuration_type,
+	unsigned int *member_list, int member_list_entries,
+	unsigned int *left_list, int left_list_entries,
+	unsigned int *joined_list, int joined_list_entries,
+	struct memb_ring_id *ring_id);
+
+static void message_handler_req_exec_pload_start (void *msg, unsigned int nodeid);
+
+static void message_handler_req_exec_pload_mcast (void *msg, unsigned int nodeid);
+
+static void req_exec_pload_start_endian_convert (void *msg);
+
+static void req_exec_pload_mcast_endian_convert (void *msg);
+
+static void message_handler_req_pload_start (void *conn, void *msg);
+
+static int pload_lib_init_fn (void *conn);
+
+static int pload_lib_exit_fn (void *conn);
+
+static char buffer[1000000];
+
+static unsigned int msgs_delivered = 0;
+
+static unsigned int msgs_wanted = 0;
+
+static unsigned int msg_size = 0;
+
+static unsigned int msg_code = 1;
+
+static unsigned int msgs_sent = 0;
+
+	
+static struct corosync_api_v1 *api;
+
+struct req_exec_pload_start {
+	mar_req_header_t header;
+	unsigned int msg_code;
+	unsigned int msg_count;
+	unsigned int msg_size;
+	unsigned int time_interval;
+};
+
+struct req_exec_pload_mcast {
+	mar_req_header_t header;
+	unsigned int msg_code;
+};
+
+static struct corosync_lib_handler pload_lib_engine[] =
+{
+	{ /* 0 */
+		.lib_handler_fn		= message_handler_req_pload_start,
+		.response_size		= sizeof (struct res_lib_pload_start),
+		.response_id		= MESSAGE_RES_PLOAD_START,
+		.flow_control		= COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+	}
+};
+
+static struct corosync_exec_handler pload_exec_engine[] =
+{
+	{
+		.exec_handler_fn 	= message_handler_req_exec_pload_start,
+		.exec_endian_convert_fn	= req_exec_pload_start_endian_convert
+	},
+	{
+		.exec_handler_fn 	= message_handler_req_exec_pload_mcast,
+		.exec_endian_convert_fn	= req_exec_pload_mcast_endian_convert
+	}
+};
+
+struct corosync_service_engine pload_service_engine = {
+	.name			= "corosync profile loading service",
+	.id			= PLOAD_SERVICE,
+	.private_data_size	= 0,
+	.flow_control		= COROSYNC_LIB_FLOW_CONTROL_REQUIRED, 
+	.lib_init_fn		= pload_lib_init_fn,
+	.lib_exit_fn		= pload_lib_exit_fn,
+	.lib_engine		= pload_lib_engine,
+	.lib_engine_count	= sizeof (pload_lib_engine) / sizeof (struct corosync_lib_handler),
+	.exec_engine		= pload_exec_engine,
+	.exec_engine_count	= sizeof (pload_exec_engine) / sizeof (struct corosync_exec_handler),
+	.confchg_fn		= pload_confchg_fn,
+	.exec_init_fn		= pload_exec_init_fn,
+	.exec_dump_fn		= NULL
+};
+
+static DECLARE_LIST_INIT (confchg_notify);
+
+/*
+ * Dynamic loading descriptor
+ */
+
+static struct corosync_service_engine *pload_get_service_engine_ver0 (void);
+
+static struct corosync_service_engine_iface_ver0 pload_service_engine_iface = {
+	.corosync_get_service_engine_ver0	= pload_get_service_engine_ver0
+};
+
+static struct lcr_iface corosync_pload_ver0[1] = {
+	{
+		.name			= "corosync_pload",
+		.version		= 0,
+		.versions_replace	= 0,
+		.versions_replace_count = 0,
+		.dependencies		= 0,
+		.dependency_count	= 0,
+		.constructor		= NULL,
+		.destructor		= NULL,
+		.interfaces		= NULL,
+	}
+};
+
+static struct lcr_comp pload_comp_ver0 = {
+	.iface_count	= 1,
+	.ifaces		= corosync_pload_ver0
+};
+
+static struct corosync_service_engine *pload_get_service_engine_ver0 (void)
+{
+	return (&pload_service_engine);
+}
+
+__attribute__ ((constructor)) static void pload_comp_register (void) {
+	lcr_interfaces_set (&corosync_pload_ver0[0], &pload_service_engine_iface);
+
+	lcr_component_register (&pload_comp_ver0);
+}
+
+static int pload_exec_init_fn (
+	struct corosync_api_v1 *corosync_api)
+{
+	api = corosync_api;
+
+	return 0;
+}
+
+static void pload_confchg_fn (
+	enum totem_configuration_type configuration_type,
+	unsigned int *member_list, int member_list_entries,
+	unsigned int *left_list, int left_list_entries,
+	unsigned int *joined_list, int joined_list_entries,
+	struct memb_ring_id *ring_id)
+{
+}
+
+static int pload_lib_init_fn (void *conn)
+{
+	return (0);
+}
+
+static int pload_lib_exit_fn (void *conn)
+{
+	return (0);
+}
+
+static void message_handler_req_pload_start (void *conn, void *msg)
+{
+	struct req_lib_pload_start *req_lib_pload_start = (struct req_lib_pload_start *)msg;
+	struct req_exec_pload_start req_exec_pload_start;
+	struct iovec iov;
+
+	req_exec_pload_start.header.id =
+		SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_START);
+	req_exec_pload_start.msg_code = req_lib_pload_start->msg_code;
+	req_exec_pload_start.msg_size = req_lib_pload_start->msg_size;
+	req_exec_pload_start.msg_count = req_lib_pload_start->msg_count;
+	req_exec_pload_start.time_interval = req_lib_pload_start->time_interval;
+	iov.iov_base = &req_exec_pload_start;
+	iov.iov_len = sizeof (struct req_exec_pload_start);
+
+	api->totem_mcast (&iov, 1, TOTEM_AGREED);
+}
+
+static void req_exec_pload_start_endian_convert (void *msg)
+{
+}
+
+static void req_exec_pload_mcast_endian_convert (void *msg)
+{
+}
+
+static int msg_no = 0;
+
+int send_message (enum totem_callback_token_type type, void *arg)
+{
+	struct req_exec_pload_mcast req_exec_pload_mcast;
+	struct iovec iov[2];
+	unsigned int res;
+	int iov_len = 2;
+
+	req_exec_pload_mcast.header.id =
+		SERVICE_ID_MAKE (PLOAD_SERVICE, MESSAGE_REQ_EXEC_PLOAD_MCAST);
+	req_exec_pload_mcast.header.size = sizeof (struct req_exec_pload_mcast) + msg_size;
+
+	iov[0].iov_base = &req_exec_pload_mcast;
+	iov[0].iov_len = sizeof (struct req_exec_pload_mcast);
+	iov[1].iov_base = buffer;
+	iov[1].iov_len = msg_size - sizeof (struct req_exec_pload_mcast);
+	if (iov[1].iov_len < 0) {
+		iov_len = 1;
+	}
+
+	do {
+		res = api->totem_mcast (iov, iov_len, TOTEM_AGREED);
+		if (res == -1) {
+			break;
+		} else {
+			msgs_sent++;
+			msg_code++;
+		}
+	} while (msgs_sent <= msgs_wanted);
+	if (msgs_sent == msgs_wanted) {
+		return (0);
+	} else {
+		return (-1);
+	}
+}
+
+void *token_callback;
+void start_mcasting (void)
+{
+	api->totem_callback_token_create (
+		&token_callback,
+		TOTEM_CALLBACK_TOKEN_RECEIVED,
+		1,
+		send_message,	
+		&token_callback);
+} 
+
+static void message_handler_req_exec_pload_start (
+	void *msg,
+	unsigned int nodeid)
+{
+	struct req_exec_pload_start *req_exec_pload_start = (struct req_exec_pload_start *)msg;
+
+	msgs_wanted = req_exec_pload_start->msg_count;
+	msg_size = req_exec_pload_start->msg_size;
+	msg_code = req_exec_pload_start->msg_code;
+
+	start_mcasting ();
+}
+
+# define timersub(a, b, result)                                               \
+  do {                                                                        \
+    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;                             \
+    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;                          \
+    if ((result)->tv_usec < 0) {                                              \
+      --(result)->tv_sec;                                                     \
+      (result)->tv_usec += 1000000;                                           \
+    }                                                                         \
+  } while (0)
+
+struct timeval tv1;
+struct timeval tv2;
+struct timeval tv_elapsed;
+int last_msg_no = 0;
+
+static void message_handler_req_exec_pload_mcast (
+	void *msg,
+	unsigned int nodeid)
+{
+	struct req_exec_pload_mcast *pload_mcast = (struct req_exec_pload_mcast *)msg;
+
+	assert (pload_mcast->msg_code - 1 == last_msg_no);
+	last_msg_no = pload_mcast->msg_code;
+	if (msgs_delivered == 0) {
+		gettimeofday (&tv1, NULL);
+	}
+	msgs_delivered += 1;
+	if (msgs_delivered == msgs_wanted) {
+		gettimeofday (&tv2, NULL);
+		timersub (&tv2, &tv1, &tv_elapsed);
+	        printf ("%5d Writes ", msgs_delivered);
+		printf ("%5d bytes per write ", msg_size);
+		printf ("%7.3f Seconds runtime ",
+		(tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+		printf ("%9.3f TP/s ",
+		((float)msgs_delivered) /  (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
+		printf ("%7.3f MB/s.\n",
+		((float)msgs_delivered) * ((float)msg_size) /  ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0));
+	}
+}

+ 5 - 2
tools/Makefile

@@ -41,8 +41,8 @@ ifeq (${COROSYNC_COMPAT}, SOLARIS)
 	override LDFLAGS += -lnsl -lsocket -lrt
 endif
 
-LIBS = ../lib/libconfdb.a ../lib/libcfg.a
-BINARIES=corosync-objctl corosync-cfgtool corosync-keygen corosync-fplay
+LIBS = ../lib/libconfdb.a ../lib/libcfg.a ../lib/libpload.a
+BINARIES=corosync-objctl corosync-cfgtool corosync-keygen corosync-fplay corosync-pload
 APPS_SRC=$(addsuffix .c,$(BINARIES))
 EXTRA_CFLAGS = -I$(srcdir)include
 
@@ -60,6 +60,9 @@ corosync-keygen: corosync-keygen.o
 corosync-fplay: corosync-fplay.o
 	$(CC) $(LDFLAGS) -o $@ $<
 
+corosync-pload: corosync-pload.o
+	$(CC) $(LDFLAGS) -o $@ $< $(LIBS)
+
 clean:
 	rm -f *.o $(BINARIES)
 

+ 76 - 0
tools/corosync-pload.c

@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake@redhat.com)
+ *
+ * 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 <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/un.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <corosync/saAis.h>
+#include <corosync/pload.h>
+
+#define timersub(a, b, result)						\
+do {									\
+	(result)->tv_sec = (a)->tv_sec - (b)->tv_sec;			\
+	(result)->tv_usec = (a)->tv_usec - (b)->tv_usec;		\
+	if ((result)->tv_usec < 0) {					\
+		--(result)->tv_sec;					\
+		(result)->tv_usec += 1000000;				\
+	}								\
+} while (0)
+
+int main (void) {
+	pload_error_t result;
+	pload_handle_t handle;
+
+	result = pload_initialize (&handle, NULL);
+	printf ("Init result %d\n", result);
+	result = pload_start (
+		handle,
+		0, /* code */
+		150000000, /* count */
+		300); /* size */
+	return (0);
+}