소스 검색

Add support for reload operations within objdb and plugins.

Use a 2 phase "commit" operation:
1) Invoke verifyconfig that should catch the errors before the reload operation
2) Invoke reloadconfig that performs the operation and should _never_ fail

Implementation note: if step 2 fails, there is no fall back at the moment.

Fix the IPC table for confdb:
MESSAGE_REQ_CONFDB_XPATH_EVAL_EXPRESSION = 12 was added to include/ipc_confdb.h
without an associated call. Thanks Chrissie for spotting this.



git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1629 fd59a12c-fef9-0310-b244-a6a79926bd2f
Fabio M. Di Nitto 17 년 전
부모
커밋
010198fac4
12개의 변경된 파일169개의 추가작업 그리고 3개의 파일을 삭제
  1. 1 0
      exec/apidef.c
  2. 2 0
      exec/config.h
  3. 31 0
      exec/objdb.c
  4. 4 0
      exec/objdb.h
  5. 8 0
      include/confdb.h
  6. 3 0
      include/coroapi.h
  7. 14 3
      include/ipc_confdb.h
  8. 52 0
      lib/confdb.c
  9. 14 0
      lib/sa-confdb.c
  10. 1 0
      lib/sa-confdb.h
  11. 30 0
      services/confdb.c
  12. 9 0
      test/testconfdb.c

+ 1 - 0
exec/apidef.c

@@ -124,6 +124,7 @@ void apidef_init (struct objdb_iface_ver0 *objdb) {
 	apidef_corosync_api_v1.object_track_start = objdb->object_track_start;
 	apidef_corosync_api_v1.object_track_start = objdb->object_track_start;
 	apidef_corosync_api_v1.object_track_stop = objdb->object_track_stop;
 	apidef_corosync_api_v1.object_track_stop = objdb->object_track_stop;
 	apidef_corosync_api_v1.object_write_config = objdb->object_write_config;
 	apidef_corosync_api_v1.object_write_config = objdb->object_write_config;
+	apidef_corosync_api_v1.object_reload_config = objdb->object_reload_config;
 }
 }
 
 
 struct corosync_api_v1 *apidef_get (void)
 struct corosync_api_v1 *apidef_get (void)

+ 2 - 0
exec/config.h

@@ -38,6 +38,8 @@
 struct config_iface_ver0 {
 struct config_iface_ver0 {
 	int (*config_readconfig) (struct objdb_iface_ver0 *objdb, char **error_string);
 	int (*config_readconfig) (struct objdb_iface_ver0 *objdb, char **error_string);
 	int (*config_writeconfig) (struct objdb_iface_ver0 *objdb, char **error_string);
 	int (*config_writeconfig) (struct objdb_iface_ver0 *objdb, char **error_string);
+	int (*config_verifyconfig) (struct objdb_iface_ver0 *objdb, char **error_string);
+	int (*config_reloadconfig) (struct objdb_iface_ver0 *objdb, int flush, char **error_string);
 };
 };
 
 
 
 

+ 31 - 0
exec/objdb.c

@@ -1415,6 +1415,36 @@ static int object_write_config(char **error_string)
 	return 0;
 	return 0;
 }
 }
 
 
