In the light of comments I've made some changes to the quorum service.

1. It now loads it's provider module. using the key
 quorum.provider: name
2. Removed the internal API and added it to corosync_api_v1
3. It also loads its 'alter-ego' module that provides the library
service so it doesn't need to be added to corosync.conf - simply
specifying 'vsftype: quorum' will now work.

Also attached, though not as part of the patch, is an example simple
quorum service provider that changes quorum based on the quorum.quorate
objdb variable. This can be toggled with corosync-objctl to test the
features.

-- 

Chrissie
Index: include/corosync/engine/coroapi.h
===================================================================
--- include/corosync/engine/coroapi.h	(revision 1677)
+++ include/corosync/engine/coroapi.h	(working copy)
@@ -471,6 +471,8 @@
 	int (*sync_request) (
 		char *service_name);
 
+	int (*sync_primary_designated) (void);
+
 	/*
 	 * Plugin loading and unloading
 	 */
Index: services/confdb.c
===================================================================
--- services/confdb.c	(revision 1677)
+++ services/confdb.c	(working copy)
@@ -212,6 +212,7 @@
 	.id					= CONFDB_SERVICE,
 	.private_data_size			= 0,
 	.flow_control				= COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED,
+	.allow_inquorate			= COROSYNC_LIB_ALLOW_INQUORATE,
 	.lib_init_fn				= confdb_lib_init_fn,
 	.lib_exit_fn				= confdb_lib_exit_fn,
 	.lib_engine				= confdb_lib_engine,
Index: exec/vsf.h
===================================================================
--- exec/vsf.h	(revision 1677)
+++ exec/vsf.h	(working copy)
@@ -34,12 +34,14 @@
 #ifndef VSF_H_DEFINED
 #define VSF_H_DEFINED
 
