[openib-general] [PATCH] opensm: fixes in signal handling

Sasha Khapyorsky sashak at voltaire.com
Tue Feb 21 15:33:00 PST 2006


Hello,

There are fixes for broken signal handling stuff. Finally this should
prevent some opensm crashes (actually deadlocks), for instance caused
by such command:

  while [ 1 ] ; do kill -HUP <opensm-pid> ; done


Yael, I hope this patch does not broke windows compilations (this masks
signal related functions under __WIN__), but cannot be absolutely sure -
please look at this from "under windows" point of view. Thanks.

Sasha.


This fixes broken signal handling. In this patch:

 - signal handling stuff is moved to main.c
 - cl_sig_* is replaced by more powerfull posix (I hope it should not
   be bad for win because this is under !__WIN__ anyway)
 - signal handler does not call resweeper or wakeup directly, but only
   update new osm_hup_flag (or osm_exit_flag on SIGINT or SIGTERM)
 - signal delivery are masked in all threads expept first one, so only
   expected thread will be interrupted (from sleep() or poll())
 - resweep thread will be wakeuped from main.c thread instead direct
 - poll was added to osm_console - this provides timeout ability and
   workarouds getline()'s signal interruption problem.


diff --git a/osm/include/opensm/osm_console.h b/osm/include/opensm/osm_console.h
index 5a4036f..c5cd22a 100644
--- a/osm/include/opensm/osm_console.h
+++ b/osm/include/opensm/osm_console.h
@@ -50,6 +50,7 @@
 BEGIN_C_DECLS
 
 void osm_console(osm_opensm_t *p_osm);
+void osm_console_prompt(void);
 
 END_C_DECLS
 