+static int object_reload_config(int flush, char **error_string)
+{
+	struct config_iface_ver0 **modules;
+	int num_modules;
+	int i;
+	int res;
+
+	main_get_config_modules(&modules, &num_modules);
+
+	/* phase 1. Each module should verify that it can reload the config
+	 * and error out here if possible at all
+	 */
+	for (i=0; i<num_modules; i++) {
+		if (modules[i]->config_verifyconfig) {
+			res = modules[i]->config_verifyconfig(&objdb_iface, error_string);
+			if (res)
+				return res;
+		}
+	}
+	/* phase 2. Do it.. */
+	for (i=0; i<num_modules; i++) {
+		if (modules[i]->config_reloadconfig) {
+			res = modules[i]->config_reloadconfig(&objdb_iface, flush, error_string);
+			if (res)
+				return res;
+		}
+	}
+	return 0;
+}
+
 struct objdb_iface_ver0 objdb_iface = {
 struct objdb_iface_ver0 objdb_iface = {
 	.objdb_init		= objdb_init,
 	.objdb_init		= objdb_init,
 	.object_create		= object_create,
 	.object_create		= object_create,
@@ -1442,6 +1472,7 @@ struct objdb_iface_ver0 objdb_iface = {
 	.object_track_stop	= object_track_stop,
 	.object_track_stop	= object_track_stop,
 	.object_dump	        = object_dump,
 	.object_dump	        = object_dump,
 	.object_write_config    = object_write_config,
 	.object_write_config    = object_write_config,
+	.object_reload_config   = object_reload_config,
 };
 };
 
 
 struct lcr_iface objdb_iface_ver0[1] = {
 struct lcr_iface objdb_iface_ver0[1] = {

+ 4 - 0
exec/objdb.h

@@ -217,6 +217,10 @@ struct objdb_iface_ver0 {
 		void * priv_data_pt);
 		void * priv_data_pt);
 
 
 	int (*object_write_config) (char **error_string);
 	int (*object_write_config) (char **error_string);
+
+	int (*object_reload_config) (
+		int flush,
+		char **error_string);
 };
 };
 
 
 #endif /* OBJDB_H_DEFINED */
 #endif /* OBJDB_H_DEFINED */

+ 8 - 0
include/confdb.h

@@ -130,6 +130,14 @@ confdb_error_t confdb_write (
 	confdb_handle_t handle,
 	confdb_handle_t handle,
 	char *error_text);
 	char *error_text);
 
 
+/*
+ * Reload the configuration
+ */
+confdb_error_t confdb_reload (
+	confdb_handle_t handle,
+	int flush,
+	char *error_text);
+
 /*
 /*
  * Get a file descriptor on which to poll.  confdb_handle_t is NOT a
  * Get a file descriptor on which to poll.  confdb_handle_t is NOT a
  * file descriptor and may not be used directly.
  * file descriptor and may not be used directly.

+ 3 - 0
include/coroapi.h

@@ -278,6 +278,9 @@ struct corosync_api_v1 {
 
 
 	int (*object_write_config) (char **error_string);
 	int (*object_write_config) (char **error_string);
 
 
+	int (*object_reload_config) (int flush,
+				     char **error_string);
+
 	/*
 	/*
 	 * Time and timer APIs
 	 * Time and timer APIs
 	 */
 	 */

+ 14 - 3
include/ipc_confdb.h

@@ -51,8 +51,8 @@ enum req_confdb_types {
 	MESSAGE_REQ_CONFDB_KEY_ITER = 9,
 	MESSAGE_REQ_CONFDB_KEY_ITER = 9,
 	MESSAGE_REQ_CONFDB_TRACK_START = 10,
 	MESSAGE_REQ_CONFDB_TRACK_START = 10,
 	MESSAGE_REQ_CONFDB_TRACK_STOP = 11,
 	MESSAGE_REQ_CONFDB_TRACK_STOP = 11,
-	MESSAGE_REQ_CONFDB_XPATH_EVAL_EXPRESSION = 12,
-	MESSAGE_REQ_CONFDB_WRITE = 13
+	MESSAGE_REQ_CONFDB_WRITE = 12,
+	MESSAGE_REQ_CONFDB_RELOAD = 13
 };
 };
 
 
 enum res_confdb_types {
 enum res_confdb_types {
@@ -71,7 +71,8 @@ enum res_confdb_types {
 	MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK = 12,
 	MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK = 12,
 	MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK = 13,
 	MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK = 13,
 	MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK = 14,
 	MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK = 14,
-	MESSAGE_RES_CONFDB_WRITE = 15
+	MESSAGE_RES_CONFDB_WRITE = 15,
+	MESSAGE_RES_CONFDB_RELOAD = 16
 };
 };
 
 
 
 
@@ -177,6 +178,16 @@ struct res_lib_confdb_write {
 	mar_name_t error __attribute__((aligned(8)));
 	mar_name_t error __attribute__((aligned(8)));
 };
 };
 
 
