1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2017 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2005 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2011-2017 Cisco Systems, Inc. All rights reserved
14 * Copyright (c) 2015 Los Alamos National Security, LLC. All rights
15 * reserved.
16 * Copyright (c) 2017 IBM Corporation. All rights reserved.
17 * $COPYRIGHT$
18 *
19 * Additional copyrights may follow
20 *
21 * $HEADER$
22 */
23
24 #include "opal_config.h"
25
26 #include <stdio.h>
27 #include <string.h>
28 #ifdef HAVE_SYSLOG_H
29 #include <syslog.h>
30 #endif
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #include "opal/mca/installdirs/installdirs.h"
36 #include "opal/util/output.h"
37 #include "opal/util/printf.h"
38 #include "opal/mca/mca.h"
39 #include "opal/mca/base/base.h"
40 #include "opal/mca/base/mca_base_component_repository.h"
41 #include "opal/constants.h"
42 #include "opal/util/opal_environ.h"
43
44 /*
45 * Public variables
46 */
47 char *mca_base_component_path = NULL;
48 int mca_base_opened = 0;
49 char *mca_base_system_default_path = NULL;
50 char *mca_base_user_default_path = NULL;
51 bool mca_base_component_show_load_errors =
52 (bool) OPAL_SHOW_LOAD_ERRORS_DEFAULT;
53 bool mca_base_component_track_load_errors = false;
54 bool mca_base_component_disable_dlopen = false;
55
56 static char *mca_base_verbose = NULL;
57
58 /*
59 * Private functions
60 */
61 static void set_defaults(opal_output_stream_t *lds);
62 static void parse_verbose(char *e, opal_output_stream_t *lds);
63
64
65 /*
66 * Main MCA initialization.
67 */
mca_base_open(void)68 int mca_base_open(void)
69 {
70 char *value;
71 opal_output_stream_t lds;
72 char hostname[OPAL_MAXHOSTNAMELEN];
73 int var_id;
74
75 if (mca_base_opened++) {
76 return OPAL_SUCCESS;
77 }
78
79 /* define the system and user default paths */
80 #if OPAL_WANT_HOME_CONFIG_FILES
81 mca_base_system_default_path = strdup(opal_install_dirs.opallibdir);
82 asprintf(&mca_base_user_default_path, "%s"OPAL_PATH_SEP".openmpi"OPAL_PATH_SEP"components", opal_home_directory());
83 #else
84 asprintf(&mca_base_system_default_path, "%s", opal_install_dirs.opallibdir);
85 #endif
86
87 /* see if the user wants to override the defaults */
88 if (NULL == mca_base_user_default_path) {
89 value = strdup(mca_base_system_default_path);
90 } else {
91 asprintf(&value, "%s%c%s", mca_base_system_default_path,
92 OPAL_ENV_SEP, mca_base_user_default_path);
93 }
94
95 mca_base_component_path = value;
96 var_id = mca_base_var_register("opal", "mca", "base", "component_path",
97 "Path where to look for additional components",
98 MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0,
99 OPAL_INFO_LVL_9,
100 MCA_BASE_VAR_SCOPE_READONLY,
101 &mca_base_component_path);
102 (void) mca_base_var_register_synonym(var_id, "opal", "mca", NULL, "component_path",
103 MCA_BASE_VAR_SYN_FLAG_DEPRECATED);
104 free(value);
105
106 mca_base_component_show_load_errors =
107 (bool) OPAL_SHOW_LOAD_ERRORS_DEFAULT;
108 var_id = mca_base_var_register("opal", "mca", "base", "component_show_load_errors",
109 "Whether to show errors for components that failed to load or not",
110 MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0,
111 OPAL_INFO_LVL_9,
112 MCA_BASE_VAR_SCOPE_READONLY,
113 &mca_base_component_show_load_errors);
114 (void) mca_base_var_register_synonym(var_id, "opal", "mca", NULL, "component_show_load_errors",
115 MCA_BASE_VAR_SYN_FLAG_DEPRECATED);
116
117 mca_base_component_track_load_errors = false;
118 var_id = mca_base_var_register("opal", "mca", "base", "component_track_load_errors",
119 "Whether to track errors for components that failed to load or not",
120 MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0,
121 OPAL_INFO_LVL_9,
122 MCA_BASE_VAR_SCOPE_READONLY,
123 &mca_base_component_track_load_errors);
124
125 mca_base_component_disable_dlopen = false;
126 var_id = mca_base_var_register("opal", "mca", "base", "component_disable_dlopen",
127 "Whether to attempt to disable opening dynamic components or not",
128 MCA_BASE_VAR_TYPE_BOOL, NULL, 0, 0,
129 OPAL_INFO_LVL_9,
130 MCA_BASE_VAR_SCOPE_READONLY,
131 &mca_base_component_disable_dlopen);
132 (void) mca_base_var_register_synonym(var_id, "opal", "mca", NULL, "component_disable_dlopen",
133 MCA_BASE_VAR_SYN_FLAG_DEPRECATED);
134
135 /* What verbosity level do we want for the default 0 stream? */
136 char *str = getenv("OPAL_OUTPUT_INTERNAL_TO_STDOUT");
137 if (NULL != str && str[0] == '1') {
138 mca_base_verbose = "stdout";
139 }
140 else {
141 mca_base_verbose = "stderr";
142 }
143 var_id = mca_base_var_register("opal", "mca", "base", "verbose",
144 "Specifies where the default error output stream goes (this is separate from distinct help messages). Accepts a comma-delimited list of: stderr, stdout, syslog, syslogpri:<notice|info|debug>, syslogid:<str> (where str is the prefix string for all syslog notices), file[:filename] (if filename is not specified, a default filename is used), fileappend (if not specified, the file is opened for truncation), level[:N] (if specified, integer verbose level; otherwise, 0 is implied)",
145 MCA_BASE_VAR_TYPE_STRING, NULL, 0, 0,
146 OPAL_INFO_LVL_9,
147 MCA_BASE_VAR_SCOPE_READONLY,
148 &mca_base_verbose);
149 (void) mca_base_var_register_synonym(var_id, "opal", "mca", NULL, "verbose",
150 MCA_BASE_VAR_SYN_FLAG_DEPRECATED);
151
152 memset(&lds, 0, sizeof(lds));
153 if (NULL != mca_base_verbose) {
154 parse_verbose(mca_base_verbose, &lds);
155 } else {
156 set_defaults(&lds);
157 }
158 gethostname(hostname, sizeof(hostname));
159 asprintf(&lds.lds_prefix, "[%s:%05d] ", hostname, getpid());
160 opal_output_reopen(0, &lds);
161 opal_output_verbose (MCA_BASE_VERBOSE_COMPONENT, 0, "mca: base: opening components");
162 free(lds.lds_prefix);
163
164 /* Open up the component repository */
165
166 return mca_base_component_repository_init();
167 }
168
169
170 /*
171 * Set sane default values for the lds
172 */
set_defaults(opal_output_stream_t * lds)173 static void set_defaults(opal_output_stream_t *lds)
174 {
175
176 /* Load up defaults */
177
178 OBJ_CONSTRUCT(lds, opal_output_stream_t);
179 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
180 lds->lds_syslog_priority = LOG_INFO;
181 lds->lds_syslog_ident = "ompi";
182 #endif
183 lds->lds_want_stderr = true;
184 }
185
186
187 /*
188 * Parse the value of an environment variable describing verbosity
189 */
parse_verbose(char * e,opal_output_stream_t * lds)190 static void parse_verbose(char *e, opal_output_stream_t *lds)
191 {
192 char *edup;
193 char *ptr, *next;
194 bool have_output = false;
195
196 if (NULL == e) {
197 return;
198 }
199
200 edup = strdup(e);
201 ptr = edup;
202
203 /* Now parse the environment variable */
204
205 while (NULL != ptr && strlen(ptr) > 0) {
206 next = strchr(ptr, ',');
207 if (NULL != next) {
208 *next = '\0';
209 }
210
211 if (0 == strcasecmp(ptr, "syslog")) {
212 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
213 lds->lds_want_syslog = true;
214 have_output = true;
215 #else
216 opal_output(0, "syslog support requested but not available on this system");
217 #endif /* defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H) */
218 }
219 else if (strncasecmp(ptr, "syslogpri:", 10) == 0) {
220 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
221 lds->lds_want_syslog = true;
222 have_output = true;
223 if (strcasecmp(ptr + 10, "notice") == 0)
224 lds->lds_syslog_priority = LOG_NOTICE;
225 else if (strcasecmp(ptr + 10, "INFO") == 0)
226 lds->lds_syslog_priority = LOG_INFO;
227 else if (strcasecmp(ptr + 10, "DEBUG") == 0)
228 lds->lds_syslog_priority = LOG_DEBUG;
229 #else
230 opal_output(0, "syslog support requested but not available on this system");
231 #endif /* defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H) */
232 } else if (strncasecmp(ptr, "syslogid:", 9) == 0) {
233 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
234 lds->lds_want_syslog = true;
235 lds->lds_syslog_ident = ptr + 9;
236 #else
237 opal_output(0, "syslog support requested but not available on this system");
238 #endif /* defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H) */
239 }
240
241 else if (strcasecmp(ptr, "stdout") == 0) {
242 lds->lds_want_stdout = true;
243 have_output = true;
244 } else if (strcasecmp(ptr, "stderr") == 0) {
245 lds->lds_want_stderr = true;
246 have_output = true;
247 }
248
249 else if (strcasecmp(ptr, "file") == 0 || strcasecmp(ptr, "file:") == 0) {
250 lds->lds_want_file = true;
251 have_output = true;
252 } else if (strncasecmp(ptr, "file:", 5) == 0) {
253 lds->lds_want_file = true;
254 lds->lds_file_suffix = strdup(ptr + 5);
255 have_output = true;
256 } else if (strcasecmp(ptr, "fileappend") == 0) {
257 lds->lds_want_file = true;
258 lds->lds_want_file_append = 1;
259 have_output = true;
260 }
261
262 else if (strncasecmp(ptr, "level", 5) == 0) {
263 lds->lds_verbose_level = 0;
264 if (ptr[5] == OPAL_ENV_SEP)
265 lds->lds_verbose_level = atoi(ptr + 6);
266 }
267
268 if (NULL == next) {
269 break;
270 }
271 ptr = next + 1;
272 }
273
274 /* If we didn't get an output, default to stderr */
275
276 if (!have_output) {
277 lds->lds_want_stderr = true;
278 }
279
280 /* All done */
281
282 free(edup);
283 }
284