1111 * All rights reserved.
1212 * Copyright (c) 2011 Cisco Systems, Inc. All rights reserved.
1313 * Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
14+ * Copyright (c) 2017 Intel, Inc. All rights reserved.
1415 * $COPYRIGHT$
1516 *
1617 * Additional copyrights may follow
2324#include "orte/constants.h"
2425
2526#include "orte/mca/mca.h"
27+ #include "opal/util/argv.h"
2628#include "opal/util/output.h"
2729#include "opal/mca/base/base.h"
30+ #include "orte/util/show_help.h"
2831
2932#include "orte/mca/ess/base/base.h"
3033
@@ -46,6 +49,7 @@ int orte_ess_base_std_buffering = -1;
4649int orte_ess_base_num_procs = -1 ;
4750char * orte_ess_base_jobid = NULL ;
4851char * orte_ess_base_vpid = NULL ;
52+ opal_list_t orte_ess_base_signals = {0 };
4953
5054static mca_base_var_enum_value_t stream_buffering_values [] = {
5155 {-1 , "default" },
@@ -55,6 +59,9 @@ static mca_base_var_enum_value_t stream_buffering_values[] = {
5559 {0 , NULL }
5660};
5761
62+ static int setup_signals (void );
63+ static char * forwarded_signals = NULL ;
64+
5865static int orte_ess_base_register (mca_base_register_flag_t flags )
5966{
6067 mca_base_var_enum_t * new_enum ;
@@ -96,21 +103,200 @@ static int orte_ess_base_register(mca_base_register_flag_t flags)
96103 MCA_BASE_VAR_SCOPE_READONLY , & orte_ess_base_num_procs );
97104 mca_base_var_register_synonym (ret , "orte" , "orte" , "ess" , "num_procs" , 0 );
98105
106+ forwarded_signals = NULL ;
107+ ret = mca_base_var_register ("orte" , "ess" , "base" , "forward_signals" ,
108+ "Comma-delimited list of additional signals (names or integers) to forward to "
109+ "application processes [\"none\" => forward nothing]. Signals provided by "
110+ "default include SIGTSTP, SIGUSR1, SIGUSR2, SIGABRT, SIGALRM, and SIGCONT" ,
111+ MCA_BASE_VAR_TYPE_STRING , NULL , 0 , 0 ,
112+ OPAL_INFO_LVL_4 , MCA_BASE_VAR_SCOPE_READONLY ,
113+ & forwarded_signals );
114+ mca_base_var_register_synonym (ret , "orte" , "ess" , "hnp" , "forward_signals" , 0 );
115+
116+
99117 return ORTE_SUCCESS ;
100118}
101119
102120static int orte_ess_base_close (void )
103121{
122+ OPAL_LIST_DESTRUCT (& orte_ess_base_signals );
123+
104124 return mca_base_framework_components_close (& orte_ess_base_framework , NULL );
105125}
106126
107127static int orte_ess_base_open (mca_base_open_flag_t flags )
108128{
129+ int rc ;
130+
131+ OBJ_CONSTRUCT (& orte_ess_base_signals , opal_list_t );
132+
133+ if (ORTE_PROC_IS_HNP || ORTE_PROC_IS_DAEMON ) {
134+ if (ORTE_SUCCESS != (rc = setup_signals ())) {
135+ return rc ;
136+ }
137+ }
109138 return mca_base_framework_components_open (& orte_ess_base_framework , flags );
110139}
111140
112141MCA_BASE_FRAMEWORK_DECLARE (orte , ess , "ORTE Environmenal System Setup" ,
113142 orte_ess_base_register , orte_ess_base_open , orte_ess_base_close ,
114143 mca_ess_base_static_components , 0 );
115144
145+ /* signal forwarding */
146+
147+ /* setup signal forwarding list */
148+ struct known_signal {
149+ /** signal number */
150+ int signal ;
151+ /** signal name */
152+ char * signame ;
153+ /** can this signal be forwarded */
154+ bool can_forward ;
155+ };
156+
157+ static struct known_signal known_signals [] = {
158+ {SIGTERM , "SIGTERM" , false},
159+ {SIGHUP , "SIGHUP" , false},
160+ {SIGINT , "SIGINT" , false},
161+ {SIGKILL , "SIGKILL" , false},
162+ #ifdef SIGSYS
163+ {SIGSYS , "SIGSYS" , true},
164+ #endif
165+ #ifdef SIGXCPU
166+ {SIGXCPU , "SIGXCPU" , true},
167+ #endif
168+ {SIGXFSZ , "SIGXFSZ" , true},
169+ #ifdef SIGVTALRM
170+ {SIGVTALRM , "SIGVTALRM" , true},
171+ #endif
172+ #ifdef SIGPROF
173+ {SIGPROF , "SIGPROF" , true},
174+ #endif
175+ #ifdef SIGINFO
176+ {SIGINFO , "SIGINFO" , true},
177+ #endif
178+ #ifdef SIGPWR
179+ {SIGPWR , "SIGPWR" , true},
180+ #endif
181+ #ifdef SIGURG
182+ {SIGURG , "SIGURG" , true},
183+ #endif
184+ #ifdef SIGUSR1
185+ {SIGUSR1 , "SIGUSR1" , true},
186+ #endif
187+ #ifdef SIGUSR2
188+ {SIGUSR2 , "SIGUSR2" , true},
189+ #endif
190+ {0 , NULL },
191+ };
192+
193+ #define ESS_ADDSIGNAL (x , s ) \
194+ do { \
195+ orte_ess_base_signal_t *_sig; \
196+ _sig = OBJ_NEW(orte_ess_base_signal_t); \
197+ _sig->signal = (x); \
198+ _sig->signame = strdup((s)); \
199+ opal_list_append(&orte_ess_base_signals, &_sig->super); \
200+ } while(0)
201+
202+ static int setup_signals (void )
203+ {
204+ int i , sval , nsigs ;
205+ char * * signals , * tmp ;
206+ orte_ess_base_signal_t * sig ;
207+ bool ignore , found ;
208+
209+ /* if they told us "none", then nothing to do */
210+ if (NULL != forwarded_signals &&
211+ 0 == strcmp (forwarded_signals , "none" )) {
212+ return ORTE_SUCCESS ;
213+ }
116214
215+ /* we know that some signals are (nearly) always defined, regardless
216+ * of environment, so add them here */
217+ nsigs = sizeof (known_signals ) / sizeof (struct known_signal );
218+ for (i = 0 ; i < nsigs ; i ++ ) {
219+ if (known_signals [i ].can_forward ) {
220+ ESS_ADDSIGNAL (known_signals [i ].signal , known_signals [i ].signame );
221+ }
222+ }
223+
224+ /* see if they asked for anything beyond those - note that they may
225+ * have asked for some we already cover, and so we ignore any duplicates */
226+ if (NULL != forwarded_signals ) {
227+ /* if they told us "none", then dump the list */
228+ signals = opal_argv_split (forwarded_signals , ',' );
229+ for (i = 0 ; NULL != signals [i ]; i ++ ) {
230+ sval = 0 ;
231+ if (0 != strncmp (signals [i ], "SIG" , 3 )) {
232+ /* treat it like a number */
233+ errno = 0 ;
234+ sval = strtoul (signals [i ], & tmp , 10 );
235+ if (0 != errno || '\0' != * tmp ) {
236+ orte_show_help ("help-ess-base.txt" , "ess-base:unknown-signal" ,
237+ true, signals [i ], forwarded_signals );
238+ opal_argv_free (signals );
239+ return OPAL_ERR_SILENT ;
240+ }
241+ }
242+
243+ /* see if it is one we already covered */
244+ ignore = false;
245+ OPAL_LIST_FOREACH (sig , & orte_ess_base_signals , orte_ess_base_signal_t ) {
246+ if (0 == strcasecmp (signals [i ], sig -> signame ) || sval == sig -> signal ) {
247+ /* got it - we will ignore */
248+ ignore = true;
249+ break ;
250+ }
251+ }
252+
253+ if (ignore ) {
254+ continue ;
255+ }
256+
257+ /* see if they gave us a signal name */
258+ found = false;
259+ for (int j = 0 ; known_signals [j ].signame ; ++ j ) {
260+ if (0 == strcasecmp (signals [i ], known_signals [j ].signame ) || sval == known_signals [j ].signal ) {
261+ if (!known_signals [j ].can_forward ) {
262+ orte_show_help ("help-ess-base.txt" , "ess-base:cannot-forward" ,
263+ true, known_signals [j ].signame , forwarded_signals );
264+ opal_argv_free (signals );
265+ return OPAL_ERR_SILENT ;
266+ }
267+ found = true;
268+ ESS_ADDSIGNAL (known_signals [j ].signal , known_signals [j ].signame );
269+ break ;
270+ }
271+ }
272+
273+ if (!found ) {
274+ if (0 == strncmp (signals [i ], "SIG" , 3 )) {
275+ orte_show_help ("help-ess-base.txt" , "ess-base:unknown-signal" ,
276+ true, signals [i ], forwarded_signals );
277+ opal_argv_free (signals );
278+ return OPAL_ERR_SILENT ;
279+ }
280+
281+ ESS_ADDSIGNAL (sval , signals [i ]);
282+ }
283+ }
284+ opal_argv_free (signals );
285+ }
286+ return ORTE_SUCCESS ;
287+ }
288+
289+ /* instantiate the class */
290+ static void scon (orte_ess_base_signal_t * t )
291+ {
292+ t -> signame = NULL ;
293+ }
294+ static void sdes (orte_ess_base_signal_t * t )
295+ {
296+ if (NULL != t -> signame ) {
297+ free (t -> signame );
298+ }
299+ }
300+ OBJ_CLASS_INSTANCE (orte_ess_base_signal_t ,
301+ opal_list_item_t ,
302+ scon , sdes );
0 commit comments