+struct req_lib_confdb_reload {
+	mar_res_header_t header __attribute__((aligned(8)));
+	mar_int32_t flush __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_reload {
+	mar_res_header_t header __attribute__((aligned(8)));
+	mar_name_t error __attribute__((aligned(8)));
+};
+
 struct res_lib_confdb_key_change_callback {
 struct res_lib_confdb_key_change_callback {
 	mar_res_header_t header __attribute__((aligned(8)));
 	mar_res_header_t header __attribute__((aligned(8)));
 	mar_uint32_t change_type __attribute__((aligned(8)));
 	mar_uint32_t change_type __attribute__((aligned(8)));

+ 52 - 0
lib/confdb.c

@@ -1219,6 +1219,58 @@ error_exit:
 	return (error);
 	return (error);
 }
 }
 
 
+confdb_error_t confdb_reload (
+	confdb_handle_t handle,
+	int flush,
+	char *error_text)
+{
+	confdb_error_t error;
+	struct confdb_inst *confdb_inst;
+	struct iovec iov[2];
+	struct res_lib_confdb_reload res_lib_confdb_reload;
+	struct req_lib_confdb_reload req_lib_confdb_reload;
+
+	error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+	if (error != SA_AIS_OK) {
+		return (error);
+	}
+
+	if (confdb_inst->standalone) {
+		error = SA_AIS_OK;
+
+		if (confdb_sa_reload(flush, error_text))
+			error = SA_AIS_ERR_ACCESS;
+		goto error_exit;
+	}
+
+	req_lib_confdb_reload.header.size = sizeof (req_lib_confdb_reload);
+	req_lib_confdb_reload.header.id = MESSAGE_REQ_CONFDB_RELOAD;
+	req_lib_confdb_reload.flush = flush;
+
+	iov[0].iov_base = (char *)&req_lib_confdb_reload;
+	iov[0].iov_len = sizeof (req_lib_confdb_reload);
+
+	pthread_mutex_lock (&confdb_inst->response_mutex);
+
+	error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+				       &res_lib_confdb_reload, sizeof (struct res_lib_confdb_reload));
+
+	pthread_mutex_unlock (&confdb_inst->response_mutex);
+
+	if (error != SA_AIS_OK) {
+		goto error_exit;
+	}
+
+	error = res_lib_confdb_reload.header.error;
+	if(res_lib_confdb_reload.error.length)
+		memcpy(error_text, res_lib_confdb_reload.error.value, res_lib_confdb_reload.error.length);
+
+error_exit:
+	saHandleInstancePut (&confdb_handle_t_db, handle);
+
+	return (error);
+}
+
 confdb_error_t confdb_track_changes (
 confdb_error_t confdb_track_changes (
 	confdb_handle_t handle,
 	confdb_handle_t handle,
 	unsigned int object_handle,
 	unsigned int object_handle,

+ 14 - 0
lib/sa-confdb.c

@@ -296,6 +296,20 @@ int confdb_sa_write (
 	return ret;
 	return ret;
 }
 }
 
 
+int confdb_sa_reload (
+	unsigned int parent_object_handle,
+	int flush,
+	char *error_text)
+{
+	char *errtext;
+	int ret;
+
+	ret = objdb->object_reload_config(flush, &errtext);
+	if (!ret)
+		strcpy(error_text, errtext);
+
+	return ret;
+}
 
 
 int confdb_sa_object_iter (
 int confdb_sa_object_iter (
 	unsigned int parent_object_handle,
 	unsigned int parent_object_handle,

+ 1 - 0
lib/sa-confdb.h

@@ -44,3 +44,4 @@ extern int confdb_sa_object_find(unsigned int parent_object_handle, unsigned int
 extern int confdb_sa_object_iter(unsigned int parent_object_handle, unsigned int start_pos, unsigned int *object_handle, void *object_name, int *object_name_len);
 extern int confdb_sa_object_iter(unsigned int parent_object_handle, unsigned int start_pos, unsigned int *object_handle, void *object_name, int *object_name_len);
 extern int confdb_sa_key_iter(unsigned int parent_object_handle, unsigned int start_pos, void *key_name, int *key_name_len, void *value, int *value_len);
 extern int confdb_sa_key_iter(unsigned int parent_object_handle, unsigned int start_pos, void *key_name, int *key_name_len, void *value, int *value_len);
 extern int confdb_sa_write(char *error_text);
 extern int confdb_sa_write(char *error_text);
+extern int confdb_sa_reload(int flush, char *error_text);

+ 30 - 0
services/confdb.c

@@ -70,6 +70,7 @@ static void message_handler_req_lib_confdb_object_find (void *conn, void *messag
 
 
 static void message_handler_req_lib_confdb_object_parent_get (void *conn, void *message);
 static void message_handler_req_lib_confdb_object_parent_get (void *conn, void *message);
 static void message_handler_req_lib_confdb_write (void *conn, void *message);
 static void message_handler_req_lib_confdb_write (void *conn, void *message);
+static void message_handler_req_lib_confdb_reload (void *conn, void *message);
 
 
 static void message_handler_req_lib_confdb_track_start (void *conn, void *message);
 static void message_handler_req_lib_confdb_track_start (void *conn, void *message);
 static void message_handler_req_lib_confdb_track_stop (void *conn, void *message);
 static void message_handler_req_lib_confdb_track_stop (void *conn, void *message);
@@ -172,6 +173,12 @@ static struct corosync_lib_handler confdb_lib_engine[] =
 		.response_id				= MESSAGE_RES_CONFDB_WRITE,
 		.response_id				= MESSAGE_RES_CONFDB_WRITE,
 		.flow_control				= COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
 		.flow_control				= COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
 	},
 	},
+	{ /* 13 */
+		.lib_handler_fn				= message_handler_req_lib_confdb_reload,
+		.response_size				= sizeof (struct res_lib_confdb_reload),
+		.response_id				= MESSAGE_RES_CONFDB_RELOAD,
+		.flow_control				= COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+	},
 };
 };
 
 
 
 
@@ -488,6 +495,29 @@ static void message_handler_req_lib_confdb_write (void *conn, void *message)
 	api->ipc_conn_send_response(conn, &res_lib_confdb_write, sizeof(res_lib_confdb_write));
 	api->ipc_conn_send_response(conn, &res_lib_confdb_write, sizeof(res_lib_confdb_write));
 }
 }
 
 