+struct corosync_api_v1;
 struct corosync_vsf_iface_ver0 {
 
 	/*
 	 * Executes a callback whenever component changes
 	 */
 	int (*init) (
+	    struct corosync_api_v1 *api,
 	    void (*primary_callback_fn) (
 		unsigned int *view_list,
 		int view_list_entries,
Index: exec/vsf_quorum.c
===================================================================
--- exec/vsf_quorum.c	(revision 1677)
+++ exec/vsf_quorum.c	(working copy)
@@ -60,6 +60,7 @@
 #include <corosync/ipc_gen.h>
 #include <corosync/ipc_quorum.h>
 #include <corosync/lcr/lcr_comp.h>
+#include <corosync/lcr/lcr_ifact.h>
 #include <corosync/engine/coroapi.h>
 
 #include "vsf.h"
@@ -101,7 +102,7 @@
 				  int quorum, struct memb_ring_id *ring_id)
 {
 	primary_designated = quorum;
-	memcpy(&quorum_ring_id, &ring_id, sizeof (quorum_ring_id));
+	memcpy(&quorum_ring_id, ring_id, sizeof (quorum_ring_id));
 
 	quorum_view_list_entries = view_list_entries;
 	memcpy(quorum_view_list, view_list, sizeof(unsigned int)*view_list_entries);
@@ -114,7 +115,9 @@
 	send_quorum_notification(NULL);
 }
 
+/* Register with sync service */
 static int quorum_init (
+	struct corosync_api_v1 *api,
 	void (*primary_callback_fn) (
 		unsigned int *view_list,
 		int view_list_entries,
@@ -123,11 +126,13 @@
 {
 	quorum_primary_callback_fn = primary_callback_fn;
 
+	/* Load the library-servicing part of this module */
+	api->service_link_and_init(api, "corosync_quorum", 0);
 	return (0);
 }
 
 /*
- * Returns 1 if this processor is in the primary (has quorum)
+ * Returns 1 to sync if this processor has quorum
  */
 static int quorum_primary (void)
 {
@@ -142,10 +147,6 @@
 	.primary			= quorum_primary
 };
 
-static struct quorum_services_api_ver1 quorum_service_api_v1 = {
-	.quorum_api_set_quorum = quorum_api_set_quorum
-};
-
 static struct corosync_lib_handler quorum_lib_service[] =
 {
 	{ /* 0 */
@@ -181,7 +182,7 @@
 	.lib_engine_count			= sizeof (quorum_lib_service) / sizeof (struct corosync_lib_handler),
 };
 
-static struct lcr_iface corosync_vsf_quorum_ver0[3] = {
+static struct lcr_iface corosync_vsf_quorum_ver0[2] = {
 	{ /* the VSF handler */
 		.name			= "corosync_vsf_quorum",
 		.version		= 0,
@@ -193,18 +194,7 @@
 		.destructor		= NULL,
 		.interfaces		= (void **)(void *)&vsf_quorum_iface_ver0,
 	},
-	{ /* API for quorum users to call */
-		.name                   = "corosync_quorum_api",
-		.version		= 0,
-		.versions_replace	= 0,
-		.versions_replace_count = 0,
-		.dependencies		= 0,
-		.dependency_count	= 0,
-		.constructor		= NULL,
-		.destructor		= NULL,
-		.interfaces		= NULL
-	},
-	{ /* Library calls */
+	{ /* Library & exec calls */
 		.name			= "corosync_quorum",
 		.version		= 0,
 		.versions_replace	= 0,
@@ -224,7 +214,7 @@
 }
 
 static struct lcr_comp vsf_quorum_comp_ver0 = {
-	.iface_count			= 3,
+	.iface_count			= 2,
 	.ifaces				= corosync_vsf_quorum_ver0
 };
 
@@ -235,16 +225,59 @@
 __attribute__ ((constructor)) static void vsf_quorum_comp_register (void) {
 	lcr_component_register (&vsf_quorum_comp_ver0);
 	lcr_interfaces_set (&corosync_vsf_quorum_ver0[0], &vsf_quorum_iface_ver0);
-	lcr_interfaces_set (&corosync_vsf_quorum_ver0[1], &quorum_service_api_v1);
-	lcr_interfaces_set (&corosync_vsf_quorum_ver0[2], &quorum_service_handler_iface);
+	lcr_interfaces_set (&corosync_vsf_quorum_ver0[1], &quorum_service_handler_iface);
 }
 
 /* -------------------------------------------------- */
 
+struct quorum_services_api_ver1 *quorum_iface;
+
 static int quorum_exec_init_fn (struct corosync_api_v1 *api)
 {
+	unsigned int find_handle;
+	unsigned int quorum_handle = 0;
+	unsigned int q_handle;
+	char *quorum_module;
+	int res;
+	void *quorum_iface_p;
+
 	corosync_api = api;
 	list_init (&trackers_list);
+
+	/* Look for a quorum module */
+	api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle);
+        api->object_find_next(find_handle, &quorum_handle);
+	api->object_find_destroy(find_handle);
+
+	if (quorum_handle) {
+		if ( !(res = api->object_key_get(quorum_handle,
+						 "provider",
+						 strlen("provider"),
+						 (void *)&quorum_module,
+						 NULL))) {
+
+			res = lcr_ifact_reference (
+				&q_handle,
+				quorum_module,
+				0,
+				&quorum_iface_p,
+				0);
+
+			if (res == -1) {
+				log_printf (LOG_LEVEL_NOTICE,
+					    "Couldn't load quorum provider %s\n",
+					    quorum_module);
+				return (-1);
+			}
+
+			log_printf (LOG_LEVEL_NOTICE,
+				    "Using quorum provider %s\n", quorum_module);
+
+			quorum_iface = (struct quorum_services_api_ver1 *)quorum_iface_p;
+			quorum_iface->init (api, quorum_api_set_quorum);
+		}
+	}
+
 	return (0);
 }
 
Index: exec/apidef.c
===================================================================
--- exec/apidef.c	(revision 1677)
+++ exec/apidef.c	(working copy)
@@ -100,6 +100,7 @@
 	.tpg_groups_mcast = (typedef_tpg_groups_mcast)totempg_groups_mcast_groups,
 	.tpg_groups_send_ok = (typedef_tpg_groups_send_ok)totempg_groups_send_ok_groups,
 	.sync_request = sync_request,
+	.sync_primary_designated = sync_primary_designated,
 	.service_link_and_init = corosync_service_link_and_init,
 	.service_unlink_and_exit = corosync_service_unlink_and_exit,
 	.plugin_interface_reference = lcr_ifact_reference,
Index: exec/quorum.h
===================================================================
--- exec/quorum.h	(revision 1677)
+++ exec/quorum.h	(working copy)
@@ -35,41 +35,10 @@
 #ifndef QUORUM_H_DEFINED
 #define QUORUM_H_DEFINED
 
-struct quorum_services_api_ver1 {
-	void (*quorum_api_set_quorum) (unsigned int *,int,
-				       int,  struct memb_ring_id *);
-		};
+typedef void (*quorum_set_quorate_fn_t) (unsigned int *view_list, int view_list_entries,
+					 int quorate, struct memb_ring_id *);
 
-static inline struct quorum_services_api_ver1 *
-quorum_services_api_reference (
-	struct corosync_api_v1 *coroapi,
-	unsigned int *handle)
-{
-	static void *quorum_services_api_p;
-	struct quorum_services_api_ver1 *return_api;
-	unsigned int res;
-
-	res = coroapi->plugin_interface_reference (
-		handle,
-		"quorum_services_api",
-		0,
-		&quorum_services_api_p,
-		0);
-	if (res == -1) {
-		return (NULL);
-	}
-	return_api = (struct quorum_services_api_ver1 *)quorum_services_api_p;
-	return (return_api);
-}
-
-static int inline quorum_services_api_release (
-	struct corosync_api_v1 *coroapi,
-	unsigned int handle)
-{
-	unsigned int res;
-
-	res = coroapi->plugin_interface_release (handle);
-	return (res);
-}
-
+struct quorum_services_api_ver1 {
+	void (*init) (struct corosync_api_v1 *api, quorum_set_quorate_fn_t);
+};
 #endif /* QUORUM_H_DEFINED */
Index: exec/vsf_ykd.c
===================================================================
--- exec/vsf_ykd.c	(revision 1677)
+++ exec/vsf_ykd.c	(working copy)
@@ -499,6 +499,7 @@
 };
 
 static int ykd_init (
+	struct corosync_api_v1 *api,
 	void (*primary_callback_fn) (
 		unsigned int *view_list,
 		int view_list_entries,
Index: exec/sync.c
===================================================================
--- exec/sync.c	(revision 1677)
+++ exec/sync.c	(working copy)
@@ -265,6 +265,7 @@
 }
 
 int sync_register (
+	struct corosync_api_v1 *api,
 	int (*callbacks_retrieve) (int sync_id, struct sync_callbacks *callack),
 	void (*synchronization_completed) (void),
 	char *vsf_type)
@@ -319,7 +320,7 @@
 			"Using virtual synchrony filter %s\n", corosync_vsf_type);
 
 		vsf_iface = (struct corosync_vsf_iface_ver0 *)vsf_iface_p;
-		vsf_iface->init (sync_primary_callback_fn);
+		vsf_iface->init (api, sync_primary_callback_fn);
 	}
 
 	sync_callbacks_retrieve = callbacks_retrieve;
Index: exec/sync.h
===================================================================
--- exec/sync.h	(revision 1677)
+++ exec/sync.h	(working copy)
@@ -47,7 +47,9 @@
 	char *name;
 };
 
+struct corosync_api_v1;
 int sync_register (
+	struct corosync_api_v1 *api,
 	int (*sync_callbacks_retrieve) (int sync_id, struct sync_callbacks *callbacks),
 	void (*synchronization_completed) (void),
 	char *vsf_type);
Index: exec/main.c
===================================================================
--- exec/main.c	(revision 1677)
+++ exec/main.c	(working copy)
@@ -704,7 +704,7 @@
 	}
 
 
-	sync_register (corosync_sync_callbacks_retrieve, corosync_sync_completed,
+	sync_register (api, corosync_sync_callbacks_retrieve, corosync_sync_completed,
 		totem_config.vsf_type);
 
 
/*
 * Copyright (c) 2008 Red Hat, Inc.
 *
 * All rights reserved.
 *
 * Author: Christine Caulfield ([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 <assert.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/poll.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <sched.h>
#include <time.h>

#include <corosync/engine/logsys.h>
#include <corosync/ipc_gen.h>
#include <corosync/lcr/lcr_comp.h>
#include <corosync/engine/coroapi.h>

#include "quorum.h"

LOGSYS_DECLARE_SUBSYS ("QUORUM", LOG_INFO);

static int quorum_exec_init_fn (struct corosync_api_v1 *api);
static void test_init(struct corosync_api_v1 *api, quorum_set_quorate_fn_t report);

/*
 * lcrso object definition
 */
static struct quorum_services_api_ver1 test_quorum_iface_ver0 = {
	.init				= test_init
};

static struct corosync_service_engine quorum_service_handler = {
	.name				        = "corosync TESTING cluster quorum service v0.1",
	.id					= 22, // HO HO HO
	.private_data_size			= 0,
	.exec_init_fn				= quorum_exec_init_fn,
};

static struct lcr_iface corosync_test_quorum_ver0[1] = {
	{ /* the quorum handler */
		.name			= "testquorum",
		.version		= 0,
		.versions_replace	= 0,
		.versions_replace_count	= 0,
		.dependencies		= 0,
		.dependency_count	= 0,
		.constructor		= NULL,
		.destructor		= NULL,
		.interfaces		= (void **)(void *)&test_quorum_iface_ver0,
	},
};

static struct corosync_service_engine *quorum_get_service_handler_ver0 (void)
{
	return (&quorum_service_handler);
}

static struct lcr_comp test_quorum_comp_ver0 = {
	.iface_count			= 1,
	.ifaces				= corosync_test_quorum_ver0
};

static struct corosync_service_engine_iface_ver0 quorum_service_handler_iface = {
	.corosync_get_service_engine_ver0 = quorum_get_service_handler_ver0
};

__attribute__ ((constructor)) static void test_quorum_comp_register (void) {
	lcr_component_register (&test_quorum_comp_ver0);
	lcr_interfaces_set (&corosync_test_quorum_ver0[0], &test_quorum_iface_ver0);
}

/* -------------------------------------------------- */

static quorum_set_quorate_fn_t set_quorum;

static void key_change_notify(object_change_type_t change_type,
			      unsigned int parent_object_handle,
			      unsigned int object_handle,
			      void *object_name_pt, int object_name_len,
			      void *key_name_pt, int key_len,
			      void *key_value_pt, int key_value_len,
			      void *priv_data_pt)
{
	int members[1];
	struct memb_ring_id ring_id;

	memset(&ring_id, 0, sizeof(ring_id))

	/* If the 'quorum.quorate' key changes, then that changes quorum */
	if (strncmp(key_name_pt, "quorate", key_len) == 0) {
		set_quorum(members, 0, atoi(key_value_pt), &ring_id);
	}
}



static int quorum_exec_init_fn (struct corosync_api_v1 *api)
{
	return (0);
}

static void test_init(struct corosync_api_v1 *api,
		      quorum_set_quorate_fn_t report)
{

	unsigned int find_handle;
	unsigned int quorum_handle = 0;

	set_quorum = report;

	/*
	 * Register for objdb changes on quorum { }
	 */
	api->object_find_create(OBJECT_PARENT_HANDLE, "quorum", strlen("quorum"), &find_handle);
        api->object_find_next(find_handle, &quorum_handle);
	api->object_find_destroy(find_handle);

	api->object_track_start(quorum_handle,
				1,
				key_change_notify,
				NULL, // object_create_notify
				NULL, // object_destroy_notify
				NULL, // object_reload_notify
				NULL); // priv_data

}
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to