فهرست منبع

Patch to allow controlled exit of a service.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@1537 fd59a12c-fef9-0310-b244-a6a79926bd2f
Steven Dake 18 سال پیش
والد
کامیت
daaa6eeab0
2فایلهای تغییر یافته به همراه132 افزوده شده و 42 حذف شده
  1. 54 19
      exec/main.c
  2. 78 23
      exec/service.c

+ 54 - 19
exec/main.c

@@ -107,6 +107,8 @@ static int num_config_modules;
 
 static struct config_iface_ver0 *config_modules[MAX_DYNAMIC_SERVICES];
 
+static struct objdb_iface_ver0 *objdb = NULL;
+
 SaClmClusterNodeT *(*main_clm_get_by_nodeid) (unsigned int node_id);
 
 static void sigusr2_handler (int num)
@@ -120,6 +122,50 @@ static void sigusr2_handler (int num)
 	}
 }
 
+static void *aisexec_exit (void *arg)
+{
+	if(objdb) {
+		openais_service_unlink_all (objdb);
+	}
+
+#ifdef DEBUG_MEMPOOL
+	int stats_inuse[MEMPOOL_GROUP_SIZE];
+	int stats_avail[MEMPOOL_GROUP_SIZE];
+	int stats_memoryused[MEMPOOL_GROUP_SIZE];
+	int i;
+
+	mempool_getstats (stats_inuse, stats_avail, stats_memoryused);
+	log_printf (LOG_LEVEL_DEBUG, "Memory pools:\n");
+	for (i = 0; i < MEMPOOL_GROUP_SIZE; i++) {
+	log_printf (LOG_LEVEL_DEBUG, "order %d size %d inuse %d avail %d memory used %d\n",
+		i, 1<<i, stats_inuse[i], stats_avail[i], stats_memoryused[i]);
+	}
+#endif
+
+	totempg_finalize ();
+	logsys_flush ();
+
+	openais_exit_error (AIS_DONE_EXIT);
+
+	/* never reached */
+	return NULL;
+}
+
+pthread_t aisexec_exit_thread;
+static void init_shutdown(void *data) 
+{
+	pthread_create (&aisexec_exit_thread, NULL, aisexec_exit, NULL);
+}
+
+
+static poll_timer_handle shutdown_handle;
+static void sigquit_handler (int num)
+{
+	/* avoid creating threads from within the interrupt context */
+	poll_timer_add (aisexec_poll_handle, 500, NULL, init_shutdown, &shutdown_handle);
+}
+
+
 static void sigsegv_handler (int num)
 {
 	signal (SIGSEGV, SIG_DFL);
@@ -145,23 +191,7 @@ struct totempg_group openais_group = {
 
 void sigintr_handler (int signum)
 {
-
-#ifdef DEBUG_MEMPOOL
-	int stats_inuse[MEMPOOL_GROUP_SIZE];
-	int stats_avail[MEMPOOL_GROUP_SIZE];
-	int stats_memoryused[MEMPOOL_GROUP_SIZE];
-	int i;
-
-	mempool_getstats (stats_inuse, stats_avail, stats_memoryused);
-	log_printf (LOG_LEVEL_DEBUG, "Memory pools:\n");
-	for (i = 0; i < MEMPOOL_GROUP_SIZE; i++) {
-	log_printf (LOG_LEVEL_DEBUG, "order %d size %d inuse %d avail %d memory used %d\n",
-		i, 1<<i, stats_inuse[i], stats_avail[i], stats_memoryused[i]);
-	}
-#endif
-
-	totempg_finalize ();
-	openais_exit_error (AIS_DONE_EXIT);
+	poll_timer_add (aisexec_poll_handle, 500, NULL, init_shutdown, &shutdown_handle);
 }
 
 
@@ -290,6 +320,7 @@ static void aisexec_tty_detach (void)
 	/*
 	 * Disconnect from TTY if this is not a debug run
 	 */
+
 	switch (fork ()) {
 		case -1:
 			openais_exit_error (AIS_DONE_FORK);
@@ -298,6 +329,10 @@ static void aisexec_tty_detach (void)
 			/*
 			 * child which is disconnected, run this process
 			 */
+/* 			setset(); */
+			close (0);
+			close (1);
+			close (2);
 			break;
 		default:
 			exit (0);
@@ -436,7 +471,6 @@ int main (int argc, char **argv)
 	unsigned int objdb_handle;
 	unsigned int config_handle;
 	unsigned int config_version = 0;
-	struct objdb_iface_ver0 *objdb;
 	void *objdb_p;
 	struct config_iface_ver0 *config;
 	void *config_p;
@@ -481,7 +515,8 @@ int main (int argc, char **argv)
 	signal (SIGUSR2, sigusr2_handler);
 	signal (SIGSEGV, sigsegv_handler);
 	signal (SIGABRT, sigabrt_handler);
-
+	signal (SIGQUIT, sigquit_handler);
+	
 	openais_timer_init (
 		serialize_mutex_lock,
 		serialize_mutex_unlock);

+ 78 - 23
exec/service.c

@@ -93,6 +93,10 @@ static struct default_service default_services[] = {
 	{
 		.name			 = "openais_confdb",
 		.ver			 = 0,
+	},
+	{
+		.name			 = "lha_crm",
+		.ver			 = 0,
 	}
 };
 
@@ -208,17 +212,47 @@ unsigned int openais_service_link_and_init (
 	return (res);
 }
 
+static int openais_service_unlink_common(
+	struct objdb_iface_ver0 *objdb,
+	unsigned int object_service_handle,
+	const char *service_name,
+	unsigned int service_version) 
+{
+	unsigned int res;
+	unsigned short *service_id;
+	unsigned int *found_service_handle;
+	res = objdb->object_key_get (object_service_handle,
+				     "handle",
+				     strlen ("handle"),
+				     (void *)&found_service_handle,
+				     NULL);
+	
+	res = objdb->object_key_get (object_service_handle,
+				     "service_id",
+				     strlen ("service_id"),
+				     (void *)&service_id,
+				     NULL);
+	
+	log_printf(LOG_LEVEL_NOTICE, "Unloading openais component: %s v%u\n",
+		   service_name, service_version);
+	
+	if (ais_service[*service_id]->exec_exit_fn) {
+		ais_service[*service_id]->exec_exit_fn (objdb);
+	}
+	ais_service[*service_id] = NULL;
+    
+	return lcr_ifact_release (*found_service_handle);	
+}
+
 extern unsigned int openais_service_unlink_and_exit (
 	struct objdb_iface_ver0 *objdb,
 	char *service_name,
 	unsigned int service_ver)
 {
+	unsigned int res;
 	unsigned int object_service_handle;
 	char *found_service_name;
 	unsigned int *found_service_ver;
-	unsigned int *found_service_handle;
-	unsigned short *service_id;
-	unsigned int res;
 
 	objdb->object_find_reset (OBJECT_PARENT_HANDLE);
 	while (objdb->object_find (
@@ -244,32 +278,53 @@ extern unsigned int openais_service_unlink_and_exit (
 		 */
 		if ((strcmp (service_name, found_service_name) == 0) &&
 			(service_ver == *found_service_ver)) {
-
-			res = objdb->object_key_get (object_service_handle,
-				"handle",
-				strlen ("handle"),
-				(void *)&found_service_handle,
-				NULL);
-
-			res = objdb->object_key_get (object_service_handle,
-				"service_id",
-				strlen ("service_id"),
-				(void *)&service_id,
-				NULL);
-					
-			if (ais_service[*service_id]->exec_exit_fn) {
-				ais_service[*service_id]->exec_exit_fn (objdb);
-			}
-			ais_service[*service_id] = NULL;
-
-			res = lcr_ifact_release (*found_service_handle);	
+			res = openais_service_unlink_common(
+			    objdb, object_service_handle, service_name, service_ver);
 			objdb->object_destroy (object_service_handle);
-			return (res);
+			return res;
 		}
 	}
 	return (-1);
 }
 
+extern unsigned int openais_service_unlink_all (
+	struct objdb_iface_ver0 *objdb)
+{
+	char *service_name;
+	unsigned int *service_ver;
+	unsigned int object_service_handle;
+
+	log_printf(LOG_LEVEL_NOTICE, "Unloading all openais components\n");
+	
+	objdb->object_find_reset (OBJECT_PARENT_HANDLE);
+	while (objdb->object_find (OBJECT_PARENT_HANDLE,
+				   "service",
+				   strlen ("service"),
+				   &object_service_handle) == 0) {
+		
+		objdb->object_key_get (object_service_handle,
+			"name",
+			strlen ("name"),
+			(void *)&service_name,
+			NULL);
+
+		objdb->object_key_get (object_service_handle,
+			"ver",
+			strlen ("ver"),
+			(void *)&service_ver,
+			NULL);
+				
+		openais_service_unlink_common(
+			objdb, object_service_handle, service_name, *service_ver);
+
+		objdb->object_destroy (object_service_handle);
+		log_printf(LOG_LEVEL_NOTICE, "%s was unlinked\n", service_name);
+		logsys_flush ();
+	}
+
+	return (0);
+}
+
 /*
  * Links default services into the executive
  */