1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2 /*
3 * Copyright (c) 2004-2010 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2011 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) 2006-2015 Cisco Systems, Inc. All rights reserved.
14 * Copyright (c) 2010-2016 Los Alamos National Security, LLC. All rights
15 * reserved.
16 * Copyright (c) 2011-2012 University of Houston. All rights reserved.
17 * Copyright (c) 2016-2017 Intel, Inc. All rights reserved.
18 * Copyright (c) 2017 IBM Corporation. All rights reserved.
19 * $COPYRIGHT$
20 *
21 * Additional copyrights may follow
22 *
23 * $HEADER$
24 */
25
26 #include "opal_config.h"
27
28 #include <string.h>
29 #include <ctype.h>
30
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #include <errno.h>
36
37 #include "opal/class/opal_list.h"
38 #include "opal/class/opal_pointer_array.h"
39
40 #include "opal/util/output.h"
41 #include "opal/util/cmd_line.h"
42 #include "opal/util/error.h"
43 #include "opal/util/argv.h"
44 #include "opal/util/show_help.h"
45 #include "opal/runtime/opal.h"
46 #include "opal/dss/dss.h"
47 #include "opal/mca/base/mca_base_pvar.h"
48
49 #include "opal/include/opal/frameworks.h"
50
51 #include "opal/mca/installdirs/installdirs.h"
52
53 #include "opal/runtime/opal_info_support.h"
54 #include "opal/mca/base/mca_base_component_repository.h"
55
56 const char *opal_info_path_prefix = "prefix";
57 const char *opal_info_path_bindir = "bindir";
58 const char *opal_info_path_libdir = "libdir";
59 const char *opal_info_path_incdir = "incdir";
60 const char *opal_info_path_mandir = "mandir";
61 const char *opal_info_path_pkglibdir = "pkglibdir";
62 const char *opal_info_path_sysconfdir = "sysconfdir";
63 const char *opal_info_path_exec_prefix = "exec_prefix";
64 const char *opal_info_path_sbindir = "sbindir";
65 const char *opal_info_path_libexecdir = "libexecdir";
66 const char *opal_info_path_datarootdir = "datarootdir";
67 const char *opal_info_path_datadir = "datadir";
68 const char *opal_info_path_sharedstatedir = "sharedstatedir";
69 const char *opal_info_path_localstatedir = "localstatedir";
70 const char *opal_info_path_infodir = "infodir";
71 const char *opal_info_path_pkgdatadir = "pkgdatadir";
72 const char *opal_info_path_pkgincludedir = "pkgincludedir";
73
74 bool opal_info_pretty = true;
75 mca_base_register_flag_t opal_info_register_flags = MCA_BASE_REGISTER_ALL;
76
77 const char *opal_info_type_all = "all";
78 const char *opal_info_type_opal = "opal";
79 const char *opal_info_component_all = "all";
80 const char *opal_info_param_all = "all";
81
82 const char *opal_info_ver_full = "full";
83 const char *opal_info_ver_major = "major";
84 const char *opal_info_ver_minor = "minor";
85 const char *opal_info_ver_release = "release";
86 const char *opal_info_ver_greek = "greek";
87 const char *opal_info_ver_repo = "repo";
88
89 const char *opal_info_ver_all = "all";
90 const char *opal_info_ver_mca = "mca";
91 const char *opal_info_ver_type = "type";
92 const char *opal_info_ver_component = "component";
93
94 static int opal_info_registered = 0;
95
component_map_construct(opal_info_component_map_t * map)96 static void component_map_construct(opal_info_component_map_t *map)
97 {
98 map->type = NULL;
99 }
component_map_destruct(opal_info_component_map_t * map)100 static void component_map_destruct(opal_info_component_map_t *map)
101 {
102 if (NULL != map->type) {
103 free(map->type);
104 }
105 /* the type close functions will release the
106 * list of components
107 */
108 }
109 OBJ_CLASS_INSTANCE(opal_info_component_map_t,
110 opal_list_item_t,
111 component_map_construct,
112 component_map_destruct);
113
114 static void opal_info_show_failed_component(const mca_base_component_repository_item_t* ri,
115 const char *error_msg);
116
opal_info_init(int argc,char ** argv,opal_cmd_line_t * opal_info_cmd_line)117 int opal_info_init(int argc, char **argv,
118 opal_cmd_line_t *opal_info_cmd_line)
119 {
120 int ret;
121 bool want_help = false;
122 bool cmd_error = false;
123 char **app_env = NULL, **global_env = NULL;
124
125 /* Initialize the argv parsing handle */
126 if (OPAL_SUCCESS != (ret = opal_init_util(&argc, &argv))) {
127 opal_show_help("help-opal_info.txt", "lib-call-fail", true,
128 "opal_init_util", __FILE__, __LINE__, NULL);
129 exit(ret);
130 }
131
132 /* add the cmd line options */
133 opal_cmd_line_make_opt3(opal_info_cmd_line, 'V', NULL, "version", 0,
134 "Show version of Open MPI");
135 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "param", 2,
136 "Show MCA parameters. The first parameter is the framework (or the keyword \"all\"); the second parameter is the specific component name (or the keyword \"all\").");
137 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "params", 2,
138 "Synonym for --param");
139 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "internal", 0,
140 "Show internal MCA parameters (not meant to be modified by users)");
141 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "path", 1,
142 "Show paths that Open MPI was configured with. Accepts the following parameters: prefix, bindir, libdir, incdir, mandir, pkglibdir, sysconfdir, all");
143 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "arch", 0,
144 "Show architecture Open MPI was compiled on");
145 opal_cmd_line_make_opt3(opal_info_cmd_line, 'c', NULL, "config", 0,
146 "Show configuration options");
147 opal_cmd_line_make_opt3(opal_info_cmd_line, 't', NULL, "type", 1,
148 "Show internal MCA parameters with the type specified in parameter.");
149 opal_cmd_line_make_opt3(opal_info_cmd_line, 'h', NULL, "help", 0,
150 "Show this help message");
151 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "pretty-print", 0,
152 "When used in conjunction with other parameters, the output is displayed in 'pretty-print' format (default)");
153 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "parsable", 0,
154 "When used in conjunction with other parameters, the output is displayed in a machine-parsable format");
155 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "parseable", 0,
156 "Synonym for --parsable");
157 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "hostname", 0,
158 "Show the hostname that Open MPI was configured and built on");
159 opal_cmd_line_make_opt3(opal_info_cmd_line, 'a', NULL, "all", 0,
160 "Show all configuration options and MCA parameters");
161 opal_cmd_line_make_opt3(opal_info_cmd_line, 'l', NULL, "level", 1,
162 "Show only variables with at most this level (1-9)");
163 opal_cmd_line_make_opt3(opal_info_cmd_line, 's', NULL, "selected-only", 0,
164 "Show only variables from selected components");
165 opal_cmd_line_make_opt3(opal_info_cmd_line, '\0', NULL, "show-failed", 0,
166 "Show the components that failed to load along with the reason why they failed.");
167
168 /* set our threading level */
169 opal_set_using_threads(false);
170
171 /* Get MCA parameters, if any */
172 if( OPAL_SUCCESS != mca_base_open() ) {
173 opal_show_help("help-opal_info.txt", "lib-call-fail", true, "mca_base_open", __FILE__, __LINE__ );
174 opal_finalize_util();
175 return OPAL_ERROR;
176 }
177 mca_base_cmd_line_setup(opal_info_cmd_line);
178
179 /* Initialize the opal_output system */
180 if (!opal_output_init()) {
181 return OPAL_ERROR;
182 }
183
184 /* Do the parsing */
185 ret = opal_cmd_line_parse(opal_info_cmd_line, false, false, argc, argv);
186 if (OPAL_SUCCESS != ret) {
187 cmd_error = true;
188 if (OPAL_ERR_SILENT != ret) {
189 fprintf(stderr, "%s: command line error (%s)\n", argv[0],
190 opal_strerror(ret));
191 }
192 }
193 if (!cmd_error &&
194 (opal_cmd_line_is_taken(opal_info_cmd_line, "help") ||
195 opal_cmd_line_is_taken(opal_info_cmd_line, "h"))) {
196 char *str, *usage;
197
198 want_help = true;
199 usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
200 str = opal_show_help_string("help-opal_info.txt", "usage",
201 true, usage);
202 if (NULL != str) {
203 printf("%s", str);
204 free(str);
205 }
206 free(usage);
207 }
208
209 /* If we had a cmd line parse error, or we showed the help
210 message, it's time to exit. */
211 if (cmd_error || want_help) {
212 mca_base_close();
213 OBJ_RELEASE(opal_info_cmd_line);
214 opal_finalize_util();
215 exit(cmd_error ? 1 : 0);
216 }
217
218 mca_base_cmd_line_process_args(opal_info_cmd_line, &app_env, &global_env);
219
220
221 /* set the flags */
222 if (opal_cmd_line_is_taken(opal_info_cmd_line, "pretty-print")) {
223 opal_info_pretty = true;
224 } else if (opal_cmd_line_is_taken(opal_info_cmd_line, "parsable") || opal_cmd_line_is_taken(opal_info_cmd_line, "parseable")) {
225 opal_info_pretty = false;
226 }
227
228 if (opal_cmd_line_is_taken(opal_info_cmd_line, "selected-only")) {
229 /* register only selected components */
230 opal_info_register_flags = MCA_BASE_REGISTER_DEFAULT;
231 }
232
233 if( opal_cmd_line_is_taken(opal_info_cmd_line, "show-failed") ) {
234 mca_base_component_track_load_errors = true;
235 }
236
237 return OPAL_SUCCESS;
238 }
239
opal_info_finalize(void)240 void opal_info_finalize(void)
241 {
242 opal_finalize_util();
243 }
244
info_register_framework(mca_base_framework_t * framework,opal_pointer_array_t * component_map)245 static int info_register_framework (mca_base_framework_t *framework, opal_pointer_array_t *component_map)
246 {
247 opal_info_component_map_t *map;
248 int rc;
249
250 rc = mca_base_framework_register(framework, opal_info_register_flags);
251 if (OPAL_SUCCESS != rc && OPAL_ERR_BAD_PARAM != rc) {
252 return rc;
253 }
254
255 if (NULL != component_map) {
256 map = OBJ_NEW(opal_info_component_map_t);
257 map->type = strdup(framework->framework_name);
258 map->components = &framework->framework_components;
259 map->failed_components = &framework->framework_failed_components;
260 opal_pointer_array_add(component_map, map);
261 }
262
263 return rc;
264 }
265
opal_info_register_project_frameworks(const char * project_name,mca_base_framework_t ** frameworks,opal_pointer_array_t * component_map)266 int opal_info_register_project_frameworks (const char *project_name, mca_base_framework_t **frameworks,
267 opal_pointer_array_t *component_map)
268 {
269 int i, rc=OPAL_SUCCESS;
270
271 for (i=0; NULL != frameworks[i]; i++) {
272 if (OPAL_SUCCESS != (rc = info_register_framework(frameworks[i], component_map))) {
273 if (OPAL_ERR_BAD_PARAM == rc) {
274 fprintf(stderr, "\nA \"bad parameter\" error was encountered when opening the %s %s framework\n",
275 project_name, frameworks[i]->framework_name);
276 fprintf(stderr, "The output received from that framework includes the following parameters:\n\n");
277 } else if (OPAL_ERR_NOT_AVAILABLE != rc) {
278 fprintf(stderr, "%s_info_register: %s failed\n", project_name, frameworks[i]->framework_name);
279 rc = OPAL_ERROR;
280 } else {
281 continue;
282 }
283
284 break;
285 }
286 }
287
288 return rc;
289 }
290
opal_info_register_types(opal_pointer_array_t * mca_types)291 void opal_info_register_types(opal_pointer_array_t *mca_types)
292 {
293 int i;
294
295 /* add the top-level types */
296 opal_pointer_array_add(mca_types, "mca");
297 opal_pointer_array_add(mca_types, "opal");
298
299 /* push all the types found by autogen */
300 for (i=0; NULL != opal_frameworks[i]; i++) {
301 opal_pointer_array_add(mca_types, opal_frameworks[i]->framework_name);
302 }
303 }
304
opal_info_register_framework_params(opal_pointer_array_t * component_map)305 int opal_info_register_framework_params(opal_pointer_array_t *component_map)
306 {
307 int rc;
308
309 if (opal_info_registered++) {
310 return OPAL_SUCCESS;
311 }
312
313 /* Register mca/base parameters */
314 if( OPAL_SUCCESS != mca_base_open() ) {
315 opal_show_help("help-opal_info.txt", "lib-call-fail", true, "mca_base_open", __FILE__, __LINE__ );
316 return OPAL_ERROR;
317 }
318
319 /* Register the OPAL layer's MCA parameters */
320 if (OPAL_SUCCESS != (rc = opal_register_params())) {
321 fprintf(stderr, "opal_info_register: opal_register_params failed\n");
322 return rc;
323 }
324
325 return opal_info_register_project_frameworks("opal", opal_frameworks, component_map);
326 }
327
328
opal_info_close_components(void)329 void opal_info_close_components(void)
330 {
331 int i;
332
333 assert(opal_info_registered);
334 if (--opal_info_registered) {
335 return;
336 }
337
338 for (i=0; NULL != opal_frameworks[i]; i++) {
339 (void) mca_base_framework_close(opal_frameworks[i]);
340 }
341
342 /* release our reference to MCA */
343 mca_base_close ();
344 }
345
346
opal_info_show_path(const char * type,const char * value)347 void opal_info_show_path(const char *type, const char *value)
348 {
349 char *pretty, *path;
350
351 pretty = strdup(type);
352 pretty[0] = toupper(pretty[0]);
353
354 asprintf(&path, "path:%s", type);
355 opal_info_out(pretty, path, value);
356 free(pretty);
357 free(path);
358 }
359
opal_info_do_path(bool want_all,opal_cmd_line_t * cmd_line)360 void opal_info_do_path(bool want_all, opal_cmd_line_t *cmd_line)
361 {
362 int i, count;
363 char *scope;
364
365 /* Check bozo case */
366 count = opal_cmd_line_get_ninsts(cmd_line, "path");
367 for (i = 0; i < count; ++i) {
368 scope = opal_cmd_line_get_param(cmd_line, "path", i, 0);
369 if (0 == strcmp("all", scope)) {
370 want_all = true;
371 break;
372 }
373 }
374
375 if (want_all) {
376 opal_info_show_path(opal_info_path_prefix, opal_install_dirs.prefix);
377 opal_info_show_path(opal_info_path_exec_prefix, opal_install_dirs.exec_prefix);
378 opal_info_show_path(opal_info_path_bindir, opal_install_dirs.bindir);
379 opal_info_show_path(opal_info_path_sbindir, opal_install_dirs.sbindir);
380 opal_info_show_path(opal_info_path_libdir, opal_install_dirs.libdir);
381 opal_info_show_path(opal_info_path_incdir, opal_install_dirs.includedir);
382 opal_info_show_path(opal_info_path_mandir, opal_install_dirs.mandir);
383 opal_info_show_path(opal_info_path_pkglibdir, opal_install_dirs.opallibdir);
384 opal_info_show_path(opal_info_path_libexecdir, opal_install_dirs.libexecdir);
385 opal_info_show_path(opal_info_path_datarootdir, opal_install_dirs.datarootdir);
386 opal_info_show_path(opal_info_path_datadir, opal_install_dirs.datadir);
387 opal_info_show_path(opal_info_path_sysconfdir, opal_install_dirs.sysconfdir);
388 opal_info_show_path(opal_info_path_sharedstatedir, opal_install_dirs.sharedstatedir);
389 opal_info_show_path(opal_info_path_localstatedir, opal_install_dirs.localstatedir);
390 opal_info_show_path(opal_info_path_infodir, opal_install_dirs.infodir);
391 opal_info_show_path(opal_info_path_pkgdatadir, opal_install_dirs.opaldatadir);
392 opal_info_show_path(opal_info_path_pkglibdir, opal_install_dirs.opallibdir);
393 opal_info_show_path(opal_info_path_pkgincludedir, opal_install_dirs.opalincludedir);
394 } else {
395 count = opal_cmd_line_get_ninsts(cmd_line, "path");
396 for (i = 0; i < count; ++i) {
397 scope = opal_cmd_line_get_param(cmd_line, "path", i, 0);
398
399 if (0 == strcmp(opal_info_path_prefix, scope)) {
400 opal_info_show_path(opal_info_path_prefix, opal_install_dirs.prefix);
401 } else if (0 == strcmp(opal_info_path_bindir, scope)) {
402 opal_info_show_path(opal_info_path_bindir, opal_install_dirs.bindir);
403 } else if (0 == strcmp(opal_info_path_libdir, scope)) {
404 opal_info_show_path(opal_info_path_libdir, opal_install_dirs.libdir);
405 } else if (0 == strcmp(opal_info_path_incdir, scope)) {
406 opal_info_show_path(opal_info_path_incdir, opal_install_dirs.includedir);
407 } else if (0 == strcmp(opal_info_path_mandir, scope)) {
408 opal_info_show_path(opal_info_path_mandir, opal_install_dirs.mandir);
409 } else if (0 == strcmp(opal_info_path_pkglibdir, scope)) {
410 opal_info_show_path(opal_info_path_pkglibdir, opal_install_dirs.opallibdir);
411 } else if (0 == strcmp(opal_info_path_sysconfdir, scope)) {
412 opal_info_show_path(opal_info_path_sysconfdir, opal_install_dirs.sysconfdir);
413 } else if (0 == strcmp(opal_info_path_exec_prefix, scope)) {
414 opal_info_show_path(opal_info_path_exec_prefix, opal_install_dirs.exec_prefix);
415 } else if (0 == strcmp(opal_info_path_sbindir, scope)) {
416 opal_info_show_path(opal_info_path_sbindir, opal_install_dirs.sbindir);
417 } else if (0 == strcmp(opal_info_path_libexecdir, scope)) {
418 opal_info_show_path(opal_info_path_libexecdir, opal_install_dirs.libexecdir);
419 } else if (0 == strcmp(opal_info_path_datarootdir, scope)) {
420 opal_info_show_path(opal_info_path_datarootdir, opal_install_dirs.datarootdir);
421 } else if (0 == strcmp(opal_info_path_datadir, scope)) {
422 opal_info_show_path(opal_info_path_datadir, opal_install_dirs.datadir);
423 } else if (0 == strcmp(opal_info_path_sharedstatedir, scope)) {
424 opal_info_show_path(opal_info_path_sharedstatedir, opal_install_dirs.sharedstatedir);
425 } else if (0 == strcmp(opal_info_path_localstatedir, scope)) {
426 opal_info_show_path(opal_info_path_localstatedir, opal_install_dirs.localstatedir);
427 } else if (0 == strcmp(opal_info_path_infodir, scope)) {
428 opal_info_show_path(opal_info_path_infodir, opal_install_dirs.infodir);
429 } else if (0 == strcmp(opal_info_path_pkgdatadir, scope)) {
430 opal_info_show_path(opal_info_path_pkgdatadir, opal_install_dirs.opaldatadir);
431 } else if (0 == strcmp(opal_info_path_pkgincludedir, scope)) {
432 opal_info_show_path(opal_info_path_pkgincludedir, opal_install_dirs.opalincludedir);
433 } else {
434 char *usage = opal_cmd_line_get_usage_msg(cmd_line);
435 opal_show_help("help-opal_info.txt", "usage", true, usage);
436 free(usage);
437 exit(1);
438 }
439 }
440 }
441 }
442
opal_info_do_params(bool want_all_in,bool want_internal,opal_pointer_array_t * mca_types,opal_pointer_array_t * component_map,opal_cmd_line_t * opal_info_cmd_line)443 void opal_info_do_params(bool want_all_in, bool want_internal,
444 opal_pointer_array_t *mca_types,
445 opal_pointer_array_t *component_map,
446 opal_cmd_line_t *opal_info_cmd_line)
447 {
448 mca_base_var_info_lvl_t max_level = OPAL_INFO_LVL_1;
449 int count;
450 char *type, *component, *str;
451 bool found;
452 int i;
453 bool want_all = false;
454 char *p;
455
456 if (opal_cmd_line_is_taken(opal_info_cmd_line, "param")) {
457 p = "param";
458 } else if (opal_cmd_line_is_taken(opal_info_cmd_line, "params")) {
459 p = "params";
460 } else {
461 p = "foo"; /* should never happen, but protect against segfault */
462 }
463
464 if (NULL != (str = opal_cmd_line_get_param (opal_info_cmd_line, "level", 0, 0))) {
465 char *tmp;
466
467 errno = 0;
468 max_level = strtol (str, &tmp, 10) + OPAL_INFO_LVL_1 - 1;
469 if (0 != errno || '\0' != tmp[0] || max_level < OPAL_INFO_LVL_1 || max_level > OPAL_INFO_LVL_9) {
470 char *usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
471 opal_show_help("help-opal_info.txt", "invalid-level", true, str);
472 free(usage);
473 exit(1);
474 }
475 } else if (want_all_in) {
476 /* if not specified default to level 9 if all components are requested */
477 max_level = OPAL_INFO_LVL_9;
478 }
479
480 if (want_all_in) {
481 want_all = true;
482 } else {
483 /* See if the special param "all" was given to --param; that
484 * supercedes any individual type
485 */
486 count = opal_cmd_line_get_ninsts(opal_info_cmd_line, p);
487 for (i = 0; i < count; ++i) {
488 type = opal_cmd_line_get_param(opal_info_cmd_line, p, (int)i, 0);
489 if (0 == strcmp(opal_info_type_all, type)) {
490 want_all = true;
491 break;
492 }
493 }
494 }
495
496 /* Show the params */
497
498 if (want_all) {
499 opal_info_show_component_version(mca_types, component_map, opal_info_type_all,
500 opal_info_component_all, opal_info_ver_full,
501 opal_info_ver_all);
502 for (i = 0; i < mca_types->size; ++i) {
503 if (NULL == (type = (char *)opal_pointer_array_get_item(mca_types, i))) {
504 continue;
505 }
506 opal_info_show_mca_params(type, opal_info_component_all, max_level, want_internal);
507 }
508 } else {
509 for (i = 0; i < count; ++i) {
510 type = opal_cmd_line_get_param(opal_info_cmd_line, p, (int)i, 0);
511 component = opal_cmd_line_get_param(opal_info_cmd_line, p, (int)i, 1);
512
513 for (found = false, i = 0; i < mca_types->size; ++i) {
514 if (NULL == (str = (char *)opal_pointer_array_get_item(mca_types, i))) {
515 continue;
516 }
517 if (0 == strcmp(str, type)) {
518 found = true;
519 break;
520 }
521 }
522
523 if (!found) {
524 char *usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
525 opal_show_help("help-opal_info.txt", "not-found", true, type);
526 free(usage);
527 exit(1);
528 }
529
530 opal_info_show_component_version(mca_types, component_map, type,
531 component, opal_info_ver_full,
532 opal_info_ver_all);
533 opal_info_show_mca_params(type, component, max_level, want_internal);
534 }
535 }
536 }
537
opal_info_err_params(opal_pointer_array_t * component_map)538 void opal_info_err_params(opal_pointer_array_t *component_map)
539 {
540 opal_info_component_map_t *map=NULL, *mptr;
541 int i;
542
543 /* all we want to do is display the LAST entry in the
544 * component_map array as this is the one that generated the error
545 */
546 for (i=0; i < component_map->size; i++) {
547 if (NULL == (mptr = (opal_info_component_map_t*)opal_pointer_array_get_item(component_map, i))) {
548 continue;
549 }
550 map = mptr;
551 }
552 if (NULL == map) {
553 fprintf(stderr, "opal_info_err_params: map not found\n");
554 return;
555 }
556 opal_info_show_mca_params(map->type, opal_info_component_all, OPAL_INFO_LVL_9, true);
557 fprintf(stderr, "\n");
558 return;
559 }
560
opal_info_do_type(opal_cmd_line_t * opal_info_cmd_line)561 void opal_info_do_type(opal_cmd_line_t *opal_info_cmd_line)
562 {
563 mca_base_var_info_lvl_t max_level = OPAL_INFO_LVL_1;
564 int count;
565 char *type, *str;
566 int i, j, k, len, ret;
567 char *p;
568 const mca_base_var_t *var;
569 char** strings, *message;
570 const mca_base_var_group_t *group;
571 p = "type";
572
573 if (NULL != (str = opal_cmd_line_get_param (opal_info_cmd_line, "level", 0, 0))) {
574 char *tmp;
575
576 errno = 0;
577 max_level = strtol (str, &tmp, 10) + OPAL_INFO_LVL_1 - 1;
578 if (0 != errno || '\0' != tmp[0] || max_level < OPAL_INFO_LVL_1 || max_level > OPAL_INFO_LVL_9) {
579 char *usage = opal_cmd_line_get_usage_msg(opal_info_cmd_line);
580 opal_show_help("help-opal_info.txt", "invalid-level", true, str);
581 free(usage);
582 exit(1);
583 }
584 }
585
586 count = opal_cmd_line_get_ninsts(opal_info_cmd_line, p);
587 len = mca_base_var_get_count ();
588
589 for (k = 0; k < count; ++k) {
590 type = opal_cmd_line_get_param(opal_info_cmd_line, p, k, 0);
591 for (i = 0; i < len; ++i) {
592 ret = mca_base_var_get (i, &var);
593 if (OPAL_SUCCESS != ret) {
594 continue;
595 }
596 if (0 == strcmp(type, ompi_var_type_names[var->mbv_type]) && (var->mbv_info_lvl <= max_level)) {
597 ret = mca_base_var_dump(var->mbv_index, &strings, !opal_info_pretty ? MCA_BASE_VAR_DUMP_PARSABLE : MCA_BASE_VAR_DUMP_READABLE);
598 if (OPAL_SUCCESS != ret) {
599 continue;
600 }
601 (void) mca_base_var_group_get(var->mbv_group_index, &group);
602 for (j = 0 ; strings[j] ; ++j) {
603 if (0 == j && opal_info_pretty) {
604 asprintf (&message, "MCA %s", group->group_framework);
605 opal_info_out(message, message, strings[j]);
606 free(message);
607 } else {
608 opal_info_out("", "", strings[j]);
609 }
610 free(strings[j]);
611 }
612 free(strings);
613 }
614 }
615 }
616 }
617
opal_info_show_mca_group_params(const mca_base_var_group_t * group,mca_base_var_info_lvl_t max_level,bool want_internal)618 static void opal_info_show_mca_group_params(const mca_base_var_group_t *group, mca_base_var_info_lvl_t max_level, bool want_internal)
619 {
620 const int *variables, *groups;
621 const mca_base_pvar_t *pvar;
622 const char *group_component;
623 const mca_base_var_t *var;
624 char **strings, *message;
625 bool requested = true;
626 int ret, i, j, count;
627
628 variables = OPAL_VALUE_ARRAY_GET_BASE(&group->group_vars, const int);
629 count = opal_value_array_get_size((opal_value_array_t *)&group->group_vars);
630
631 /* the default component name is "base". depending on how the
632 * group was registered the group may or not have this set. */
633 group_component = group->group_component ? group->group_component : "base";
634
635 /* check if this group may be disabled due to a selection variable */
636 if (0 != strcmp (group_component, "base")) {
637 int var_id;
638
639 /* read the selection parameter */
640 var_id = mca_base_var_find (group->group_project, group->group_framework, NULL, NULL);
641 if (0 <= var_id) {
642 const mca_base_var_storage_t *value=NULL;
643 char **requested_components;
644 bool include_mode;
645
646 mca_base_var_get_value (var_id, &value, NULL, NULL);
647 if (NULL != value && NULL != value->stringval && '\0' != value->stringval[0]) {
648 mca_base_component_parse_requested (value->stringval, &include_mode, &requested_components);
649
650 for (i = 0, requested = !include_mode ; requested_components[i] ; ++i) {
651 if (0 == strcmp (requested_components[i], group_component)) {
652 requested = include_mode;
653 break;
654 }
655 }
656
657 opal_argv_free (requested_components);
658 }
659 }
660 }
661
662 const mca_base_var_group_t *curr_group = NULL;
663 char *component_msg = NULL;
664 asprintf(&component_msg, " %s", group_component);
665
666 for (i = 0 ; i < count ; ++i) {
667 ret = mca_base_var_get(variables[i], &var);
668 if (OPAL_SUCCESS != ret || ((var->mbv_flags & MCA_BASE_VAR_FLAG_INTERNAL) &&
669 !want_internal) ||
670 max_level < var->mbv_info_lvl) {
671 continue;
672 }
673
674 if (opal_info_pretty && curr_group != group) {
675 asprintf(&message, "MCA%s %s%s", requested ? "" : " (-)",
676 group->group_framework,
677 component_msg ? component_msg : "");
678 opal_info_out(message, message, "---------------------------------------------------");
679 free(message);
680 curr_group = group;
681 }
682
683 ret = mca_base_var_dump(variables[i], &strings, !opal_info_pretty ? MCA_BASE_VAR_DUMP_PARSABLE : MCA_BASE_VAR_DUMP_READABLE);
684 if (OPAL_SUCCESS != ret) {
685 continue;
686 }
687
688 for (j = 0 ; strings[j] ; ++j) {
689 if (0 == j && opal_info_pretty) {
690 asprintf (&message, "MCA%s %s%s", requested ? "" : " (-)",
691 group->group_framework,
692 component_msg ? component_msg : "");
693 opal_info_out(message, message, strings[j]);
694 free(message);
695 } else {
696 opal_info_out("", "", strings[j]);
697 }
698 free(strings[j]);
699 }
700 if (!opal_info_pretty) {
701 /* generate an entry indicating whether this variable is disabled or not. if the
702 * format in mca_base_var/pvar.c changes this needs to be changed as well */
703 asprintf (&message, "mca:%s:%s:param:%s:disabled:%s", group->group_framework,
704 group_component, var->mbv_full_name, requested ? "false" : "true");
705 opal_info_out("", "", message);
706 free (message);
707 }
708 free(strings);
709 }
710
711 variables = OPAL_VALUE_ARRAY_GET_BASE(&group->group_pvars, const int);
712 count = opal_value_array_get_size((opal_value_array_t *)&group->group_pvars);
713
714 for (i = 0 ; i < count ; ++i) {
715 ret = mca_base_pvar_get(variables[i], &pvar);
716 if (OPAL_SUCCESS != ret || max_level < pvar->verbosity) {
717 continue;
718 }
719
720 if (opal_info_pretty && curr_group != group) {
721 asprintf(&message, "MCA%s %s%s", requested ? "" : " (-)",
722 group->group_framework,
723 component_msg ? component_msg : "");
724 opal_info_out(message, message, "---------------------------------------------------");
725 free(message);
726 curr_group = group;
727 }
728
729 ret = mca_base_pvar_dump (variables[i], &strings, !opal_info_pretty ? MCA_BASE_VAR_DUMP_PARSABLE : MCA_BASE_VAR_DUMP_READABLE);
730 if (OPAL_SUCCESS != ret) {
731 continue;
732 }
733
734 for (j = 0 ; strings[j] ; ++j) {
735 if (0 == j && opal_info_pretty) {
736 asprintf (&message, "MCA%s %s%s", requested ? "" : " (-)",
737 group->group_framework,
738 component_msg ? component_msg : "");
739 opal_info_out(message, message, strings[j]);
740 free(message);
741 } else {
742 opal_info_out("", "", strings[j]);
743 }
744 free(strings[j]);
745 }
746 if (!opal_info_pretty) {
747 /* generate an entry indicating whether this variable is disabled or not. if the
748 * format in mca_base_var/pvar.c changes this needs to be changed as well */
749 asprintf (&message, "mca:%s:%s:pvar:%s:disabled:%s", group->group_framework,
750 group_component, pvar->name, requested ? "false" : "true");
751 opal_info_out("", "", message);
752 free (message);
753 }
754 free(strings);
755 }
756
757 groups = OPAL_VALUE_ARRAY_GET_BASE(&group->group_subgroups, const int);
758 count = opal_value_array_get_size((opal_value_array_t *)&group->group_subgroups);
759
760 for (i = 0 ; i < count ; ++i) {
761 ret = mca_base_var_group_get(groups[i], &group);
762 if (OPAL_SUCCESS != ret) {
763 continue;
764 }
765 opal_info_show_mca_group_params(group, max_level, want_internal);
766 }
767 free(component_msg);
768 }
769
opal_info_show_mca_params(const char * type,const char * component,mca_base_var_info_lvl_t max_level,bool want_internal)770 void opal_info_show_mca_params(const char *type, const char *component,
771 mca_base_var_info_lvl_t max_level, bool want_internal)
772 {
773 const mca_base_var_group_t *group;
774 int ret;
775
776 if (0 == strcmp (component, "all")) {
777 ret = mca_base_var_group_find("*", type, NULL);
778 if (0 > ret) {
779 return;
780 }
781
782 (void) mca_base_var_group_get(ret, &group);
783
784 opal_info_show_mca_group_params(group, max_level, want_internal);
785 } else {
786 ret = mca_base_var_group_find("*", type, component);
787 if (0 > ret) {
788 return;
789 }
790
791 (void) mca_base_var_group_get(ret, &group);
792 opal_info_show_mca_group_params(group, max_level, want_internal);
793 }
794 }
795
796
797
opal_info_do_arch()798 void opal_info_do_arch()
799 {
800 opal_info_out("Configured architecture", "config:arch", OPAL_ARCH);
801 }
802
803
opal_info_do_hostname()804 void opal_info_do_hostname()
805 {
806 opal_info_out("Configure host", "config:host", OPAL_CONFIGURE_HOST);
807 }
808
809
escape_quotes(const char * value)810 static char *escape_quotes(const char *value)
811 {
812 const char *src;
813 int num_quotes = 0;
814 for (src = value; src != NULL && *src != '\0'; ++src) {
815 if ('"' == *src) {
816 ++num_quotes;
817 }
818 }
819
820 // If there are no quotes in the string, there's nothing to do
821 if (0 == num_quotes) {
822 return NULL;
823 }
824
825 // If we have quotes, make a new string. Copy over the old
826 // string, escaping the quotes along the way. This is simple and
827 // clear to read; it's not particularly efficient (performance is
828 // definitely not important here).
829 char *quoted_value;
830 quoted_value = calloc(1, strlen(value) + num_quotes + 1);
831 if (NULL == quoted_value) {
832 return NULL;
833 }
834
835 char *dest;
836 for (src = value, dest = quoted_value; *src != '\0'; ++src, ++dest) {
837 if ('"' == *src) {
838 *dest++ = '\\';
839 }
840 *dest = *src;
841 }
842
843 return quoted_value;
844 }
845
846
847 /*
848 * Private variables - set some reasonable screen size defaults
849 */
850
851 static int centerpoint = 24;
852 static int screen_width = 78;
853
854 /*
855 * Prints the passed message in a pretty or parsable format.
856 */
opal_info_out(const char * pretty_message,const char * plain_message,const char * value)857 void opal_info_out(const char *pretty_message, const char *plain_message, const char *value)
858 {
859 size_t len, max_value_width, value_offset;
860 char *spaces = NULL;
861 char *filler = NULL;
862 char *pos, *v, savev, *v_to_free;
863
864 #ifdef HAVE_ISATTY
865 /* If we have isatty(), if this is not a tty, then disable
866 * wrapping for grep-friendly behavior
867 */
868 if (0 == isatty(STDOUT_FILENO)) {
869 screen_width = INT_MAX;
870 }
871 #endif
872
873 #ifdef TIOCGWINSZ
874 if (screen_width < INT_MAX) {
875 struct winsize size;
876 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, (char*) &size) >= 0) {
877 screen_width = size.ws_col;
878 }
879 }
880 #endif
881
882 /* Sanity check (allow NULL to mean "") */
883 if (NULL == value) {
884 value = "";
885 }
886
887 /* Strip leading and trailing whitespace from the string value */
888 value_offset = strspn(value, " ");
889
890 v = v_to_free = strdup(value + value_offset);
891 len = strlen(v);
892
893 if (len > 0) {
894 while (len > 0 && isspace(v[len-1])) len--;
895 v[len] = '\0';
896 }
897
898 if (opal_info_pretty && NULL != pretty_message) {
899 if (centerpoint > (int)strlen(pretty_message)) {
900 asprintf(&spaces, "%*s", centerpoint -
901 (int)strlen(pretty_message), " ");
902 } else {
903 spaces = strdup("");
904 #if OPAL_ENABLE_DEBUG
905 if (centerpoint < (int)strlen(pretty_message)) {
906 opal_show_help("help-opal_info.txt",
907 "developer warning: field too long", false,
908 pretty_message, centerpoint);
909 }
910 #endif
911 }
912 max_value_width = screen_width - strlen(spaces) - strlen(pretty_message) - 2;
913 if (0 < strlen(pretty_message)) {
914 asprintf(&filler, "%s%s: ", spaces, pretty_message);
915 } else {
916 asprintf(&filler, "%s ", spaces);
917 }
918 free(spaces);
919 spaces = NULL;
920
921 while (true) {
922 if (strlen(v) < max_value_width) {
923 printf("%s%s\n", filler, v);
924 break;
925 } else {
926 asprintf(&spaces, "%*s", centerpoint + 2, " ");
927
928 /* Work backwards to find the first space before
929 * max_value_width
930 */
931 savev = v[max_value_width];
932 v[max_value_width] = '\0';
933 pos = (char*)strrchr(v, (int)' ');
934 v[max_value_width] = savev;
935 if (NULL == pos) {
936 /* No space found < max_value_width. Look for the first
937 * space after max_value_width.
938 */
939 pos = strchr(&v[max_value_width], ' ');
940
941 if (NULL == pos) {
942
943 /* There's just no spaces. So just print it and be done. */
944
945 printf("%s%s\n", filler, v);
946 break;
947 } else {
948 *pos = '\0';
949 printf("%s%s\n", filler, v);
950 v = pos + 1;
951 }
952 } else {
953 *pos = '\0';
954 printf("%s%s\n", filler, v);
955 v = pos + 1;
956 }
957
958 /* Reset for the next iteration */
959 free(filler);
960 filler = strdup(spaces);
961 free(spaces);
962 spaces = NULL;
963 }
964 }
965 if (NULL != filler) {
966 free(filler);
967 }
968 if (NULL != spaces) {
969 free(spaces);
970 }
971 } else {
972 if (NULL != plain_message && 0 < strlen(plain_message)) {
973 // Escape any double quotes in the value.
974 char *quoted_value;
975 quoted_value = escape_quotes(value);
976 if (NULL != quoted_value) {
977 value = quoted_value;
978 }
979
980 char *colon = strchr(value, ':');
981 if (NULL != colon) {
982 printf("%s:\"%s\"\n", plain_message, value);
983 } else {
984 printf("%s:%s\n", plain_message, value);
985 }
986
987 if (NULL != quoted_value) {
988 free(quoted_value);
989 }
990 } else {
991 printf("%s\n", value);
992 }
993 }
994 if (NULL != v_to_free) {
995 free(v_to_free);
996 }
997 }
998
999 /*
1000 * Prints the passed integer in a pretty or parsable format.
1001 */
opal_info_out_int(const char * pretty_message,const char * plain_message,int value)1002 void opal_info_out_int(const char *pretty_message,
1003 const char *plain_message,
1004 int value)
1005 {
1006 char *valstr;
1007
1008 asprintf(&valstr, "%d", (int)value);
1009 opal_info_out(pretty_message, plain_message, valstr);
1010 free(valstr);
1011 }
1012
1013 /*
1014 * Show all the components of a specific type/component combo (component may be
1015 * a wildcard)
1016 */
opal_info_show_component_version(opal_pointer_array_t * mca_types,opal_pointer_array_t * component_map,const char * type_name,const char * component_name,const char * scope,const char * ver_type)1017 void opal_info_show_component_version(opal_pointer_array_t *mca_types,
1018 opal_pointer_array_t *component_map,
1019 const char *type_name,
1020 const char *component_name,
1021 const char *scope, const char *ver_type)
1022 {
1023 bool want_all_components = false;
1024 bool want_all_types = false;
1025 bool found;
1026 mca_base_component_list_item_t *cli;
1027 mca_base_failed_component_t *cli_failed;
1028 int j;
1029 char *pos;
1030 opal_info_component_map_t *map;
1031
1032 /* see if all components wanted */
1033 if (0 == strcmp(opal_info_component_all, component_name)) {
1034 want_all_components = true;
1035 }
1036
1037 /* see if all types wanted */
1038 if (0 != strcmp(opal_info_type_all, type_name)) {
1039 /* Check to see if the type is valid */
1040
1041 for (found = false, j = 0; j < mca_types->size; ++j) {
1042 if (NULL == (pos = (char*)opal_pointer_array_get_item(mca_types, j))) {
1043 continue;
1044 }
1045 if (0 == strcmp(pos, type_name)) {
1046 found = true;
1047 break;
1048 }
1049 }
1050
1051 if (!found) {
1052 return;
1053 }
1054 } else {
1055 want_all_types = true;
1056 }
1057
1058 /* Now that we have a valid type, find the right components */
1059 for (j=0; j < component_map->size; j++) {
1060 if (NULL == (map = (opal_info_component_map_t*)opal_pointer_array_get_item(component_map, j))) {
1061 continue;
1062 }
1063 if ((want_all_types || 0 == strcmp(type_name, map->type)) && map->components) {
1064 /* found it! */
1065 OPAL_LIST_FOREACH(cli, map->components, mca_base_component_list_item_t) {
1066 const mca_base_component_t *component = cli->cli_component;
1067 if (want_all_components ||
1068 0 == strcmp(component->mca_component_name, component_name)) {
1069 opal_info_show_mca_version(component, scope, ver_type);
1070 }
1071 }
1072
1073 /* found it! */
1074 OPAL_LIST_FOREACH(cli_failed, map->failed_components, mca_base_failed_component_t) {
1075 mca_base_component_repository_item_t *ri = cli_failed->comp;
1076 if (want_all_components ||
1077 0 == strcmp(component_name, ri->ri_name) ) {
1078 opal_info_show_failed_component(ri, cli_failed->error_msg);
1079 }
1080 }
1081
1082 if (!want_all_types) {
1083 break;
1084 }
1085 }
1086 }
1087 }
1088
1089
opal_info_show_failed_component(const mca_base_component_repository_item_t * ri,const char * error_msg)1090 static void opal_info_show_failed_component(const mca_base_component_repository_item_t* ri,
1091 const char *error_msg)
1092 {
1093 char *message, *content;
1094
1095 if (opal_info_pretty) {
1096 asprintf(&message, "MCA %s", ri->ri_type);
1097 asprintf(&content, "%s (failed to load) %s", ri->ri_name, error_msg);
1098
1099 opal_info_out(message, NULL, content);
1100
1101 free(message);
1102 free(content);
1103 } else {
1104 asprintf(&message, "mca:%s:%s:failed", ri->ri_type, ri->ri_name);
1105 asprintf(&content, "%s", error_msg);
1106
1107 opal_info_out(NULL, message, content);
1108
1109 free(message);
1110 free(content);
1111 }
1112 }
1113
1114 /*
1115 * Given a component, display its relevant version(s)
1116 */
opal_info_show_mca_version(const mca_base_component_t * component,const char * scope,const char * ver_type)1117 void opal_info_show_mca_version(const mca_base_component_t* component,
1118 const char *scope, const char *ver_type)
1119 {
1120 bool printed;
1121 bool want_mca = false;
1122 bool want_type = false;
1123 bool want_component = false;
1124 char *message, *content;
1125 char *mca_version;
1126 char *api_version;
1127 char *component_version;
1128 char *tmp;
1129
1130 if (0 == strcmp(ver_type, opal_info_ver_all) ||
1131 0 == strcmp(ver_type, opal_info_ver_mca)) {
1132 want_mca = true;
1133 }
1134
1135 if (0 == strcmp(ver_type, opal_info_ver_all) ||
1136 0 == strcmp(ver_type, opal_info_ver_type)) {
1137 want_type = true;
1138 }
1139
1140 if (0 == strcmp(ver_type, opal_info_ver_all) ||
1141 0 == strcmp(ver_type, opal_info_ver_component)) {
1142 want_component = true;
1143 }
1144
1145 mca_version = opal_info_make_version_str(scope, component->mca_major_version,
1146 component->mca_minor_version,
1147 component->mca_release_version, "",
1148 "");
1149 api_version = opal_info_make_version_str(scope, component->mca_type_major_version,
1150 component->mca_type_minor_version,
1151 component->mca_type_release_version, "",
1152 "");
1153 component_version = opal_info_make_version_str(scope, component->mca_component_major_version,
1154 component->mca_component_minor_version,
1155 component->mca_component_release_version,
1156 "", "");
1157 if (opal_info_pretty) {
1158 asprintf(&message, "MCA %s", component->mca_type_name);
1159 printed = false;
1160 asprintf(&content, "%s (", component->mca_component_name);
1161
1162 if (want_mca) {
1163 asprintf(&tmp, "%sMCA v%s", content, mca_version);
1164 free(content);
1165 content = tmp;
1166 printed = true;
1167 }
1168
1169 if (want_type) {
1170 if (printed) {
1171 asprintf(&tmp, "%s, ", content);
1172 free(content);
1173 content = tmp;
1174 }
1175 asprintf(&tmp, "%sAPI v%s", content, api_version);
1176 free(content);
1177 content = tmp;
1178 printed = true;
1179 }
1180
1181 if (want_component) {
1182 if (printed) {
1183 asprintf(&tmp, "%s, ", content);
1184 free(content);
1185 content = tmp;
1186 }
1187 asprintf(&tmp, "%sComponent v%s", content, component_version);
1188 free(content);
1189 content = tmp;
1190 printed = true;
1191 }
1192 if (NULL != content) {
1193 asprintf(&tmp, "%s)", content);
1194 free(content);
1195 } else {
1196 tmp = NULL;
1197 }
1198
1199 opal_info_out(message, NULL, tmp);
1200 free(message);
1201 if (NULL != tmp) {
1202 free(tmp);
1203 }
1204
1205 } else {
1206 asprintf(&message, "mca:%s:%s:version", component->mca_type_name, component->mca_component_name);
1207 if (want_mca) {
1208 asprintf(&tmp, "mca:%s", mca_version);
1209 opal_info_out(NULL, message, tmp);
1210 free(tmp);
1211 }
1212 if (want_type) {
1213 asprintf(&tmp, "api:%s", api_version);
1214 opal_info_out(NULL, message, tmp);
1215 free(tmp);
1216 }
1217 if (want_component) {
1218 asprintf(&tmp, "component:%s", component_version);
1219 opal_info_out(NULL, message, tmp);
1220 free(tmp);
1221 }
1222 free(message);
1223 }
1224
1225 if (NULL != mca_version) {
1226 free(mca_version);
1227 }
1228 if (NULL != api_version) {
1229 free(api_version);
1230 }
1231 if (NULL != component_version) {
1232 free(component_version);
1233 }
1234 }
1235
1236
opal_info_make_version_str(const char * scope,int major,int minor,int release,const char * greek,const char * repo)1237 char *opal_info_make_version_str(const char *scope,
1238 int major, int minor, int release,
1239 const char *greek,
1240 const char *repo)
1241 {
1242 char *str = NULL, *tmp;
1243 char temp[BUFSIZ];
1244
1245 temp[BUFSIZ - 1] = '\0';
1246 if (0 == strcmp(scope, opal_info_ver_full) ||
1247 0 == strcmp(scope, opal_info_ver_all)) {
1248 snprintf(temp, BUFSIZ - 1, "%d.%d.%d", major, minor, release);
1249 str = strdup(temp);
1250 if (NULL != greek) {
1251 asprintf(&tmp, "%s%s", str, greek);
1252 free(str);
1253 str = tmp;
1254 }
1255 } else if (0 == strcmp(scope, opal_info_ver_major)) {
1256 snprintf(temp, BUFSIZ - 1, "%d", major);
1257 } else if (0 == strcmp(scope, opal_info_ver_minor)) {
1258 snprintf(temp, BUFSIZ - 1, "%d", minor);
1259 } else if (0 == strcmp(scope, opal_info_ver_release)) {
1260 snprintf(temp, BUFSIZ - 1, "%d", release);
1261 } else if (0 == strcmp(scope, opal_info_ver_greek)) {
1262 str = strdup(greek);
1263 } else if (0 == strcmp(scope, opal_info_ver_repo)) {
1264 str = strdup(repo);
1265 }
1266
1267 if (NULL == str) {
1268 str = strdup(temp);
1269 }
1270
1271 return str;
1272 }
1273
opal_info_show_opal_version(const char * scope)1274 void opal_info_show_opal_version(const char *scope)
1275 {
1276 char *tmp, *tmp2;
1277
1278 asprintf(&tmp, "%s:version:full", opal_info_type_opal);
1279 tmp2 = opal_info_make_version_str(scope,
1280 OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
1281 OPAL_RELEASE_VERSION,
1282 OPAL_GREEK_VERSION,
1283 OPAL_REPO_REV);
1284 opal_info_out("OPAL", tmp, tmp2);
1285 free(tmp);
1286 free(tmp2);
1287 asprintf(&tmp, "%s:version:repo", opal_info_type_opal);
1288 opal_info_out("OPAL repo revision", tmp, OPAL_REPO_REV);
1289 free(tmp);
1290 asprintf(&tmp, "%s:version:release_date", opal_info_type_opal);
1291 opal_info_out("OPAL release date", tmp, OPAL_RELEASE_DATE);
1292 free(tmp);
1293 }
1294