+static void message_handler_req_lib_confdb_reload (void *conn, void *message)
+{
+	struct req_lib_confdb_reload *req_lib_confdb_reload = (struct req_lib_confdb_reload *)message;
+	struct res_lib_confdb_reload res_lib_confdb_reload;
+	int ret = SA_AIS_OK;
+	char *error_string = NULL;
+
+	if (api->object_reload_config(req_lib_confdb_reload->flush, &error_string))
+		ret = SA_AIS_ERR_ACCESS;
+
+	res_lib_confdb_reload.header.size = sizeof(res_lib_confdb_reload);
+	res_lib_confdb_reload.header.id = MESSAGE_RES_CONFDB_RELOAD;
+	res_lib_confdb_reload.header.error = ret;
+
+	if(error_string) {
+		strcpy((char *)res_lib_confdb_reload.error.value, error_string);
+		res_lib_confdb_reload.error.length = strlen(error_string) + 1;
+	} else
+		res_lib_confdb_reload.error.length = 0;
+
+	api->ipc_conn_send_response(conn, &res_lib_confdb_reload, sizeof(res_lib_confdb_reload));
+}
+
 static void confdb_notify_lib_of_key_change(object_change_type_t change_type,
 static void confdb_notify_lib_of_key_change(object_change_type_t change_type,
 											  unsigned int parent_object_handle,
 											  unsigned int parent_object_handle,
 											  unsigned int object_handle,
 											  unsigned int object_handle,

+ 9 - 0
test/testconfdb.c

@@ -178,6 +178,15 @@ int main (int argc, char *argv[]) {
 	if (argv[1] && strcmp(argv[1], "write")==0)
 	if (argv[1] && strcmp(argv[1], "write")==0)
 		do_write_tests(handle);
 		do_write_tests(handle);
 
 
+	if (argv[1] && strcmp(argv[1], "reload")==0) {
+		/* Test reload interface */
+		result = confdb_reload(handle, 0, key_value);
+		printf ("Try to reload the config (noflush): %d (should be 1)\n", result);
+
+		result = confdb_reload(handle, 1, key_value);
+		printf ("Try to reload the config (flush): %d (should be 1)\n", result);
+	}
+
 	/* Test iterators */
 	/* Test iterators */
 	print_config_tree(handle, OBJECT_PARENT_HANDLE, 0);
 	print_config_tree(handle, OBJECT_PARENT_HANDLE, 0);