[ofa-general] [PATCH] opensm/console: Fixed osm_console poll to handle POLLHUP

Nicolas Morey Chaisemartin nicolas.morey-chaisemartin at ext.bull.net
Fri Mar 6 01:17:42 PST 2009


When opensm is called after a pipe to execute a command in the local console, 
it uses 100% CPU as osm_console poll returns (POLLIN) as if there was something to read from stdin where there isn't.

This patch fixes the problem by closing the local console when POLLHUP is received. 
osm_console will return an error code which will unset the console_init_flag so it won't be reopened.
For socket console, cio_close is called to close the current connection but keep the socket open.

Signed-off-by: Nicolas Morey-Chaisemartin <nicolas.morey-chaisemartin at ext.bull.net>
---
 opensm/include/opensm/osm_console.h    |    2 +-
 opensm/include/opensm/osm_console_io.h |    1 +
 opensm/opensm/main.c                   |    6 ++++--
 opensm/opensm/osm_console.c            |   22 ++++++++++++++++++----
 opensm/opensm/osm_console_io.c         |    2 +-
 5 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/opensm/include/opensm/osm_console.h b/opensm/include/opensm/osm_console.h
index 3ea8fa5..dcce1e4 100644
--- a/opensm/include/opensm/osm_console.h
+++ b/opensm/include/opensm/osm_console.h
@@ -46,6 +46,6 @@
 
 BEGIN_C_DECLS
 // TODO replace p_osm
-void osm_console(osm_opensm_t * p_osm);
+int osm_console(osm_opensm_t * p_osm);
 END_C_DECLS
 #endif				/* _OSM_CONSOLE_H_ */
diff --git a/opensm/include/opensm/osm_console_io.h b/opensm/include/opensm/osm_console_io.h
index 5fe233d..f31d811 100644
--- a/opensm/include/opensm/osm_console_io.h
+++ b/opensm/include/opensm/osm_console_io.h
@@ -83,6 +83,7 @@ int is_console_enabled(osm_subn_opt_t *p_opt);
 
 #ifdef ENABLE_OSM_CONSOLE_SOCKET
 int cio_open(osm_console_t * p_oct, int new_fd, osm_log_t * p_log);
+int cio_close(osm_console_t * p_oct);
 int is_authorized(osm_console_t * p_oct);
 #endif
 
diff --git a/opensm/opensm/main.c b/opensm/opensm/main.c
index 2271634..5a39f84 100644
--- a/opensm/opensm/main.c
+++ b/opensm/opensm/main.c
@@ -494,8 +494,10 @@ int osm_manager_loop(osm_subn_opt_t * p_opt, osm_opensm_t * p_osm)
 	   Sit here forever - dwell or do console i/o & cmds
 	 */
 	while (!osm_exit_flag) {
-		if (console_init_flag)
-			osm_console(p_osm);
+		if (console_init_flag){
+			if(osm_console(p_osm))
+				console_init_flag = 0;
+		}
 		else
 			cl_thread_suspend(10000);
 
diff --git a/opensm/opensm/osm_console.c b/opensm/opensm/osm_console.c
index 63c5ea8..04c820c 100644
--- a/opensm/opensm/osm_console.c
+++ b/opensm/opensm/osm_console.c
@@ -1376,7 +1376,7 @@ static void parse_cmd_line(char *line, osm_opensm_t * p_osm)
 	}
 }
 
-void osm_console(osm_opensm_t * p_osm)
+int osm_console(osm_opensm_t * p_osm)
 {
 	struct pollfd pollfd[2];
 	char *p_line;
@@ -1409,7 +1409,7 @@ void osm_console(osm_opensm_t * p_osm)
 	}
 
 	if (poll(fds, nfds, 1000) <= 0)
-		return;
+		return 0;
 
 #ifdef ENABLE_OSM_CONSOLE_SOCKET
 	if (pollfd[0].revents & POLLIN) {
@@ -1422,7 +1422,7 @@ void osm_console(osm_opensm_t * p_osm)
 				"ERR 4B04: Failed to accept console socket: %s\n",
 				strerror(errno));
 			p_oct->in_fd = -1;
-			return;
+			return 0;
 		}
 		if (inet_ntop
 		    (AF_INET, &sin.sin_addr, p_oct->client_ip,
@@ -1444,7 +1444,7 @@ void osm_console(osm_opensm_t * p_osm)
 				p_oct->client_hn, p_oct->client_ip);
 			close(new_fd);
 		}
-		return;
+		return 0;
 	}
 #endif
 
@@ -1462,5 +1462,19 @@ void osm_console(osm_opensm_t * p_osm)
 			osm_console_exit(p_oct, p_log);
 		if (p_line)
 			free(p_line);
+		return 0;
 	}
+	/* input fd is closed (hanged up) */
+	if (pollfd[1].revents & POLLHUP) {
+		/* If we are using a sowket, we close the current connection */
+		if (p_oct->socket >= 0) {
+			cio_close(p_oct);
+			return 0;
+		}
+		/* If we use a local console, stdin is closed (most probable is pipe ended)
+		 * so we close the local console */
+		return -1;
+	}
+
+	return 0;
 }
diff --git a/opensm/opensm/osm_console_io.c b/opensm/opensm/osm_console_io.c
index 3d3ece4..ce867bd 100644
--- a/opensm/opensm/osm_console_io.c
+++ b/opensm/opensm/osm_console_io.c
@@ -94,7 +94,7 @@ int is_console_enabled(osm_subn_opt_t * p_opt)
 
 
 #ifdef ENABLE_OSM_CONSOLE_SOCKET
-static int cio_close(osm_console_t * p_oct)
+int cio_close(osm_console_t * p_oct)
 {
 	int rtnval = -1;
 	if (p_oct && (p_oct->in_fd > 0)) {
-- 
1.6.2-rc2.GIT




More information about the general mailing list