]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ofed/opensm/opensm/osm_db_pack.c
MFV r353623: 10473 zfs(1M) missing cross-reference to zfs-program(1M)
[FreeBSD/FreeBSD.git] / contrib / ofed / opensm / opensm / osm_db_pack.c
1 /*
2  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2006 Mellanox Technologies LTD. All rights reserved.
4  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  */
35
36 #if HAVE_CONFIG_H
37 #  include <config.h>
38 #endif                          /* HAVE_CONFIG_H */
39
40 #include <stdlib.h>
41 #include <complib/cl_debug.h>
42 #include <opensm/osm_file_ids.h>
43 #define FILE_ID OSM_FILE_DB_PACK_C
44 #include <opensm/osm_db_pack.h>
45
46 static inline void pack_guid(uint64_t guid, char *p_guid_str)
47 {
48         sprintf(p_guid_str, "0x%016" PRIx64, guid);
49 }
50
51 static inline uint64_t unpack_guid(char *p_guid_str)
52 {
53         return strtoull(p_guid_str, NULL, 0);
54 }
55
56 static inline void pack_lids(uint16_t min_lid, uint16_t max_lid, char *lid_str)
57 {
58         sprintf(lid_str, "0x%04x 0x%04x", min_lid, max_lid);
59 }
60
61 static inline int unpack_lids(IN char *p_lid_str, OUT uint16_t * p_min_lid,
62                               OUT uint16_t * p_max_lid)
63 {
64         unsigned long tmp;
65         char *p_next;
66         char *p_num;
67         char lids_str[24];
68
69         strncpy(lids_str, p_lid_str, 23);
70         lids_str[23] = '\0';
71         p_num = strtok_r(lids_str, " \t", &p_next);
72         if (!p_num)
73                 return 1;
74         tmp = strtoul(p_num, NULL, 0);
75         if (tmp >= 0xC000)
76                 return 1;
77
78         *p_min_lid = (uint16_t) tmp;
79
80         p_num = strtok_r(NULL, " \t", &p_next);
81         if (!p_num)
82                 return 1;
83         tmp = strtoul(p_num, NULL, 0);
84         if (tmp >= 0xC000)
85                 return 1;
86
87         *p_max_lid = (uint16_t) tmp;
88
89         return 0;
90 }
91
92 static inline void pack_mkey(uint64_t mkey, char *p_mkey_str)
93 {
94         sprintf(p_mkey_str, "0x%016" PRIx64, mkey);
95 }
96
97 static inline uint64_t unpack_mkey(char *p_mkey_str)
98 {
99         return strtoull(p_mkey_str, NULL, 0);
100 }
101
102 static inline void pack_neighbor(uint64_t guid, uint8_t portnum, char *p_str)
103 {
104         sprintf(p_str, "0x%016" PRIx64 ":%u", guid, portnum);
105 }
106
107 static inline int unpack_neighbor(char *p_str, uint64_t *guid,
108                                   uint8_t *portnum)
109 {
110         char tmp_str[24];
111         char *p_num, *p_next;
112         unsigned long tmp_port;
113
114         strncpy(tmp_str, p_str, 23);
115         tmp_str[23] = '\0';
116         p_num = strtok_r(tmp_str, ":", &p_next);
117         if (!p_num)
118                 return 1;
119         if (guid)
120                 *guid = strtoull(p_num, NULL, 0);
121
122         p_num = strtok_r(NULL, ":", &p_next);
123         if (!p_num)
124                 return 1;
125         if (portnum) {
126                 tmp_port = strtoul(p_num, NULL, 0);
127                 CL_ASSERT(tmp_port < 0x100);
128                 *portnum = (uint8_t) tmp_port;
129         }
130
131         return 0;
132 }
133
134 int osm_db_guid2lid_guids(IN osm_db_domain_t * p_g2l,
135                           OUT cl_qlist_t * p_guid_list)
136 {
137         char *p_key;
138         cl_list_t keys;
139         osm_db_guid_elem_t *p_guid_elem;
140
141         cl_list_construct(&keys);
142         cl_list_init(&keys, 10);
143
144         if (osm_db_keys(p_g2l, &keys))
145                 return 1;
146
147         while ((p_key = cl_list_remove_head(&keys)) != NULL) {
148                 p_guid_elem =
149                     (osm_db_guid_elem_t *) malloc(sizeof(osm_db_guid_elem_t));
150                 CL_ASSERT(p_guid_elem != NULL);
151
152                 p_guid_elem->guid = unpack_guid(p_key);
153                 cl_qlist_insert_head(p_guid_list, &p_guid_elem->item);
154         }
155
156         cl_list_destroy(&keys);
157         return 0;
158 }
159
160 int osm_db_guid2lid_get(IN osm_db_domain_t * p_g2l, IN uint64_t guid,
161                         OUT uint16_t * p_min_lid, OUT uint16_t * p_max_lid)
162 {
163         char guid_str[20];
164         char *p_lid_str;
165         uint16_t min_lid, max_lid;
166
167         pack_guid(guid, guid_str);
168         p_lid_str = osm_db_lookup(p_g2l, guid_str);
169         if (!p_lid_str)
170                 return 1;
171         if (unpack_lids(p_lid_str, &min_lid, &max_lid))
172                 return 1;
173
174         if (p_min_lid)
175                 *p_min_lid = min_lid;
176         if (p_max_lid)
177                 *p_max_lid = max_lid;
178
179         return 0;
180 }
181
182 int osm_db_guid2lid_set(IN osm_db_domain_t * p_g2l, IN uint64_t guid,
183                         IN uint16_t min_lid, IN uint16_t max_lid)
184 {
185         char guid_str[20];
186         char lid_str[16];
187
188         pack_guid(guid, guid_str);
189         pack_lids(min_lid, max_lid, lid_str);
190
191         return osm_db_update(p_g2l, guid_str, lid_str);
192 }
193
194 int osm_db_guid2lid_delete(IN osm_db_domain_t * p_g2l, IN uint64_t guid)
195 {
196         char guid_str[20];
197         pack_guid(guid, guid_str);
198         return osm_db_delete(p_g2l, guid_str);
199 }
200
201 int osm_db_guid2mkey_guids(IN osm_db_domain_t * p_g2m,
202                            OUT cl_qlist_t * p_guid_list)
203 {
204         char *p_key;
205         cl_list_t keys;
206         osm_db_guid_elem_t *p_guid_elem;
207
208         cl_list_construct(&keys);
209         cl_list_init(&keys, 10);
210
211         if (osm_db_keys(p_g2m, &keys))
212                 return 1;
213
214         while ((p_key = cl_list_remove_head(&keys)) != NULL) {
215                 p_guid_elem =
216                     (osm_db_guid_elem_t *) malloc(sizeof(osm_db_guid_elem_t));
217                 CL_ASSERT(p_guid_elem != NULL);
218
219                 p_guid_elem->guid = unpack_guid(p_key);
220                 cl_qlist_insert_head(p_guid_list, &p_guid_elem->item);
221         }
222
223         cl_list_destroy(&keys);
224         return 0;
225 }
226
227 int osm_db_guid2mkey_get(IN osm_db_domain_t * p_g2m, IN uint64_t guid,
228                          OUT uint64_t * p_mkey)
229 {
230         char guid_str[20];
231         char *p_mkey_str;
232
233         pack_guid(guid, guid_str);
234         p_mkey_str = osm_db_lookup(p_g2m, guid_str);
235         if (!p_mkey_str)
236                 return 1;
237
238         if (p_mkey)
239                 *p_mkey = unpack_mkey(p_mkey_str);
240
241         return 0;
242 }
243
244 int osm_db_guid2mkey_set(IN osm_db_domain_t * p_g2m, IN uint64_t guid,
245                          IN uint64_t mkey)
246 {
247         char guid_str[20];
248         char mkey_str[20];
249
250         pack_guid(guid, guid_str);
251         pack_mkey(mkey, mkey_str);
252
253         return osm_db_update(p_g2m, guid_str, mkey_str);
254 }
255
256 int osm_db_guid2mkey_delete(IN osm_db_domain_t * p_g2m, IN uint64_t guid)
257 {
258         char guid_str[20];
259         pack_guid(guid, guid_str);
260         return osm_db_delete(p_g2m, guid_str);
261 }
262
263 int osm_db_neighbor_guids(IN osm_db_domain_t * p_neighbor,
264                           OUT cl_qlist_t * p_neighbor_list)
265 {
266         char *p_key;
267         cl_list_t keys;
268         osm_db_neighbor_elem_t *p_neighbor_elem;
269
270         cl_list_construct(&keys);
271         cl_list_init(&keys, 10);
272
273         if (osm_db_keys(p_neighbor, &keys))
274                 return 1;
275
276         while ((p_key = cl_list_remove_head(&keys)) != NULL) {
277                 p_neighbor_elem =
278                     (osm_db_neighbor_elem_t *) malloc(sizeof(osm_db_neighbor_elem_t));
279                 CL_ASSERT(p_neighbor_elem != NULL);
280
281                 unpack_neighbor(p_key, &p_neighbor_elem->guid,
282                                 &p_neighbor_elem->portnum);
283                 cl_qlist_insert_head(p_neighbor_list, &p_neighbor_elem->item);
284         }
285
286         cl_list_destroy(&keys);
287         return 0;
288 }
289
290 int osm_db_neighbor_get(IN osm_db_domain_t * p_neighbor, IN uint64_t guid1,
291                         IN uint8_t portnum1, OUT uint64_t * p_guid2,
292                         OUT uint8_t * p_portnum2)
293 {
294         char neighbor_str[24];
295         char *p_other_str;
296         uint64_t temp_guid;
297         uint8_t temp_portnum;
298
299         pack_neighbor(guid1, portnum1, neighbor_str);
300         p_other_str = osm_db_lookup(p_neighbor, neighbor_str);
301         if (!p_other_str)
302                 return 1;
303         if (unpack_neighbor(p_other_str, &temp_guid, &temp_portnum))
304                 return 1;
305
306         if (p_guid2)
307                 *p_guid2 = temp_guid;
308         if (p_portnum2)
309                 *p_portnum2 = temp_portnum;
310
311         return 0;
312 }
313
314 int osm_db_neighbor_set(IN osm_db_domain_t * p_neighbor, IN uint64_t guid1,
315                         IN uint8_t portnum1, IN uint64_t guid2,
316                         IN uint8_t portnum2)
317 {
318         char n1_str[24], n2_str[24];
319
320         pack_neighbor(guid1, portnum1, n1_str);
321         pack_neighbor(guid2, portnum2, n2_str);
322
323         return osm_db_update(p_neighbor, n1_str, n2_str);
324 }
325
326 int osm_db_neighbor_delete(IN osm_db_domain_t * p_neighbor, IN uint64_t guid,
327                            IN uint8_t portnum)
328 {
329         char n_str[24];
330
331         pack_neighbor(guid, portnum, n_str);
332         return osm_db_delete(p_neighbor, n_str);
333 }