diff --git a/osm/include/opensm/osm_opensm.h b/osm/include/opensm/osm_opensm.h
index 833c4c3..3235ad4 100644
--- a/osm/include/opensm/osm_opensm.h
+++ b/osm/include/opensm/osm_opensm.h
@@ -388,38 +388,12 @@ osm_opensm_wait_for_subnet_up(
 
 /****v* OpenSM/osm_exit_flag 
 */
-extern volatile int osm_exit_flag;
+extern volatile unsigned int osm_exit_flag;
 /* 
 * DESCRIPTION 
 *  Set to one to cause all threads to leave 
 *********/
 
-#ifndef __WIN__
-/****f* OpenSM: OpenSM/osm_reg_sig_handler
-* NAME
-*	 osm_reg_sig_handler
-*
-* DESCRIPTION
-*	Registers the common signal handler
-*
-* SYNOPSIS
-*/
-void osm_reg_sig_handler(
-IN osm_opensm_t* const p_osm);
-/*
-* PARAMETERS
-*	p_osm
-*		[in] Pointer to a OpenSM object to handle signals on.
-*
-* RETURN VALUES
-*	None
-*
-* NOTES
-*
-* SEE ALSO
-*********/
-#endif /* __WIN__ */
-
 END_C_DECLS
 
 #endif	/* _OSM_OPENSM_H_ */
diff --git a/osm/opensm/main.c b/osm/opensm/main.c
index c5ba443..797b14c 100644
--- a/osm/opensm/main.c
+++ b/osm/opensm/main.c
@@ -77,14 +77,59 @@
   instantiating more than one opensm object.
 */
 osm_opensm_t osm;
-volatile int osm_exit_flag = 0;
+
+volatile unsigned int osm_exit_flag = 0;
+
+static volatile unsigned int osm_hup_flag = 0;
 
 #define GUID_ARRAY_SIZE 64
 #define INVALID_GUID (0xFFFFFFFFFFFFFFFFULL)
 
+
+#ifdef __WIN__
+#define block_signals()
+#define setup_signals()
+#else
+
+static void mark_exit_flag(int signum)
+{
+	if(!osm_exit_flag)
+		printf("OpenSM: Got signal %d - exiting...\n", signum);
+	osm_exit_flag = 1;
+}
+
+static void mark_hup_flag(int signum)
+{
+	osm_hup_flag = 1;
+}
+
+static sigset_t saved_sigset;
+
+static void block_signals()
+{
+	sigset_t set;
+	sigfillset(&set);
+	sigprocmask(SIG_SETMASK, &set, &saved_sigset);
+}
+
+static void setup_signals()
+{
+	struct sigaction act;
+	sigfillset(&act.sa_mask);
+	act.sa_handler = mark_exit_flag;
+	act.sa_flags = 0;
+#ifndef OSM_VENDOR_INTF_OPENIB
+	sigaction(SIGINT, &act, NULL);
+#endif
+	sigaction(SIGTERM, &act, NULL);
+	act.sa_handler = mark_hup_flag;
+	sigaction(SIGHUP, &act, NULL);
+	sigprocmask(SIG_SETMASK, &saved_sigset, NULL);
+}
+#endif /* __WIN__ */
+
 /**********************************************************************
  **********************************************************************/
-void show_usage(void);
 
 void
 show_usage(void)
@@ -247,7 +292,6 @@ show_usage(void)
 
 /**********************************************************************
  **********************************************************************/
-void show_menu(void);
 
 void
 show_menu(void)
@@ -764,6 +808,8 @@ main(
   if ( cache_options == TRUE )
     osm_subn_write_conf_file( &opt );
 
+  block_signals();
+
   status = osm_opensm_init( &osm, &opt );
   if( status != IB_SUCCESS )
   {
@@ -794,9 +840,6 @@ main(
     goto Exit;
   }
 
-  /* this should handle ^C etc */
-  osm_reg_sig_handler( &osm );
-
   status = osm_opensm_bind( &osm, guid );
   if( status != IB_SUCCESS )
   {
@@ -817,6 +860,8 @@ main(
     }
   }
 
+  setup_signals();
+
   osm_opensm_sweep( &osm );
   /* since osm_opensm_init get opt as RO we'll set the opt value with UI pfn here */
   /* Now do the registration */
@@ -839,11 +884,23 @@ main(
       In the future, some sort of console interactivity could
       be implemented in this loop.
     */
-    while( !osm_exit_flag )
+    if (opt.console) {
+      printf("\nOpenSM Console\n\n");
+      osm_console_prompt();
+    }
+    while( !osm_exit_flag ) {
       if (opt.console)
         osm_console(&osm);
       else
         cl_thread_suspend( 10000 );
+
+      if (osm_hup_flag) {
+        osm_hup_flag = 0;
+        /* a HUP signal should only start a new heavy sweep */
+        osm.subn.force_immediate_heavy_sweep = TRUE;
+        cl_event_signal(&osm.sm.signal);
+      }
+    }
   }
 
 #if 0
diff --git a/osm/opensm/osm_console.c b/osm/opensm/osm_console.c
index c470b49..43d9f87 100644
--- a/osm/opensm/osm_console.c
+++ b/osm/opensm/osm_console.c
@@ -39,6 +39,7 @@
 #define _GNU_SOURCE		/* for getline */
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/poll.h>
 #include <opensm/osm_console.h>
 
 #define OSM_COMMAND_LINE_LEN	120
@@ -186,15 +187,27 @@ static void parse_cmd_line(char *line, o
 	}
 }
 
+void osm_console_prompt(void)
+{
+	printf("%s", OSM_COMMAND_PROMPT);
+	fflush(stdout);
+}
+
 void osm_console(osm_opensm_t *p_osm)
 {
+	struct pollfd pollfd;
 	char *p_line;
 	size_t len;
 	ssize_t n;
 
-	printf("\nOpenSM Console\n\n");
-	while (1) {
-		printf("%s", OSM_COMMAND_PROMPT);
+	pollfd.fd = 0;
+	pollfd.events = POLLIN;
+	pollfd.revents = 0;
+
+	if (poll(&pollfd, 1, 10000) <= 0)
+		return;
+
+	if (pollfd.revents|POLLIN) {
 		p_line = NULL;
 		/* Get input line */
 		n = getline(&p_line, &len, stdin);
@@ -206,6 +219,7 @@ void osm_console(osm_opensm_t *p_osm)
 			printf("Input error\n");
 			fflush(stdin);
 		}
+		osm_console_prompt();
 	}
 }
 
diff --git a/osm/opensm/osm_opensm.c b/osm/opensm/osm_opensm.c
index 6ca6796..54d0ae3 100644
--- a/osm/opensm/osm_opensm.c
+++ b/osm/opensm/osm_opensm.c
@@ -54,7 +54,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <complib/cl_memory.h>
-#include <complib/cl_signal_osd.h>
 #include <complib/cl_dispatcher.h>
 #include <complib/cl_passivelock.h>
 #include <vendor/osm_vendor_api.h>
@@ -149,52 +148,6 @@ osm_opensm_create_mcgroups(
 }
 
 /**********************************************************************
- * SHUT DOWN IS CONTROLLED BY A GLOBAL EXIT FLAG
- **********************************************************************/
-#ifndef __WIN__
-static osm_opensm_t *__p_osm_to_signal;
-
-void
-__sig_handler(
-   int signum )
-{
-   static int got_signal = 0;
-
-   if( signum != SIGHUP )
-   {
-      if( !got_signal )
-      {
-         got_signal++;
-         printf( "OpenSM: Got signal %d - exiting...\n", signum );
-         osm_exit_flag = 1;
-      }
-   }
-   else
-   {
-      /* a HUP signal should only start a new heavy sweep */
-      __p_osm_to_signal->subn.force_immediate_heavy_sweep = TRUE;
-      osm_state_mgr_process( &__p_osm_to_signal->sm.state_mgr,
-                             OSM_SIGNAL_SWEEP );
-   }
-}
-
-void
-osm_reg_sig_handler(
-   IN osm_opensm_t * const p_osm )
-{
-   __p_osm_to_signal = p_osm;
-#ifndef OSM_VENDOR_INTF_OPENIB 
-   cl_reg_sig_hdl( SIGINT, __sig_handler );
-#endif
-   cl_reg_sig_hdl( SIGTERM, __sig_handler );
-   cl_reg_sig_hdl( SIGHUP, __sig_handler );
-   osm_exit_flag = 0;
-
-   return;
-}
-#endif /* __WIN__ */
-
-/**********************************************************************
  **********************************************************************/
 ib_api_status_t
 osm_opensm_init(
diff --git a/osm/opensm/osm_sm.c b/osm/opensm/osm_sm.c
index 8ace290..e252861 100644
--- a/osm/opensm/osm_sm.c
+++ b/osm/opensm/osm_sm.c
@@ -87,10 +87,6 @@ __osm_sm_sweeper(
 
    if( p_sm->thread_state == OSM_THREAD_STATE_INIT )
    {
-      osm_log( p_sm->p_log, OSM_LOG_DEBUG,
-               "__osm_sm_sweeper: " "Masking ^C Signals\n" );
-      cl_sig_mask_sigint(  );
-
       p_sm->thread_state = OSM_THREAD_STATE_RUN;
    }
 
diff --git a/osm/opensm/osm_vl15intf.c b/osm/opensm/osm_vl15intf.c
index ef18e54..4796a17 100644
--- a/osm/opensm/osm_vl15intf.c
+++ b/osm/opensm/osm_vl15intf.c
@@ -85,7 +85,6 @@ __osm_vl15_poller(
 
   if ( p_vl->thread_state == OSM_THREAD_STATE_NONE)
   {
-    cl_sig_mask_sigint( );
     p_vl->thread_state = OSM_THREAD_STATE_RUN;
   }
 



More information about the general mailing list