2 * Copyright (c) 2006-2007 Voltaire, Inc. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 * Implementation of opensm partition management configuration
41 #endif /* HAVE_CONFIG_H */
49 #include <iba/ib_types.h>
50 #include <opensm/osm_base.h>
51 #include <opensm/osm_partition.h>
52 #include <opensm/osm_subnet.h>
53 #include <opensm/osm_log.h>
55 #include <complib/cl_byteswap.h>
61 unsigned is_ipoib, mtu, rate, sl, scope_mask;
65 extern osm_prtn_t *osm_prtn_make_new(osm_log_t * p_log, osm_subn_t * p_subn,
66 const char *name, uint16_t pkey);
67 extern ib_api_status_t osm_prtn_add_all(osm_log_t * p_log,
69 osm_prtn_t * p, boolean_t full);
70 extern ib_api_status_t osm_prtn_add_port(osm_log_t * p_log,
71 osm_subn_t * p_subn, osm_prtn_t * p,
72 ib_net64_t guid, boolean_t full);
73 extern ib_api_status_t osm_prtn_add_mcgroup(osm_log_t * p_log,
74 osm_subn_t * p_subn, osm_prtn_t * p,
76 uint8_t mtu, uint8_t scope);
78 static int partition_create(unsigned lineno, struct part_conf *conf,
79 char *name, char *id, char *flag, char *flag_val)
84 if (!id && name && isdigit(*name)) {
92 pkey = (uint16_t) strtoul(id, &end, 0);
93 if (end == id || *end)
98 conf->p_prtn = osm_prtn_make_new(conf->p_log, conf->p_subn,
99 name, cl_hton16(pkey));
103 if (!conf->p_subn->opt.qos && conf->sl != OSM_DEFAULT_SL) {
104 OSM_LOG(conf->p_log, OSM_LOG_DEBUG, "Overriding SL %d"
105 " to default SL %d on partition %s"
106 " as QoS is not enabled.\n",
107 conf->sl, OSM_DEFAULT_SL, name);
108 conf->sl = OSM_DEFAULT_SL;
110 conf->p_prtn->sl = (uint8_t) conf->sl;
115 if (!conf->scope_mask) {
116 osm_prtn_add_mcgroup(conf->p_log, conf->p_subn, conf->p_prtn,
117 (uint8_t) conf->rate,
123 for (scope = 0; scope < 16; scope++) {
124 if (((1<<scope) & conf->scope_mask) == 0)
127 osm_prtn_add_mcgroup(conf->p_log, conf->p_subn, conf->p_prtn,
128 (uint8_t) conf->rate,
135 static int partition_add_flag(unsigned lineno, struct part_conf *conf,
136 char *flag, char *val)
138 int len = strlen(flag);
139 if (!strncmp(flag, "ipoib", len)) {
141 } else if (!strncmp(flag, "mtu", len)) {
142 if (!val || (conf->mtu = strtoul(val, NULL, 0)) == 0)
143 OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
144 "PARSE WARN: line %d: "
145 "flag \'mtu\' requires valid value"
146 " - skipped\n", lineno);
147 } else if (!strncmp(flag, "rate", len)) {
148 if (!val || (conf->rate = strtoul(val, NULL, 0)) == 0)
149 OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
150 "PARSE WARN: line %d: "
151 "flag \'rate\' requires valid value"
152 " - skipped\n", lineno);
153 } else if (!strncmp(flag, "scope", len)) {
155 if (!val || (scope = strtoul(val, NULL, 0)) == 0 || scope > 0xF)
156 OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
157 "PARSE WARN: line %d: "
158 "flag \'scope\' requires valid value"
159 " - skipped\n", lineno);
161 conf->scope_mask |= (1<<scope);
162 } else if (!strncmp(flag, "sl", len)) {
166 if (!val || !*val || (sl = strtoul(val, &end, 0)) > 15 ||
167 (*end && !isspace(*end)))
168 OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
169 "PARSE WARN: line %d: "
170 "flag \'sl\' requires valid value"
171 " - skipped\n", lineno);
174 } else if (!strncmp(flag, "defmember", len)) {
175 if (!val || (strncmp(val, "limited", strlen(val))
176 && strncmp(val, "full", strlen(val))))
177 OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
178 "PARSE WARN: line %d: "
179 "flag \'defmember\' requires valid value (limited or full)"
180 " - skipped\n", lineno);
182 conf->full = strncmp(val, "full", strlen(val)) == 0;
184 OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
185 "PARSE WARN: line %d: "
186 "unrecognized partition flag \'%s\'"
187 " - ignored\n", lineno, flag);
192 static int partition_add_port(unsigned lineno, struct part_conf *conf,
193 char *name, char *flag)
195 osm_prtn_t *p = conf->p_prtn;
197 boolean_t full = conf->full;
199 if (!name || !*name || !strncmp(name, "NONE", strlen(name)))
203 /* reset default membership to limited */
205 if (!strncmp(flag, "full", strlen(flag)))
207 else if (strncmp(flag, "limited", strlen(flag))) {
208 OSM_LOG(conf->p_log, OSM_LOG_VERBOSE,
209 "PARSE WARN: line %d: "
210 "unrecognized port flag \'%s\'."
211 " Assume \'limited\'\n", lineno, flag);
215 if (!strncmp(name, "ALL", strlen(name))) {
216 return osm_prtn_add_all(conf->p_log, conf->p_subn, p,
217 full) == IB_SUCCESS ? 0 : -1;
218 } else if (!strncmp(name, "SELF", strlen(name))) {
219 guid = cl_ntoh64(conf->p_subn->sm_port_guid);
222 guid = strtoull(name, &end, 0);
227 if (osm_prtn_add_port(conf->p_log, conf->p_subn, p,
228 cl_hton64(guid), full) != IB_SUCCESS)
234 /* conf file parser */
236 #define STRIP_HEAD_SPACES(p) while (*(p) == ' ' || *(p) == '\t' || \
237 *(p) == '\n') { (p)++; }
238 #define STRIP_TAIL_SPACES(p) { char *q = (p) + strlen(p); \
239 while ( q != (p) && ( *q == '\0' || \
240 *q == ' ' || *q == '\t' || \
241 *q == '\n')) { *q-- = '\0'; }; }
243 static int parse_name_token(char *str, char **name, char **val)
252 while (*p == ' ' || *p == '\t' || *p == '\n')
259 len = strlen(str) + 1;
263 while (q != p && (*q == '\0' || *q == ' ' || *q == '\t' || *q == '\n'))
272 while (*p == ' ' || *p == '\t' || *p == '\n')
276 len += (int)(q - str) + 1;
277 while (q != p && (*q == '\0' || *q == ' ' || *q == '\t' || *q == '\n'))
284 static struct part_conf *new_part_conf(osm_log_t * p_log, osm_subn_t * p_subn)
286 static struct part_conf part;
287 struct part_conf *conf = ∂
289 memset(conf, 0, sizeof(*conf));
291 conf->p_subn = p_subn;
294 conf->sl = OSM_DEFAULT_SL;
299 static int flush_part_conf(struct part_conf *conf)
301 memset(conf, 0, sizeof(*conf));
305 static int parse_part_conf(struct part_conf *conf, char *str, int lineno)
308 char *name, *id, *flag, *flval;
312 if (*p == '\t' || *p == '\0' || *p == '\n')
315 len += (int)(p - str);
323 OSM_LOG(conf->p_log, OSM_LOG_ERROR, "PARSE ERROR: line %d: "
324 "no partition definition found\n", lineno);
325 fprintf(stderr, "\nPARSE ERROR: line %d: "
326 "no partition definition found\n", lineno);
333 name = id = flag = flval = NULL;
339 ret = parse_name_token(p, &name, &id);
348 ret = parse_name_token(p, &flag, &flval);
350 OSM_LOG(conf->p_log, OSM_LOG_ERROR,
351 "PARSE ERROR: line %d: "
352 "bad partition flags\n", lineno);
353 fprintf(stderr, "\nPARSE ERROR: line %d: "
354 "bad partition flags\n", lineno);
359 partition_add_flag(lineno, conf, flag, flval);
362 if (p != str || (partition_create(lineno, conf,
363 name, id, flag, flval) < 0)) {
364 OSM_LOG(conf->p_log, OSM_LOG_ERROR, "PARSE ERROR: line %d: "
365 "bad partition definition\n", lineno);
366 fprintf(stderr, "\nPARSE ERROR: line %d: "
367 "bad partition definition\n", lineno);
377 ret = parse_name_token(p, &name, &flag);
378 if (partition_add_port(lineno, conf, name, flag) < 0) {
379 OSM_LOG(conf->p_log, OSM_LOG_ERROR,
380 "PARSE ERROR: line %d: "
381 "bad PortGUID\n", lineno);
382 fprintf(stderr, "PARSE ERROR: line %d: "
383 "bad PortGUID\n", lineno);
393 int osm_prtn_config_parse_file(osm_log_t * p_log, osm_subn_t * p_subn,
394 const char *file_name)
397 struct part_conf *conf = NULL;
401 file = fopen(file_name, "r");
403 OSM_LOG(p_log, OSM_LOG_VERBOSE,
404 "Cannot open config file \'%s\': %s\n",
405 file_name, strerror(errno));
411 while (fgets(line, sizeof(line) - 1, file) != NULL) {
424 while (*p == ' ' || *p == '\t' || *p == '\n')
429 if (!conf && !(conf = new_part_conf(p_log, p_subn))) {
430 OSM_LOG(conf->p_log, OSM_LOG_ERROR,
431 "PARSE ERROR: line %d: "
432 "internal: cannot create config\n",
435 "PARSE ERROR: line %d: "
436 "internal: cannot create config\n",
445 len = parse_part_conf(conf, p, lineno);
453 flush_part_conf(conf);