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

Clean up usage of ais_done. This includes passing a
value for each done type. Also, libais_disconnect cleaned up
so it doesn't ais_done when its queues are full. Instead it
disconnects the library connection. A new connection state
variable added to the conn_info structure in place of active.

(Logical change 1.58)


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

Steven Dake 21 лет назад
Родитель
Сommit
e325206977
1 измененных файлов с 79 добавлено и 26 удалено
  1. 79 26
      exec/main.c

+ 79 - 26
exec/main.c

@@ -92,7 +92,20 @@ struct service_handler *ais_service_handlers[] = {
 
 
 static int poll_handler_libais_deliver (poll_handle handle, int fd, int revent, void *data, unsigned int *prio);
 static int poll_handler_libais_deliver (poll_handle handle, int fd, int revent, void *data, unsigned int *prio);
 
 
-static inline void ais_done (int err)
+enum e_ais_done {
+	AIS_DONE_EXIT = -1,
+	AIS_DONE_UID_DETERMINE = -2,
+	AIS_DONE_GID_DETERMINE = -3,
+	AIS_DONE_MEMPOOL_INIT = -4,
+	AIS_DONE_FORK = -5,
+	AIS_DONE_LIBAIS_SOCKET = -6,
+	AIS_DONE_LIBAIS_BIND = -7,
+	AIS_DONE_READKEY = -8,
+	AIS_DONE_READNETWORK = -9,
+	AIS_DONE_READGROUPS = -10,
+};
+
+static inline void ais_done (enum e_ais_done err)
 {
 {
 	log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting.\n");
 	log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting.\n");
 	exit (1);
 	exit (1);
@@ -121,7 +134,7 @@ static inline struct conn_info *conn_info_create (int fd) {
 		return (0);
 		return (0);
 	}
 	}
 	
 	
-	conn_info->active = 1;
+	conn_info->state = CONN_STATE_ACTIVE;
 	conn_info->fd = fd;
 	conn_info->fd = fd;
 	conn_info->service = SOCKET_SERVICE_INIT;
 	conn_info->service = SOCKET_SERVICE_INIT;
 	return (conn_info);
 	return (conn_info);
@@ -133,9 +146,20 @@ struct sockaddr_in this_ip;
 
 
 char *socketname = "libais.socket";
 char *socketname = "libais.socket";
 
 
+static int libais_connection_active (struct conn_info *conn_info)
+{
+	return (conn_info->state == CONN_STATE_ACTIVE);
+}
+
+static void libais_disconnect_delayed (struct conn_info *conn_info)
+{
+	conn_info->state = CONN_STATE_DISCONNECTING_DELAYED;
+}
+
 static int libais_disconnect (struct conn_info *conn_info)
 static int libais_disconnect (struct conn_info *conn_info)
 {
 {
 	int res = 0;
 	int res = 0;
+	struct outq_item *outq_item;
 
 
 	if (ais_service_handlers[conn_info->service - 1]->libais_exit_fn) {
 	if (ais_service_handlers[conn_info->service - 1]->libais_exit_fn) {
 		res = ais_service_handlers[conn_info->service - 1]->libais_exit_fn (conn_info);
 		res = ais_service_handlers[conn_info->service - 1]->libais_exit_fn (conn_info);
@@ -145,11 +169,21 @@ static int libais_disconnect (struct conn_info *conn_info)
 	 * Close the library connection and free its
 	 * Close the library connection and free its
 	 * data if it hasn't already been freed
 	 * data if it hasn't already been freed
 	 */
 	 */
-	if (conn_info->inb) {
+	if (conn_info->state != CONN_STATE_DISCONNECTING) {
+		conn_info->state = CONN_STATE_DISCONNECTING;
+
 		close (conn_info->fd);
 		close (conn_info->fd);
+		/*
+		 * Free the outq queued items
+		 */
+		while (!queue_is_empty (&conn_info->outq)) {
+			outq_item = queue_item_get (&conn_info->outq);
+			mempool_free (outq_item->msg);
+			queue_item_remove (&conn_info->outq);
+		}
+
 		queue_free (&conn_info->outq);
 		queue_free (&conn_info->outq);
 		free (conn_info->inb);
 		free (conn_info->inb);
-		conn_info->inb = 0;
 	}
 	}
 
 
 	/*
 	/*
@@ -171,13 +205,16 @@ extern int libais_send_response (struct conn_info *conn_info,
 {
 {
 	struct queue *outq;
 	struct queue *outq;
 	char *cmsg;
 	char *cmsg;
-	int res;
+	int res = 0;
 	int queue_empty;
 	int queue_empty;
 	struct outq_item *queue_item;
 	struct outq_item *queue_item;
 	struct outq_item queue_item_out;
 	struct outq_item queue_item_out;
 	struct msghdr msg_send;
 	struct msghdr msg_send;
 	struct iovec iov_send;
 	struct iovec iov_send;
 
 
+	if (!libais_connection_active (conn_info)) {
+		return (-1);
+	}
 	outq = &conn_info->outq;
 	outq = &conn_info->outq;
 
 
 	msg_send.msg_iov = &iov_send;
 	msg_send.msg_iov = &iov_send;
@@ -189,8 +226,13 @@ extern int libais_send_response (struct conn_info *conn_info,
 	msg_send.msg_flags = 0;
 	msg_send.msg_flags = 0;
 
 
 	if (queue_is_full (outq)) {
 	if (queue_is_full (outq)) {
-		log_printf (LOG_LEVEL_ERROR, "queue is full.\n");
-		ais_done (1);
+		/*
+		 * Start a disconnect if we have not already started one
+		 * and report that the outgoing queue is full
+		 */
+		log_printf (LOG_LEVEL_ERROR, "Library queue is full, disconnecting library connection.\n");
+		libais_disconnect_delayed (conn_info);
+		return (-1);
 	}
 	}
 	while (!queue_is_empty (outq)) {
 	while (!queue_is_empty (outq)) {
 		queue_item = queue_item_get (outq);
 		queue_item = queue_item_get (outq);
@@ -203,7 +245,7 @@ retry_sendmsg:
 			goto retry_sendmsg;
 			goto retry_sendmsg;
 		}
 		}
 		if (res == -1 && errno == EAGAIN) {
 		if (res == -1 && errno == EAGAIN) {
-			break; /* outgoing kernel queue full, ais_done while not empty */
+			break; /* outgoing kernel queue full */
 		}
 		}
 		if (res == -1) {
 		if (res == -1) {
 			return (-1); /* message couldn't be sent */
 			return (-1); /* message couldn't be sent */
@@ -217,7 +259,6 @@ retry_sendmsg:
 		mempool_free (queue_item->msg);
 		mempool_free (queue_item->msg);
 	} /* while queue not empty */
 	} /* while queue not empty */
 
 
-	res = 0;
 	queue_empty = queue_is_empty (outq);
 	queue_empty = queue_is_empty (outq);
 	/*
 	/*
 	 * Send requested message
 	 * Send requested message
@@ -241,7 +282,9 @@ retry_sendmsg_two:
 	if (res == -1)  {
 	if (res == -1)  {
 		cmsg = mempool_malloc (mlen);
 		cmsg = mempool_malloc (mlen);
 		if (cmsg == 0) {
 		if (cmsg == 0) {
-			ais_done (1);
+			log_printf (LOG_LEVEL_ERROR, "Library queue couldn't allocate a message, disconnecting library connection.\n");
+			libais_disconnect_delayed (conn_info);
+			return (-1);
 		}
 		}
 		queue_item_out.msg = cmsg;
 		queue_item_out.msg = cmsg;
 		queue_item_out.mlen = mlen;
 		queue_item_out.mlen = mlen;
@@ -328,6 +371,14 @@ static int poll_handler_libais_deliver (poll_handle handle, int fd, int revent,
 	msg_recv.msg_namelen = 0;
 	msg_recv.msg_namelen = 0;
 	msg_recv.msg_flags = 0;
 	msg_recv.msg_flags = 0;
 
 
+	/*
+	 * Handle delayed disconnections
+	 */
+	if (conn_info->state != CONN_STATE_ACTIVE) {
+		res = libais_disconnect (conn_info);
+		return (res);
+	}
+
 	if (conn_info->authenticated) {
 	if (conn_info->authenticated) {
 		msg_recv.msg_control = 0;
 		msg_recv.msg_control = 0;
 		msg_recv.msg_controllen = 0;
 		msg_recv.msg_controllen = 0;
@@ -348,10 +399,12 @@ retry_recv:
 		goto retry_recv;
 		goto retry_recv;
 	} else
 	} else
 	if (res == -1) {
 	if (res == -1) {
-		goto error_exit;
+printf ("res-1 errno = %d\n", errno);
+		goto error_disconnect;
 	} else
 	} else
 	if (res == 0) {
 	if (res == 0) {
-		goto error_exit;
+printf ("Res0 errno = %d\n", errno);
+		goto error_disconnect;
 		return (-1);
 		return (-1);
 	}
 	}
 
 
@@ -403,7 +456,7 @@ retry_recv:
 				log_printf (LOG_LEVEL_SECURITY, "Invalid header id is %d min 0 max %d\n",
 				log_printf (LOG_LEVEL_SECURITY, "Invalid header id is %d min 0 max %d\n",
 				header->id, ais_service_handlers[service - 1]->libais_handlers_count);
 				header->id, ais_service_handlers[service - 1]->libais_handlers_count);
 				res = -1;
 				res = -1;
-				goto error_exit;
+				goto error_disconnect;
 			}
 			}
 
 
 			/*
 			/*
@@ -449,7 +502,7 @@ retry_recv:
 	
 	
 	return (res);
 	return (res);
 
 
-error_exit:
+error_disconnect:
 	res = libais_disconnect (conn_info);
 	res = libais_disconnect (conn_info);
 	return (res);
 	return (res);
 }
 }
@@ -474,7 +527,7 @@ void sigintr_handler (int signum)
 #endif
 #endif
 
 
 	print_stats ();
 	print_stats ();
-	ais_done (0);
+	ais_done (AIS_DONE_EXIT);
 }
 }
 
 
 static struct sched_param sched_param = { 
 static struct sched_param sched_param = { 
@@ -560,7 +613,7 @@ static void aisexec_uid_determine (void)
 	passwd = getpwnam("ais");
 	passwd = getpwnam("ais");
 	if (passwd == 0) {
 	if (passwd == 0) {
 		log_printf (LOG_LEVEL_ERROR, "ERROR: The 'ais' user is not found in /etc/passwd, please read the documentation.\n");
 		log_printf (LOG_LEVEL_ERROR, "ERROR: The 'ais' user is not found in /etc/passwd, please read the documentation.\n");
-		ais_done (-1);
+		ais_done (AIS_DONE_UID_DETERMINE);
 	}
 	}
 	ais_uid = passwd->pw_uid;
 	ais_uid = passwd->pw_uid;
 }
 }
@@ -571,7 +624,7 @@ static void aisexec_gid_determine (void)
 	group = getgrnam ("ais");
 	group = getgrnam ("ais");
 	if (group == 0) {
 	if (group == 0) {
 		log_printf (LOG_LEVEL_ERROR, "ERROR: The 'ais' group is not found in /etc/group, please read the documentation.\n");
 		log_printf (LOG_LEVEL_ERROR, "ERROR: The 'ais' group is not found in /etc/group, please read the documentation.\n");
-		ais_done (-1);
+		ais_done (AIS_DONE_GID_DETERMINE);
 	}
 	}
 	gid_valid = group->gr_gid;
 	gid_valid = group->gr_gid;
 }
 }
@@ -589,7 +642,7 @@ static void aisexec_mempool_init (void)
 	res = mempool_init (pool_sizes);
 	res = mempool_init (pool_sizes);
 	if (res == ENOMEM) {
 	if (res == ENOMEM) {
 		log_printf (LOG_LEVEL_ERROR, "Couldn't allocate memory pools, not enough memory");
 		log_printf (LOG_LEVEL_ERROR, "Couldn't allocate memory pools, not enough memory");
-		ais_done (1);
+		ais_done (AIS_DONE_MEMPOOL_INIT);
 	}
 	}
 }
 }
 
 
@@ -602,7 +655,7 @@ static void aisexec_tty_detach (void)
 	 */
 	 */
 	switch (fork ()) {
 	switch (fork ()) {
 		case -1:
 		case -1:
-			ais_done (1);
+			ais_done (AIS_DONE_FORK);
 			break;
 			break;
 		case 0:
 		case 0:
 			/*
 			/*
@@ -642,7 +695,7 @@ static void aisexec_libais_bind (int *server_fd)
 	libais_server_fd = socket (PF_UNIX, SOCK_STREAM, 0);
 	libais_server_fd = socket (PF_UNIX, SOCK_STREAM, 0);
 	if (libais_server_fd == -1) {
 	if (libais_server_fd == -1) {
 		log_printf (LOG_LEVEL_ERROR ,"Cannot create libais client connections socket.\n");
 		log_printf (LOG_LEVEL_ERROR ,"Cannot create libais client connections socket.\n");
-		ais_done (1);
+		ais_done (AIS_DONE_LIBAIS_SOCKET);
 	};
 	};
 
 
 	memset (&un_addr, 0, sizeof (struct sockaddr_un));
 	memset (&un_addr, 0, sizeof (struct sockaddr_un));
@@ -652,7 +705,7 @@ static void aisexec_libais_bind (int *server_fd)
 	res = bind (libais_server_fd, (struct sockaddr *)&un_addr, sizeof (struct sockaddr_un));
 	res = bind (libais_server_fd, (struct sockaddr *)&un_addr, sizeof (struct sockaddr_un));
 	if (res) {
 	if (res) {
 		log_printf (LOG_LEVEL_ERROR, "ERROR: Could not bind AF_UNIX: %s.\n", strerror (errno));
 		log_printf (LOG_LEVEL_ERROR, "ERROR: Could not bind AF_UNIX: %s.\n", strerror (errno));
-		ais_done (1);
+		ais_done (AIS_DONE_LIBAIS_BIND);
 	}
 	}
 	listen (libais_server_fd, SERVER_BACKLOG);
 	listen (libais_server_fd, SERVER_BACKLOG);
 
 
@@ -688,16 +741,16 @@ void aisexec_keyread (unsigned char *key)
 	fd = open ("/etc/ais/authkey", O_RDONLY);
 	fd = open ("/etc/ais/authkey", O_RDONLY);
 	if (fd == -1) {
 	if (fd == -1) {
 		log_printf (LOG_LEVEL_ERROR, "Could not open /etc/ais/authkey: %s\n", strerror (errno));
 		log_printf (LOG_LEVEL_ERROR, "Could not open /etc/ais/authkey: %s\n", strerror (errno));
-		ais_done (1);
+		ais_done (AIS_DONE_READKEY);
 	}
 	}
 	res = read (fd, key, 128);
 	res = read (fd, key, 128);
 	if (res == -1) {
 	if (res == -1) {
 		log_printf (LOG_LEVEL_ERROR, "Could not read /etc/ais/authkey: %s\n", strerror (errno));
 		log_printf (LOG_LEVEL_ERROR, "Could not read /etc/ais/authkey: %s\n", strerror (errno));
-		ais_done (1);
+		ais_done (AIS_DONE_READKEY);
 	}
 	}
 	if (res != 128) {
 	if (res != 128) {
 		log_printf (LOG_LEVEL_ERROR, "Could only read %d bits of 1024 bits from /etc/ais/authkey.\n", res * 8);
 		log_printf (LOG_LEVEL_ERROR, "Could only read %d bits of 1024 bits from /etc/ais/authkey.\n", res * 8);
-		ais_done (1);
+		ais_done (AIS_DONE_READKEY);
 	}
 	}
 
 
 	close (fd);
 	close (fd);
@@ -736,7 +789,7 @@ int main (int argc, char **argv)
 	res = amfReadNetwork (&error_string, &sockaddr_in_mcast, &sockaddr_in_bindnet);
 	res = amfReadNetwork (&error_string, &sockaddr_in_mcast, &sockaddr_in_bindnet);
 	if (res == -1) {
 	if (res == -1) {
 		log_printf (LOG_LEVEL_ERROR, error_string);
 		log_printf (LOG_LEVEL_ERROR, error_string);
-		ais_done (1);
+		ais_done (AIS_DONE_READNETWORK);
 	}
 	}
 
 
 	/*
 	/*
@@ -775,7 +828,7 @@ int main (int argc, char **argv)
 	res = amfReadGroups(&error_string);
 	res = amfReadGroups(&error_string);
 	if (res == -1) {
 	if (res == -1) {
 		log_printf (LOG_LEVEL_ERROR, error_string);
 		log_printf (LOG_LEVEL_ERROR, error_string);
-		ais_done (1);
+		ais_done (AIS_DONE_READGROUPS);
 	}
 	}
 	
 	
 	aisexec_tty_detach ();
 	aisexec_tty_detach ();