1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2005 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2014 Intel, Inc. All rights reserved.
13 * Copyright (c) 2014-2015 Cisco Systems, Inc. All rights reserved.
14 * $COPYRIGHT$
15 *
16 * Additional copyrights may follow
17 *
18 * $HEADER$
19 */
20
21 #include "opal_config.h"
22
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "opal/util/cmd_line.h"
27 #include "opal/util/argv.h"
28 #include "opal/util/opal_environ.h"
29 #include "opal/util/show_help.h"
30 #include "opal/mca/base/base.h"
31 #include "opal/constants.h"
32
33
34 /*
35 * Private variables
36 */
37
38 /*
39 * Private functions
40 */
41 static int process_arg(const char *param, const char *value,
42 char ***params, char ***values);
43 static void add_to_env(char **params, char **values, char ***env);
44
45
46 /*
47 * Add -mca to the possible command line options list
48 */
mca_base_cmd_line_setup(opal_cmd_line_t * cmd)49 int mca_base_cmd_line_setup(opal_cmd_line_t *cmd)
50 {
51 int ret = OPAL_SUCCESS;
52
53 ret = opal_cmd_line_make_opt3(cmd, '\0', OPAL_MCA_CMD_LINE_ID, OPAL_MCA_CMD_LINE_ID, 2,
54 "Pass context-specific MCA parameters; they are considered global if --g"OPAL_MCA_CMD_LINE_ID" is not used and only one context is specified (arg0 is the parameter name; arg1 is the parameter value)");
55 if (OPAL_SUCCESS != ret) {
56 return ret;
57 }
58
59 ret = opal_cmd_line_make_opt3(cmd, '\0', "g"OPAL_MCA_CMD_LINE_ID, "g"OPAL_MCA_CMD_LINE_ID, 2,
60 "Pass global MCA parameters that are applicable to all contexts (arg0 is the parameter name; arg1 is the parameter value)");
61
62 if (OPAL_SUCCESS != ret) {
63 return ret;
64 }
65
66 {
67 opal_cmd_line_init_t entry =
68 {"mca_base_param_file_prefix", '\0', "am", NULL, 1,
69 NULL, OPAL_CMD_LINE_TYPE_STRING,
70 "Aggregate MCA parameter set file list",
71 OPAL_CMD_LINE_OTYPE_LAUNCH
72 };
73 ret = opal_cmd_line_make_opt_mca(cmd, entry);
74 if (OPAL_SUCCESS != ret) {
75 return ret;
76 }
77 }
78
79 {
80 opal_cmd_line_init_t entry =
81 {"mca_base_envar_file_prefix", '\0', "tune", NULL, 1,
82 NULL, OPAL_CMD_LINE_TYPE_STRING,
83 "Application profile options file list",
84 OPAL_CMD_LINE_OTYPE_DEBUG
85 };
86 ret = opal_cmd_line_make_opt_mca(cmd, entry);
87 if (OPAL_SUCCESS != ret) {
88 return ret;
89 }
90 }
91
92 return ret;
93 }
94
95
96 /*
97 * Look for and handle any -mca options on the command line
98 */
mca_base_cmd_line_process_args(opal_cmd_line_t * cmd,char *** context_env,char *** global_env)99 int mca_base_cmd_line_process_args(opal_cmd_line_t *cmd,
100 char ***context_env, char ***global_env)
101 {
102 int i, num_insts, rc;
103 char **params;
104 char **values;
105
106 /* If no relevant parameters were given, just return */
107
108 if (!opal_cmd_line_is_taken(cmd, OPAL_MCA_CMD_LINE_ID) &&
109 !opal_cmd_line_is_taken(cmd, "g"OPAL_MCA_CMD_LINE_ID)) {
110 return OPAL_SUCCESS;
111 }
112
113 /* Handle app context-specific parameters */
114
115 num_insts = opal_cmd_line_get_ninsts(cmd, OPAL_MCA_CMD_LINE_ID);
116 params = values = NULL;
117 for (i = 0; i < num_insts; ++i) {
118 if (OPAL_SUCCESS != (rc = process_arg(opal_cmd_line_get_param(cmd, OPAL_MCA_CMD_LINE_ID, i, 0),
119 opal_cmd_line_get_param(cmd, OPAL_MCA_CMD_LINE_ID, i, 1),
120 ¶ms, &values))) {
121 return rc;
122 }
123 }
124 if (NULL != params) {
125 add_to_env(params, values, context_env);
126 opal_argv_free(params);
127 opal_argv_free(values);
128 }
129
130 /* Handle global parameters */
131
132 num_insts = opal_cmd_line_get_ninsts(cmd, "g"OPAL_MCA_CMD_LINE_ID);
133 params = values = NULL;
134 for (i = 0; i < num_insts; ++i) {
135 if (OPAL_SUCCESS != (rc = process_arg(opal_cmd_line_get_param(cmd, "g"OPAL_MCA_CMD_LINE_ID, i, 0),
136 opal_cmd_line_get_param(cmd, "g"OPAL_MCA_CMD_LINE_ID, i, 1),
137 ¶ms, &values))) {
138 return rc;
139 }
140 }
141 if (NULL != params) {
142 add_to_env(params, values, global_env);
143 opal_argv_free(params);
144 opal_argv_free(values);
145 }
146
147 /* All done */
148
149 return OPAL_SUCCESS;
150 }
151
152
153
154 /*
155 * Process a single MCA argument.
156 */
process_arg(const char * param,const char * value,char *** params,char *** values)157 static int process_arg(const char *param, const char *value,
158 char ***params, char ***values)
159 {
160 int i;
161 char *p1;
162
163 /* check for quoted value */
164 if ('\"' == value[0] && '\"' == value[strlen(value)-1]) {
165 p1 = strdup(&value[1]);
166 p1[strlen(p1)-1] = '\0';
167 } else {
168 p1 = strdup(value);
169 }
170
171 /* Look to see if we've already got an -mca argument for the same
172 param. Check against the list of MCA param's that we've
173 already saved arguments for - if found, return an error. */
174
175 for (i = 0; NULL != *params && NULL != (*params)[i]; ++i) {
176 if (0 == strcmp(param, (*params)[i])) {
177 /* cannot use show_help here as it may not get out prior
178 * to the process exiting */
179 fprintf(stderr,
180 "---------------------------------------------------------------------------\n"
181 "The following MCA parameter has been listed multiple times on the\n"
182 "command line:\n\n"
183 " MCA param: %s\n\n"
184 "MCA parameters can only be listed once on a command line to ensure there\n"
185 "is no ambiguity as to its value. Please correct the situation and\n"
186 "try again.\n"
187 "---------------------------------------------------------------------------\n",
188 param);
189 free(p1);
190 return OPAL_ERROR;
191 }
192 }
193
194 /* If we didn't already have an value for the same param, save
195 this one away */
196 opal_argv_append_nosize(params, param);
197 opal_argv_append_nosize(values, p1);
198 free(p1);
199
200 return OPAL_SUCCESS;
201 }
202
203
add_to_env(char ** params,char ** values,char *** env)204 static void add_to_env(char **params, char **values, char ***env)
205 {
206 int i;
207 char *name;
208
209 /* Loop through all the args that we've gotten and make env
210 vars of the form OPAL_MCA_PREFIX*=value. */
211
212 for (i = 0; NULL != params && NULL != params[i]; ++i) {
213 (void) mca_base_var_env_name (params[i], &name);
214 opal_setenv(name, values[i], true, env);
215 free(name);
216 }
217 }
218
mca_base_cmd_line_wrap_args(char ** args)219 void mca_base_cmd_line_wrap_args(char **args)
220 {
221 int i;
222 char *tstr;
223
224 for (i=0; NULL != args && NULL != args[i]; i++) {
225 if (0 == strcmp(args[i], "-"OPAL_MCA_CMD_LINE_ID) ||
226 0 == strcmp(args[i], "--"OPAL_MCA_CMD_LINE_ID)) {
227 if (NULL == args[i+1] || NULL == args[i+2]) {
228 /* this should be impossible as the error would
229 * have been detected well before here, but just
230 * be safe */
231 return;
232 }
233 i += 2;
234 asprintf(&tstr, "\"%s\"", args[i]);
235 free(args[i]);
236 args[i] = tstr;
237 }
238 }
239 }
240