1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky * Copyright (c) 2004-2007 Voltaire Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
4*d6b92ffaSHans Petter Selasky * Copyright (c) 2008 Lawrence Livermore National Laboratory
5*d6b92ffaSHans Petter Selasky *
6*d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two
7*d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU
8*d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file
9*d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the
10*d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below:
11*d6b92ffaSHans Petter Selasky *
12*d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or
13*d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following
14*d6b92ffaSHans Petter Selasky * conditions are met:
15*d6b92ffaSHans Petter Selasky *
16*d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above
17*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
18*d6b92ffaSHans Petter Selasky * disclaimer.
19*d6b92ffaSHans Petter Selasky *
20*d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above
21*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
22*d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials
23*d6b92ffaSHans Petter Selasky * provided with the distribution.
24*d6b92ffaSHans Petter Selasky *
25*d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26*d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27*d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28*d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29*d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30*d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31*d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32*d6b92ffaSHans Petter Selasky * SOFTWARE.
33*d6b92ffaSHans Petter Selasky *
34*d6b92ffaSHans Petter Selasky */
35*d6b92ffaSHans Petter Selasky
36*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
37*d6b92ffaSHans Petter Selasky #include <config.h>
38*d6b92ffaSHans Petter Selasky #endif /* HAVE_CONFIG_H */
39*d6b92ffaSHans Petter Selasky
40*d6b92ffaSHans Petter Selasky #define _GNU_SOURCE
41*d6b92ffaSHans Petter Selasky #include <stdio.h>
42*d6b92ffaSHans Petter Selasky #include <stdlib.h>
43*d6b92ffaSHans Petter Selasky #include <sys/types.h>
44*d6b92ffaSHans Petter Selasky #include <sys/stat.h>
45*d6b92ffaSHans Petter Selasky #include <unistd.h>
46*d6b92ffaSHans Petter Selasky #include <fcntl.h>
47*d6b92ffaSHans Petter Selasky #include <string.h>
48*d6b92ffaSHans Petter Selasky #include <errno.h>
49*d6b92ffaSHans Petter Selasky #include <inttypes.h>
50*d6b92ffaSHans Petter Selasky
51*d6b92ffaSHans Petter Selasky #include <infiniband/ibnetdisc.h>
52*d6b92ffaSHans Petter Selasky
53*d6b92ffaSHans Petter Selasky #include "internal.h"
54*d6b92ffaSHans Petter Selasky #include "chassis.h"
55*d6b92ffaSHans Petter Selasky
56*d6b92ffaSHans Petter Selasky /* For this caching lib, we always cache little endian */
57*d6b92ffaSHans Petter Selasky
58*d6b92ffaSHans Petter Selasky /* Cache format
59*d6b92ffaSHans Petter Selasky *
60*d6b92ffaSHans Petter Selasky * Bytes 1-4 - magic number
61*d6b92ffaSHans Petter Selasky * Bytes 5-8 - version number
62*d6b92ffaSHans Petter Selasky * Bytes 9-12 - node count
63*d6b92ffaSHans Petter Selasky * Bytes 13-16 - port count
64*d6b92ffaSHans Petter Selasky * Bytes 17-24 - "from node" guid
65*d6b92ffaSHans Petter Selasky * Bytes 25-28 - maxhops discovered
66*d6b92ffaSHans Petter Selasky * Bytes X-Y - nodes (variable length)
67*d6b92ffaSHans Petter Selasky * Bytes X-Y - ports (variable length)
68*d6b92ffaSHans Petter Selasky *
69*d6b92ffaSHans Petter Selasky * Nodes are cached as
70*d6b92ffaSHans Petter Selasky *
71*d6b92ffaSHans Petter Selasky * 2 bytes - smalid
72*d6b92ffaSHans Petter Selasky * 1 byte - smalmc
73*d6b92ffaSHans Petter Selasky * 1 byte - smaenhsp0 flag
74*d6b92ffaSHans Petter Selasky * IB_SMP_DATA_SIZE bytes - switchinfo
75*d6b92ffaSHans Petter Selasky * 8 bytes - guid
76*d6b92ffaSHans Petter Selasky * 1 byte - type
77*d6b92ffaSHans Petter Selasky * 1 byte - numports
78*d6b92ffaSHans Petter Selasky * IB_SMP_DATA_SIZE bytes - info
79*d6b92ffaSHans Petter Selasky * IB_SMP_DATA_SIZE bytes - nodedesc
80*d6b92ffaSHans Petter Selasky * 1 byte - number of ports stored
81*d6b92ffaSHans Petter Selasky * 8 bytes - portguid A
82*d6b92ffaSHans Petter Selasky * 1 byte - port num A
83*d6b92ffaSHans Petter Selasky * 8 bytes - portguid B
84*d6b92ffaSHans Petter Selasky * 1 byte - port num B
85*d6b92ffaSHans Petter Selasky * ... etc., depending on number of ports stored
86*d6b92ffaSHans Petter Selasky *
87*d6b92ffaSHans Petter Selasky * Ports are cached as
88*d6b92ffaSHans Petter Selasky *
89*d6b92ffaSHans Petter Selasky * 8 bytes - guid
90*d6b92ffaSHans Petter Selasky * 1 byte - portnum
91*d6b92ffaSHans Petter Selasky * 1 byte - external portnum
92*d6b92ffaSHans Petter Selasky * 2 bytes - base lid
93*d6b92ffaSHans Petter Selasky * 1 byte - lmc
94*d6b92ffaSHans Petter Selasky * IB_SMP_DATA_SIZE bytes - info
95*d6b92ffaSHans Petter Selasky * 8 bytes - node guid port "owned" by
96*d6b92ffaSHans Petter Selasky * 1 byte - flag indicating if remote port exists
97*d6b92ffaSHans Petter Selasky * 8 bytes - port guid remotely connected to
98*d6b92ffaSHans Petter Selasky * 1 byte - port num remotely connected to
99*d6b92ffaSHans Petter Selasky */
100*d6b92ffaSHans Petter Selasky
101*d6b92ffaSHans Petter Selasky /* Structs that hold cache info temporarily before
102*d6b92ffaSHans Petter Selasky * the real structs can be reconstructed.
103*d6b92ffaSHans Petter Selasky */
104*d6b92ffaSHans Petter Selasky
105*d6b92ffaSHans Petter Selasky typedef struct ibnd_port_cache_key {
106*d6b92ffaSHans Petter Selasky uint64_t guid;
107*d6b92ffaSHans Petter Selasky uint8_t portnum;
108*d6b92ffaSHans Petter Selasky } ibnd_port_cache_key_t;
109*d6b92ffaSHans Petter Selasky
110*d6b92ffaSHans Petter Selasky typedef struct ibnd_node_cache {
111*d6b92ffaSHans Petter Selasky ibnd_node_t *node;
112*d6b92ffaSHans Petter Selasky uint8_t ports_stored_count;
113*d6b92ffaSHans Petter Selasky ibnd_port_cache_key_t *port_cache_keys;
114*d6b92ffaSHans Petter Selasky struct ibnd_node_cache *next;
115*d6b92ffaSHans Petter Selasky struct ibnd_node_cache *htnext;
116*d6b92ffaSHans Petter Selasky int node_stored_to_fabric;
117*d6b92ffaSHans Petter Selasky } ibnd_node_cache_t;
118*d6b92ffaSHans Petter Selasky
119*d6b92ffaSHans Petter Selasky typedef struct ibnd_port_cache {
120*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
121*d6b92ffaSHans Petter Selasky uint64_t node_guid;
122*d6b92ffaSHans Petter Selasky uint8_t remoteport_flag;
123*d6b92ffaSHans Petter Selasky ibnd_port_cache_key_t remoteport_cache_key;
124*d6b92ffaSHans Petter Selasky struct ibnd_port_cache *next;
125*d6b92ffaSHans Petter Selasky struct ibnd_port_cache *htnext;
126*d6b92ffaSHans Petter Selasky int port_stored_to_fabric;
127*d6b92ffaSHans Petter Selasky } ibnd_port_cache_t;
128*d6b92ffaSHans Petter Selasky
129*d6b92ffaSHans Petter Selasky typedef struct ibnd_fabric_cache {
130*d6b92ffaSHans Petter Selasky f_internal_t *f_int;
131*d6b92ffaSHans Petter Selasky uint64_t from_node_guid;
132*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *nodes_cache;
133*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *ports_cache;
134*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *nodescachetbl[HTSZ];
135*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *portscachetbl[HTSZ];
136*d6b92ffaSHans Petter Selasky } ibnd_fabric_cache_t;
137*d6b92ffaSHans Petter Selasky
138*d6b92ffaSHans Petter Selasky #define IBND_FABRIC_CACHE_BUFLEN 4096
139*d6b92ffaSHans Petter Selasky #define IBND_FABRIC_CACHE_MAGIC 0x8FE7832B
140*d6b92ffaSHans Petter Selasky #define IBND_FABRIC_CACHE_VERSION 0x00000001
141*d6b92ffaSHans Petter Selasky
142*d6b92ffaSHans Petter Selasky #define IBND_FABRIC_CACHE_COUNT_OFFSET 8
143*d6b92ffaSHans Petter Selasky
144*d6b92ffaSHans Petter Selasky #define IBND_FABRIC_CACHE_HEADER_LEN (28)
145*d6b92ffaSHans Petter Selasky #define IBND_NODE_CACHE_HEADER_LEN (15 + IB_SMP_DATA_SIZE*3)
146*d6b92ffaSHans Petter Selasky #define IBND_PORT_CACHE_KEY_LEN (8 + 1)
147*d6b92ffaSHans Petter Selasky #define IBND_PORT_CACHE_LEN (31 + IB_SMP_DATA_SIZE)
148*d6b92ffaSHans Petter Selasky
ibnd_read(int fd,void * buf,size_t count)149*d6b92ffaSHans Petter Selasky static ssize_t ibnd_read(int fd, void *buf, size_t count)
150*d6b92ffaSHans Petter Selasky {
151*d6b92ffaSHans Petter Selasky size_t count_done = 0;
152*d6b92ffaSHans Petter Selasky ssize_t ret;
153*d6b92ffaSHans Petter Selasky
154*d6b92ffaSHans Petter Selasky while ((count - count_done) > 0) {
155*d6b92ffaSHans Petter Selasky ret = read(fd, ((char *) buf) + count_done, count - count_done);
156*d6b92ffaSHans Petter Selasky if (ret < 0) {
157*d6b92ffaSHans Petter Selasky if (errno == EINTR)
158*d6b92ffaSHans Petter Selasky continue;
159*d6b92ffaSHans Petter Selasky else {
160*d6b92ffaSHans Petter Selasky IBND_DEBUG("read: %s\n", strerror(errno));
161*d6b92ffaSHans Petter Selasky return -1;
162*d6b92ffaSHans Petter Selasky }
163*d6b92ffaSHans Petter Selasky }
164*d6b92ffaSHans Petter Selasky if (!ret)
165*d6b92ffaSHans Petter Selasky break;
166*d6b92ffaSHans Petter Selasky count_done += ret;
167*d6b92ffaSHans Petter Selasky }
168*d6b92ffaSHans Petter Selasky
169*d6b92ffaSHans Petter Selasky if (count_done != count) {
170*d6b92ffaSHans Petter Selasky IBND_DEBUG("read: read short\n");
171*d6b92ffaSHans Petter Selasky return -1;
172*d6b92ffaSHans Petter Selasky }
173*d6b92ffaSHans Petter Selasky
174*d6b92ffaSHans Petter Selasky return count_done;
175*d6b92ffaSHans Petter Selasky }
176*d6b92ffaSHans Petter Selasky
_unmarshall8(uint8_t * inbuf,uint8_t * num)177*d6b92ffaSHans Petter Selasky static size_t _unmarshall8(uint8_t * inbuf, uint8_t * num)
178*d6b92ffaSHans Petter Selasky {
179*d6b92ffaSHans Petter Selasky (*num) = inbuf[0];
180*d6b92ffaSHans Petter Selasky
181*d6b92ffaSHans Petter Selasky return (sizeof(*num));
182*d6b92ffaSHans Petter Selasky }
183*d6b92ffaSHans Petter Selasky
_unmarshall16(uint8_t * inbuf,uint16_t * num)184*d6b92ffaSHans Petter Selasky static size_t _unmarshall16(uint8_t * inbuf, uint16_t * num)
185*d6b92ffaSHans Petter Selasky {
186*d6b92ffaSHans Petter Selasky (*num) = ((uint16_t) inbuf[1] << 8) | inbuf[0];
187*d6b92ffaSHans Petter Selasky
188*d6b92ffaSHans Petter Selasky return (sizeof(*num));
189*d6b92ffaSHans Petter Selasky }
190*d6b92ffaSHans Petter Selasky
_unmarshall32(uint8_t * inbuf,uint32_t * num)191*d6b92ffaSHans Petter Selasky static size_t _unmarshall32(uint8_t * inbuf, uint32_t * num)
192*d6b92ffaSHans Petter Selasky {
193*d6b92ffaSHans Petter Selasky (*num) = (uint32_t) inbuf[0];
194*d6b92ffaSHans Petter Selasky (*num) |= ((uint32_t) inbuf[1] << 8);
195*d6b92ffaSHans Petter Selasky (*num) |= ((uint32_t) inbuf[2] << 16);
196*d6b92ffaSHans Petter Selasky (*num) |= ((uint32_t) inbuf[3] << 24);
197*d6b92ffaSHans Petter Selasky
198*d6b92ffaSHans Petter Selasky return (sizeof(*num));
199*d6b92ffaSHans Petter Selasky }
200*d6b92ffaSHans Petter Selasky
_unmarshall64(uint8_t * inbuf,uint64_t * num)201*d6b92ffaSHans Petter Selasky static size_t _unmarshall64(uint8_t * inbuf, uint64_t * num)
202*d6b92ffaSHans Petter Selasky {
203*d6b92ffaSHans Petter Selasky (*num) = (uint64_t) inbuf[0];
204*d6b92ffaSHans Petter Selasky (*num) |= ((uint64_t) inbuf[1] << 8);
205*d6b92ffaSHans Petter Selasky (*num) |= ((uint64_t) inbuf[2] << 16);
206*d6b92ffaSHans Petter Selasky (*num) |= ((uint64_t) inbuf[3] << 24);
207*d6b92ffaSHans Petter Selasky (*num) |= ((uint64_t) inbuf[4] << 32);
208*d6b92ffaSHans Petter Selasky (*num) |= ((uint64_t) inbuf[5] << 40);
209*d6b92ffaSHans Petter Selasky (*num) |= ((uint64_t) inbuf[6] << 48);
210*d6b92ffaSHans Petter Selasky (*num) |= ((uint64_t) inbuf[7] << 56);
211*d6b92ffaSHans Petter Selasky
212*d6b92ffaSHans Petter Selasky return (sizeof(*num));
213*d6b92ffaSHans Petter Selasky }
214*d6b92ffaSHans Petter Selasky
_unmarshall_buf(const void * inbuf,void * outbuf,unsigned int len)215*d6b92ffaSHans Petter Selasky static size_t _unmarshall_buf(const void *inbuf, void *outbuf, unsigned int len)
216*d6b92ffaSHans Petter Selasky {
217*d6b92ffaSHans Petter Selasky memcpy(outbuf, inbuf, len);
218*d6b92ffaSHans Petter Selasky
219*d6b92ffaSHans Petter Selasky return len;
220*d6b92ffaSHans Petter Selasky }
221*d6b92ffaSHans Petter Selasky
_load_header_info(int fd,ibnd_fabric_cache_t * fabric_cache,unsigned int * node_count,unsigned int * port_count)222*d6b92ffaSHans Petter Selasky static int _load_header_info(int fd, ibnd_fabric_cache_t * fabric_cache,
223*d6b92ffaSHans Petter Selasky unsigned int *node_count, unsigned int *port_count)
224*d6b92ffaSHans Petter Selasky {
225*d6b92ffaSHans Petter Selasky uint8_t buf[IBND_FABRIC_CACHE_BUFLEN];
226*d6b92ffaSHans Petter Selasky uint32_t magic = 0;
227*d6b92ffaSHans Petter Selasky uint32_t version = 0;
228*d6b92ffaSHans Petter Selasky size_t offset = 0;
229*d6b92ffaSHans Petter Selasky uint32_t tmp32;
230*d6b92ffaSHans Petter Selasky
231*d6b92ffaSHans Petter Selasky if (ibnd_read(fd, buf, IBND_FABRIC_CACHE_HEADER_LEN) < 0)
232*d6b92ffaSHans Petter Selasky return -1;
233*d6b92ffaSHans Petter Selasky
234*d6b92ffaSHans Petter Selasky offset += _unmarshall32(buf + offset, &magic);
235*d6b92ffaSHans Petter Selasky
236*d6b92ffaSHans Petter Selasky if (magic != IBND_FABRIC_CACHE_MAGIC) {
237*d6b92ffaSHans Petter Selasky IBND_DEBUG("invalid fabric cache file\n");
238*d6b92ffaSHans Petter Selasky return -1;
239*d6b92ffaSHans Petter Selasky }
240*d6b92ffaSHans Petter Selasky
241*d6b92ffaSHans Petter Selasky offset += _unmarshall32(buf + offset, &version);
242*d6b92ffaSHans Petter Selasky
243*d6b92ffaSHans Petter Selasky if (version != IBND_FABRIC_CACHE_VERSION) {
244*d6b92ffaSHans Petter Selasky IBND_DEBUG("invalid fabric cache version\n");
245*d6b92ffaSHans Petter Selasky return -1;
246*d6b92ffaSHans Petter Selasky }
247*d6b92ffaSHans Petter Selasky
248*d6b92ffaSHans Petter Selasky offset += _unmarshall32(buf + offset, node_count);
249*d6b92ffaSHans Petter Selasky offset += _unmarshall32(buf + offset, port_count);
250*d6b92ffaSHans Petter Selasky
251*d6b92ffaSHans Petter Selasky offset += _unmarshall64(buf + offset, &fabric_cache->from_node_guid);
252*d6b92ffaSHans Petter Selasky offset += _unmarshall32(buf + offset, &tmp32);
253*d6b92ffaSHans Petter Selasky fabric_cache->f_int->fabric.maxhops_discovered = tmp32;
254*d6b92ffaSHans Petter Selasky
255*d6b92ffaSHans Petter Selasky return 0;
256*d6b92ffaSHans Petter Selasky }
257*d6b92ffaSHans Petter Selasky
_destroy_ibnd_node_cache(ibnd_node_cache_t * node_cache)258*d6b92ffaSHans Petter Selasky static void _destroy_ibnd_node_cache(ibnd_node_cache_t * node_cache)
259*d6b92ffaSHans Petter Selasky {
260*d6b92ffaSHans Petter Selasky free(node_cache->port_cache_keys);
261*d6b92ffaSHans Petter Selasky if (!node_cache->node_stored_to_fabric && node_cache->node)
262*d6b92ffaSHans Petter Selasky destroy_node(node_cache->node);
263*d6b92ffaSHans Petter Selasky free(node_cache);
264*d6b92ffaSHans Petter Selasky }
265*d6b92ffaSHans Petter Selasky
_destroy_ibnd_fabric_cache(ibnd_fabric_cache_t * fabric_cache)266*d6b92ffaSHans Petter Selasky static void _destroy_ibnd_fabric_cache(ibnd_fabric_cache_t * fabric_cache)
267*d6b92ffaSHans Petter Selasky {
268*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache;
269*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache_next;
270*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *port_cache;
271*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *port_cache_next;
272*d6b92ffaSHans Petter Selasky
273*d6b92ffaSHans Petter Selasky if (!fabric_cache)
274*d6b92ffaSHans Petter Selasky return;
275*d6b92ffaSHans Petter Selasky
276*d6b92ffaSHans Petter Selasky node_cache = fabric_cache->nodes_cache;
277*d6b92ffaSHans Petter Selasky while (node_cache) {
278*d6b92ffaSHans Petter Selasky node_cache_next = node_cache->next;
279*d6b92ffaSHans Petter Selasky
280*d6b92ffaSHans Petter Selasky _destroy_ibnd_node_cache(node_cache);
281*d6b92ffaSHans Petter Selasky
282*d6b92ffaSHans Petter Selasky node_cache = node_cache_next;
283*d6b92ffaSHans Petter Selasky }
284*d6b92ffaSHans Petter Selasky
285*d6b92ffaSHans Petter Selasky port_cache = fabric_cache->ports_cache;
286*d6b92ffaSHans Petter Selasky while (port_cache) {
287*d6b92ffaSHans Petter Selasky port_cache_next = port_cache->next;
288*d6b92ffaSHans Petter Selasky
289*d6b92ffaSHans Petter Selasky if (!port_cache->port_stored_to_fabric && port_cache->port)
290*d6b92ffaSHans Petter Selasky free(port_cache->port);
291*d6b92ffaSHans Petter Selasky free(port_cache);
292*d6b92ffaSHans Petter Selasky
293*d6b92ffaSHans Petter Selasky port_cache = port_cache_next;
294*d6b92ffaSHans Petter Selasky }
295*d6b92ffaSHans Petter Selasky
296*d6b92ffaSHans Petter Selasky free(fabric_cache);
297*d6b92ffaSHans Petter Selasky }
298*d6b92ffaSHans Petter Selasky
store_node_cache(ibnd_node_cache_t * node_cache,ibnd_fabric_cache_t * fabric_cache)299*d6b92ffaSHans Petter Selasky static void store_node_cache(ibnd_node_cache_t * node_cache,
300*d6b92ffaSHans Petter Selasky ibnd_fabric_cache_t * fabric_cache)
301*d6b92ffaSHans Petter Selasky {
302*d6b92ffaSHans Petter Selasky int hash_indx = HASHGUID(node_cache->node->guid) % HTSZ;
303*d6b92ffaSHans Petter Selasky
304*d6b92ffaSHans Petter Selasky node_cache->next = fabric_cache->nodes_cache;
305*d6b92ffaSHans Petter Selasky fabric_cache->nodes_cache = node_cache;
306*d6b92ffaSHans Petter Selasky
307*d6b92ffaSHans Petter Selasky node_cache->htnext = fabric_cache->nodescachetbl[hash_indx];
308*d6b92ffaSHans Petter Selasky fabric_cache->nodescachetbl[hash_indx] = node_cache;
309*d6b92ffaSHans Petter Selasky }
310*d6b92ffaSHans Petter Selasky
_load_node(int fd,ibnd_fabric_cache_t * fabric_cache)311*d6b92ffaSHans Petter Selasky static int _load_node(int fd, ibnd_fabric_cache_t * fabric_cache)
312*d6b92ffaSHans Petter Selasky {
313*d6b92ffaSHans Petter Selasky uint8_t buf[IBND_FABRIC_CACHE_BUFLEN];
314*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache = NULL;
315*d6b92ffaSHans Petter Selasky ibnd_node_t *node = NULL;
316*d6b92ffaSHans Petter Selasky size_t offset = 0;
317*d6b92ffaSHans Petter Selasky uint8_t tmp8;
318*d6b92ffaSHans Petter Selasky
319*d6b92ffaSHans Petter Selasky node_cache = (ibnd_node_cache_t *) malloc(sizeof(ibnd_node_cache_t));
320*d6b92ffaSHans Petter Selasky if (!node_cache) {
321*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: node_cache\n");
322*d6b92ffaSHans Petter Selasky return -1;
323*d6b92ffaSHans Petter Selasky }
324*d6b92ffaSHans Petter Selasky memset(node_cache, '\0', sizeof(ibnd_node_cache_t));
325*d6b92ffaSHans Petter Selasky
326*d6b92ffaSHans Petter Selasky node = (ibnd_node_t *) malloc(sizeof(ibnd_node_t));
327*d6b92ffaSHans Petter Selasky if (!node) {
328*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: node\n");
329*d6b92ffaSHans Petter Selasky free(node_cache);
330*d6b92ffaSHans Petter Selasky return -1;
331*d6b92ffaSHans Petter Selasky }
332*d6b92ffaSHans Petter Selasky memset(node, '\0', sizeof(ibnd_node_t));
333*d6b92ffaSHans Petter Selasky
334*d6b92ffaSHans Petter Selasky node_cache->node = node;
335*d6b92ffaSHans Petter Selasky
336*d6b92ffaSHans Petter Selasky if (ibnd_read(fd, buf, IBND_NODE_CACHE_HEADER_LEN) < 0)
337*d6b92ffaSHans Petter Selasky goto cleanup;
338*d6b92ffaSHans Petter Selasky
339*d6b92ffaSHans Petter Selasky offset += _unmarshall16(buf + offset, &node->smalid);
340*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &node->smalmc);
341*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &tmp8);
342*d6b92ffaSHans Petter Selasky node->smaenhsp0 = tmp8;
343*d6b92ffaSHans Petter Selasky offset += _unmarshall_buf(buf + offset, node->switchinfo,
344*d6b92ffaSHans Petter Selasky IB_SMP_DATA_SIZE);
345*d6b92ffaSHans Petter Selasky offset += _unmarshall64(buf + offset, &node->guid);
346*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &tmp8);
347*d6b92ffaSHans Petter Selasky node->type = tmp8;
348*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &tmp8);
349*d6b92ffaSHans Petter Selasky node->numports = tmp8;
350*d6b92ffaSHans Petter Selasky offset += _unmarshall_buf(buf + offset, node->info, IB_SMP_DATA_SIZE);
351*d6b92ffaSHans Petter Selasky offset += _unmarshall_buf(buf + offset, node->nodedesc,
352*d6b92ffaSHans Petter Selasky IB_SMP_DATA_SIZE);
353*d6b92ffaSHans Petter Selasky
354*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &node_cache->ports_stored_count);
355*d6b92ffaSHans Petter Selasky
356*d6b92ffaSHans Petter Selasky if (node_cache->ports_stored_count) {
357*d6b92ffaSHans Petter Selasky unsigned int tomalloc = 0;
358*d6b92ffaSHans Petter Selasky unsigned int toread = 0;
359*d6b92ffaSHans Petter Selasky unsigned int i;
360*d6b92ffaSHans Petter Selasky
361*d6b92ffaSHans Petter Selasky tomalloc =
362*d6b92ffaSHans Petter Selasky sizeof(ibnd_port_cache_key_t) *
363*d6b92ffaSHans Petter Selasky node_cache->ports_stored_count;
364*d6b92ffaSHans Petter Selasky
365*d6b92ffaSHans Petter Selasky toread =
366*d6b92ffaSHans Petter Selasky IBND_PORT_CACHE_KEY_LEN * node_cache->ports_stored_count;
367*d6b92ffaSHans Petter Selasky
368*d6b92ffaSHans Petter Selasky node_cache->port_cache_keys =
369*d6b92ffaSHans Petter Selasky (ibnd_port_cache_key_t *) malloc(tomalloc);
370*d6b92ffaSHans Petter Selasky if (!node_cache->port_cache_keys) {
371*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: node_cache port_cache_keys\n");
372*d6b92ffaSHans Petter Selasky goto cleanup;
373*d6b92ffaSHans Petter Selasky }
374*d6b92ffaSHans Petter Selasky
375*d6b92ffaSHans Petter Selasky if (ibnd_read(fd, buf, toread) < 0)
376*d6b92ffaSHans Petter Selasky goto cleanup;
377*d6b92ffaSHans Petter Selasky
378*d6b92ffaSHans Petter Selasky offset = 0;
379*d6b92ffaSHans Petter Selasky
380*d6b92ffaSHans Petter Selasky for (i = 0; i < node_cache->ports_stored_count; i++) {
381*d6b92ffaSHans Petter Selasky offset +=
382*d6b92ffaSHans Petter Selasky _unmarshall64(buf + offset,
383*d6b92ffaSHans Petter Selasky &node_cache->port_cache_keys[i].guid);
384*d6b92ffaSHans Petter Selasky offset +=
385*d6b92ffaSHans Petter Selasky _unmarshall8(buf + offset,
386*d6b92ffaSHans Petter Selasky &node_cache->
387*d6b92ffaSHans Petter Selasky port_cache_keys[i].portnum);
388*d6b92ffaSHans Petter Selasky }
389*d6b92ffaSHans Petter Selasky }
390*d6b92ffaSHans Petter Selasky
391*d6b92ffaSHans Petter Selasky store_node_cache(node_cache, fabric_cache);
392*d6b92ffaSHans Petter Selasky
393*d6b92ffaSHans Petter Selasky return 0;
394*d6b92ffaSHans Petter Selasky
395*d6b92ffaSHans Petter Selasky cleanup:
396*d6b92ffaSHans Petter Selasky _destroy_ibnd_node_cache(node_cache);
397*d6b92ffaSHans Petter Selasky return -1;
398*d6b92ffaSHans Petter Selasky }
399*d6b92ffaSHans Petter Selasky
store_port_cache(ibnd_port_cache_t * port_cache,ibnd_fabric_cache_t * fabric_cache)400*d6b92ffaSHans Petter Selasky static void store_port_cache(ibnd_port_cache_t * port_cache,
401*d6b92ffaSHans Petter Selasky ibnd_fabric_cache_t * fabric_cache)
402*d6b92ffaSHans Petter Selasky {
403*d6b92ffaSHans Petter Selasky int hash_indx = HASHGUID(port_cache->port->guid) % HTSZ;
404*d6b92ffaSHans Petter Selasky
405*d6b92ffaSHans Petter Selasky port_cache->next = fabric_cache->ports_cache;
406*d6b92ffaSHans Petter Selasky fabric_cache->ports_cache = port_cache;
407*d6b92ffaSHans Petter Selasky
408*d6b92ffaSHans Petter Selasky port_cache->htnext = fabric_cache->portscachetbl[hash_indx];
409*d6b92ffaSHans Petter Selasky fabric_cache->portscachetbl[hash_indx] = port_cache;
410*d6b92ffaSHans Petter Selasky }
411*d6b92ffaSHans Petter Selasky
_load_port(int fd,ibnd_fabric_cache_t * fabric_cache)412*d6b92ffaSHans Petter Selasky static int _load_port(int fd, ibnd_fabric_cache_t * fabric_cache)
413*d6b92ffaSHans Petter Selasky {
414*d6b92ffaSHans Petter Selasky uint8_t buf[IBND_FABRIC_CACHE_BUFLEN];
415*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *port_cache = NULL;
416*d6b92ffaSHans Petter Selasky ibnd_port_t *port = NULL;
417*d6b92ffaSHans Petter Selasky size_t offset = 0;
418*d6b92ffaSHans Petter Selasky uint8_t tmp8;
419*d6b92ffaSHans Petter Selasky
420*d6b92ffaSHans Petter Selasky port_cache = (ibnd_port_cache_t *) malloc(sizeof(ibnd_port_cache_t));
421*d6b92ffaSHans Petter Selasky if (!port_cache) {
422*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: port_cache\n");
423*d6b92ffaSHans Petter Selasky return -1;
424*d6b92ffaSHans Petter Selasky }
425*d6b92ffaSHans Petter Selasky memset(port_cache, '\0', sizeof(ibnd_port_cache_t));
426*d6b92ffaSHans Petter Selasky
427*d6b92ffaSHans Petter Selasky port = (ibnd_port_t *) malloc(sizeof(ibnd_port_t));
428*d6b92ffaSHans Petter Selasky if (!port) {
429*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: port\n");
430*d6b92ffaSHans Petter Selasky free(port_cache);
431*d6b92ffaSHans Petter Selasky return -1;
432*d6b92ffaSHans Petter Selasky }
433*d6b92ffaSHans Petter Selasky memset(port, '\0', sizeof(ibnd_port_t));
434*d6b92ffaSHans Petter Selasky
435*d6b92ffaSHans Petter Selasky port_cache->port = port;
436*d6b92ffaSHans Petter Selasky
437*d6b92ffaSHans Petter Selasky if (ibnd_read(fd, buf, IBND_PORT_CACHE_LEN) < 0)
438*d6b92ffaSHans Petter Selasky goto cleanup;
439*d6b92ffaSHans Petter Selasky
440*d6b92ffaSHans Petter Selasky offset += _unmarshall64(buf + offset, &port->guid);
441*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &tmp8);
442*d6b92ffaSHans Petter Selasky port->portnum = tmp8;
443*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &tmp8);
444*d6b92ffaSHans Petter Selasky port->ext_portnum = tmp8;
445*d6b92ffaSHans Petter Selasky offset += _unmarshall16(buf + offset, &port->base_lid);
446*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &port->lmc);
447*d6b92ffaSHans Petter Selasky offset += _unmarshall_buf(buf + offset, port->info, IB_SMP_DATA_SIZE);
448*d6b92ffaSHans Petter Selasky offset += _unmarshall64(buf + offset, &port_cache->node_guid);
449*d6b92ffaSHans Petter Selasky offset += _unmarshall8(buf + offset, &port_cache->remoteport_flag);
450*d6b92ffaSHans Petter Selasky offset +=
451*d6b92ffaSHans Petter Selasky _unmarshall64(buf + offset, &port_cache->remoteport_cache_key.guid);
452*d6b92ffaSHans Petter Selasky offset +=
453*d6b92ffaSHans Petter Selasky _unmarshall8(buf + offset,
454*d6b92ffaSHans Petter Selasky &port_cache->remoteport_cache_key.portnum);
455*d6b92ffaSHans Petter Selasky
456*d6b92ffaSHans Petter Selasky store_port_cache(port_cache, fabric_cache);
457*d6b92ffaSHans Petter Selasky
458*d6b92ffaSHans Petter Selasky return 0;
459*d6b92ffaSHans Petter Selasky
460*d6b92ffaSHans Petter Selasky cleanup:
461*d6b92ffaSHans Petter Selasky free(port);
462*d6b92ffaSHans Petter Selasky free(port_cache);
463*d6b92ffaSHans Petter Selasky return -1;
464*d6b92ffaSHans Petter Selasky }
465*d6b92ffaSHans Petter Selasky
_find_port(ibnd_fabric_cache_t * fabric_cache,ibnd_port_cache_key_t * port_cache_key)466*d6b92ffaSHans Petter Selasky static ibnd_port_cache_t *_find_port(ibnd_fabric_cache_t * fabric_cache,
467*d6b92ffaSHans Petter Selasky ibnd_port_cache_key_t * port_cache_key)
468*d6b92ffaSHans Petter Selasky {
469*d6b92ffaSHans Petter Selasky int hash_indx = HASHGUID(port_cache_key->guid) % HTSZ;
470*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *port_cache;
471*d6b92ffaSHans Petter Selasky
472*d6b92ffaSHans Petter Selasky for (port_cache = fabric_cache->portscachetbl[hash_indx];
473*d6b92ffaSHans Petter Selasky port_cache; port_cache = port_cache->htnext) {
474*d6b92ffaSHans Petter Selasky if (port_cache->port->guid == port_cache_key->guid
475*d6b92ffaSHans Petter Selasky && port_cache->port->portnum == port_cache_key->portnum)
476*d6b92ffaSHans Petter Selasky return port_cache;
477*d6b92ffaSHans Petter Selasky }
478*d6b92ffaSHans Petter Selasky
479*d6b92ffaSHans Petter Selasky return NULL;
480*d6b92ffaSHans Petter Selasky }
481*d6b92ffaSHans Petter Selasky
_find_node(ibnd_fabric_cache_t * fabric_cache,uint64_t guid)482*d6b92ffaSHans Petter Selasky static ibnd_node_cache_t *_find_node(ibnd_fabric_cache_t * fabric_cache,
483*d6b92ffaSHans Petter Selasky uint64_t guid)
484*d6b92ffaSHans Petter Selasky {
485*d6b92ffaSHans Petter Selasky int hash_indx = HASHGUID(guid) % HTSZ;
486*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache;
487*d6b92ffaSHans Petter Selasky
488*d6b92ffaSHans Petter Selasky for (node_cache = fabric_cache->nodescachetbl[hash_indx];
489*d6b92ffaSHans Petter Selasky node_cache; node_cache = node_cache->htnext) {
490*d6b92ffaSHans Petter Selasky if (node_cache->node->guid == guid)
491*d6b92ffaSHans Petter Selasky return node_cache;
492*d6b92ffaSHans Petter Selasky }
493*d6b92ffaSHans Petter Selasky
494*d6b92ffaSHans Petter Selasky return NULL;
495*d6b92ffaSHans Petter Selasky }
496*d6b92ffaSHans Petter Selasky
_fill_port(ibnd_fabric_cache_t * fabric_cache,ibnd_node_t * node,ibnd_port_cache_key_t * port_cache_key)497*d6b92ffaSHans Petter Selasky static int _fill_port(ibnd_fabric_cache_t * fabric_cache, ibnd_node_t * node,
498*d6b92ffaSHans Petter Selasky ibnd_port_cache_key_t * port_cache_key)
499*d6b92ffaSHans Petter Selasky {
500*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *port_cache;
501*d6b92ffaSHans Petter Selasky
502*d6b92ffaSHans Petter Selasky if (!(port_cache = _find_port(fabric_cache, port_cache_key))) {
503*d6b92ffaSHans Petter Selasky IBND_DEBUG("Cache invalid: cannot find port\n");
504*d6b92ffaSHans Petter Selasky return -1;
505*d6b92ffaSHans Petter Selasky }
506*d6b92ffaSHans Petter Selasky
507*d6b92ffaSHans Petter Selasky if (port_cache->port_stored_to_fabric) {
508*d6b92ffaSHans Petter Selasky IBND_DEBUG("Cache invalid: duplicate port discovered\n");
509*d6b92ffaSHans Petter Selasky return -1;
510*d6b92ffaSHans Petter Selasky }
511*d6b92ffaSHans Petter Selasky
512*d6b92ffaSHans Petter Selasky node->ports[port_cache->port->portnum] = port_cache->port;
513*d6b92ffaSHans Petter Selasky port_cache->port_stored_to_fabric++;
514*d6b92ffaSHans Petter Selasky
515*d6b92ffaSHans Petter Selasky /* achu: needed if user wishes to re-cache a loaded fabric.
516*d6b92ffaSHans Petter Selasky * Otherwise, mostly unnecessary to do this.
517*d6b92ffaSHans Petter Selasky */
518*d6b92ffaSHans Petter Selasky int rc = add_to_portguid_hash(port_cache->port,
519*d6b92ffaSHans Petter Selasky fabric_cache->f_int->fabric.portstbl);
520*d6b92ffaSHans Petter Selasky if (rc) {
521*d6b92ffaSHans Petter Selasky IBND_DEBUG("Error Occurred when trying"
522*d6b92ffaSHans Petter Selasky " to insert new port guid 0x%016" PRIx64 " to DB\n",
523*d6b92ffaSHans Petter Selasky port_cache->port->guid);
524*d6b92ffaSHans Petter Selasky }
525*d6b92ffaSHans Petter Selasky return 0;
526*d6b92ffaSHans Petter Selasky }
527*d6b92ffaSHans Petter Selasky
_rebuild_nodes(ibnd_fabric_cache_t * fabric_cache)528*d6b92ffaSHans Petter Selasky static int _rebuild_nodes(ibnd_fabric_cache_t * fabric_cache)
529*d6b92ffaSHans Petter Selasky {
530*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache;
531*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache_next;
532*d6b92ffaSHans Petter Selasky
533*d6b92ffaSHans Petter Selasky node_cache = fabric_cache->nodes_cache;
534*d6b92ffaSHans Petter Selasky while (node_cache) {
535*d6b92ffaSHans Petter Selasky ibnd_node_t *node;
536*d6b92ffaSHans Petter Selasky int i;
537*d6b92ffaSHans Petter Selasky
538*d6b92ffaSHans Petter Selasky node_cache_next = node_cache->next;
539*d6b92ffaSHans Petter Selasky
540*d6b92ffaSHans Petter Selasky node = node_cache->node;
541*d6b92ffaSHans Petter Selasky
542*d6b92ffaSHans Petter Selasky /* Insert node into appropriate data structures */
543*d6b92ffaSHans Petter Selasky
544*d6b92ffaSHans Petter Selasky node->next = fabric_cache->f_int->fabric.nodes;
545*d6b92ffaSHans Petter Selasky fabric_cache->f_int->fabric.nodes = node;
546*d6b92ffaSHans Petter Selasky
547*d6b92ffaSHans Petter Selasky int rc = add_to_nodeguid_hash(node_cache->node,
548*d6b92ffaSHans Petter Selasky fabric_cache->
549*d6b92ffaSHans Petter Selasky f_int->
550*d6b92ffaSHans Petter Selasky fabric.nodestbl);
551*d6b92ffaSHans Petter Selasky if (rc) {
552*d6b92ffaSHans Petter Selasky IBND_DEBUG("Error Occurred when trying"
553*d6b92ffaSHans Petter Selasky " to insert new node guid 0x%016" PRIx64 " to DB\n",
554*d6b92ffaSHans Petter Selasky node_cache->node->guid);
555*d6b92ffaSHans Petter Selasky }
556*d6b92ffaSHans Petter Selasky
557*d6b92ffaSHans Petter Selasky add_to_type_list(node_cache->node, fabric_cache->f_int);
558*d6b92ffaSHans Petter Selasky
559*d6b92ffaSHans Petter Selasky node_cache->node_stored_to_fabric++;
560*d6b92ffaSHans Petter Selasky
561*d6b92ffaSHans Petter Selasky /* Rebuild node ports array */
562*d6b92ffaSHans Petter Selasky
563*d6b92ffaSHans Petter Selasky if (!(node->ports =
564*d6b92ffaSHans Petter Selasky calloc(sizeof(*node->ports), node->numports + 1))) {
565*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: node->ports\n");
566*d6b92ffaSHans Petter Selasky return -1;
567*d6b92ffaSHans Petter Selasky }
568*d6b92ffaSHans Petter Selasky
569*d6b92ffaSHans Petter Selasky for (i = 0; i < node_cache->ports_stored_count; i++) {
570*d6b92ffaSHans Petter Selasky if (_fill_port(fabric_cache, node,
571*d6b92ffaSHans Petter Selasky &node_cache->port_cache_keys[i]) < 0)
572*d6b92ffaSHans Petter Selasky return -1;
573*d6b92ffaSHans Petter Selasky }
574*d6b92ffaSHans Petter Selasky
575*d6b92ffaSHans Petter Selasky node_cache = node_cache_next;
576*d6b92ffaSHans Petter Selasky }
577*d6b92ffaSHans Petter Selasky
578*d6b92ffaSHans Petter Selasky return 0;
579*d6b92ffaSHans Petter Selasky }
580*d6b92ffaSHans Petter Selasky
_rebuild_ports(ibnd_fabric_cache_t * fabric_cache)581*d6b92ffaSHans Petter Selasky static int _rebuild_ports(ibnd_fabric_cache_t * fabric_cache)
582*d6b92ffaSHans Petter Selasky {
583*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *port_cache;
584*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *port_cache_next;
585*d6b92ffaSHans Petter Selasky
586*d6b92ffaSHans Petter Selasky port_cache = fabric_cache->ports_cache;
587*d6b92ffaSHans Petter Selasky while (port_cache) {
588*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache;
589*d6b92ffaSHans Petter Selasky ibnd_port_cache_t *remoteport_cache;
590*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
591*d6b92ffaSHans Petter Selasky
592*d6b92ffaSHans Petter Selasky port_cache_next = port_cache->next;
593*d6b92ffaSHans Petter Selasky
594*d6b92ffaSHans Petter Selasky port = port_cache->port;
595*d6b92ffaSHans Petter Selasky
596*d6b92ffaSHans Petter Selasky if (!(node_cache =
597*d6b92ffaSHans Petter Selasky _find_node(fabric_cache, port_cache->node_guid))) {
598*d6b92ffaSHans Petter Selasky IBND_DEBUG("Cache invalid: cannot find node\n");
599*d6b92ffaSHans Petter Selasky return -1;
600*d6b92ffaSHans Petter Selasky }
601*d6b92ffaSHans Petter Selasky
602*d6b92ffaSHans Petter Selasky port->node = node_cache->node;
603*d6b92ffaSHans Petter Selasky
604*d6b92ffaSHans Petter Selasky if (port_cache->remoteport_flag) {
605*d6b92ffaSHans Petter Selasky if (!(remoteport_cache = _find_port(fabric_cache,
606*d6b92ffaSHans Petter Selasky &port_cache->remoteport_cache_key)))
607*d6b92ffaSHans Petter Selasky {
608*d6b92ffaSHans Petter Selasky IBND_DEBUG
609*d6b92ffaSHans Petter Selasky ("Cache invalid: cannot find remote port\n");
610*d6b92ffaSHans Petter Selasky return -1;
611*d6b92ffaSHans Petter Selasky }
612*d6b92ffaSHans Petter Selasky
613*d6b92ffaSHans Petter Selasky port->remoteport = remoteport_cache->port;
614*d6b92ffaSHans Petter Selasky } else
615*d6b92ffaSHans Petter Selasky port->remoteport = NULL;
616*d6b92ffaSHans Petter Selasky
617*d6b92ffaSHans Petter Selasky add_to_portlid_hash(port, fabric_cache->f_int->lid2guid);
618*d6b92ffaSHans Petter Selasky port_cache = port_cache_next;
619*d6b92ffaSHans Petter Selasky }
620*d6b92ffaSHans Petter Selasky
621*d6b92ffaSHans Petter Selasky return 0;
622*d6b92ffaSHans Petter Selasky }
623*d6b92ffaSHans Petter Selasky
ibnd_load_fabric(const char * file,unsigned int flags)624*d6b92ffaSHans Petter Selasky ibnd_fabric_t *ibnd_load_fabric(const char *file, unsigned int flags)
625*d6b92ffaSHans Petter Selasky {
626*d6b92ffaSHans Petter Selasky unsigned int node_count = 0;
627*d6b92ffaSHans Petter Selasky unsigned int port_count = 0;
628*d6b92ffaSHans Petter Selasky ibnd_fabric_cache_t *fabric_cache = NULL;
629*d6b92ffaSHans Petter Selasky f_internal_t *f_int = NULL;
630*d6b92ffaSHans Petter Selasky ibnd_node_cache_t *node_cache = NULL;
631*d6b92ffaSHans Petter Selasky int fd = -1;
632*d6b92ffaSHans Petter Selasky unsigned int i;
633*d6b92ffaSHans Petter Selasky
634*d6b92ffaSHans Petter Selasky if (!file) {
635*d6b92ffaSHans Petter Selasky IBND_DEBUG("file parameter NULL\n");
636*d6b92ffaSHans Petter Selasky return NULL;
637*d6b92ffaSHans Petter Selasky }
638*d6b92ffaSHans Petter Selasky
639*d6b92ffaSHans Petter Selasky if ((fd = open(file, O_RDONLY)) < 0) {
640*d6b92ffaSHans Petter Selasky IBND_DEBUG("open: %s\n", strerror(errno));
641*d6b92ffaSHans Petter Selasky return NULL;
642*d6b92ffaSHans Petter Selasky }
643*d6b92ffaSHans Petter Selasky
644*d6b92ffaSHans Petter Selasky fabric_cache =
645*d6b92ffaSHans Petter Selasky (ibnd_fabric_cache_t *) malloc(sizeof(ibnd_fabric_cache_t));
646*d6b92ffaSHans Petter Selasky if (!fabric_cache) {
647*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: fabric_cache\n");
648*d6b92ffaSHans Petter Selasky goto cleanup;
649*d6b92ffaSHans Petter Selasky }
650*d6b92ffaSHans Petter Selasky memset(fabric_cache, '\0', sizeof(ibnd_fabric_cache_t));
651*d6b92ffaSHans Petter Selasky
652*d6b92ffaSHans Petter Selasky f_int = allocate_fabric_internal();
653*d6b92ffaSHans Petter Selasky if (!f_int) {
654*d6b92ffaSHans Petter Selasky IBND_DEBUG("OOM: fabric\n");
655*d6b92ffaSHans Petter Selasky goto cleanup;
656*d6b92ffaSHans Petter Selasky }
657*d6b92ffaSHans Petter Selasky
658*d6b92ffaSHans Petter Selasky fabric_cache->f_int = f_int;
659*d6b92ffaSHans Petter Selasky
660*d6b92ffaSHans Petter Selasky if (_load_header_info(fd, fabric_cache, &node_count, &port_count) < 0)
661*d6b92ffaSHans Petter Selasky goto cleanup;
662*d6b92ffaSHans Petter Selasky
663*d6b92ffaSHans Petter Selasky for (i = 0; i < node_count; i++) {
664*d6b92ffaSHans Petter Selasky if (_load_node(fd, fabric_cache) < 0)
665*d6b92ffaSHans Petter Selasky goto cleanup;
666*d6b92ffaSHans Petter Selasky }
667*d6b92ffaSHans Petter Selasky
668*d6b92ffaSHans Petter Selasky for (i = 0; i < port_count; i++) {
669*d6b92ffaSHans Petter Selasky if (_load_port(fd, fabric_cache) < 0)
670*d6b92ffaSHans Petter Selasky goto cleanup;
671*d6b92ffaSHans Petter Selasky }
672*d6b92ffaSHans Petter Selasky
673*d6b92ffaSHans Petter Selasky /* Special case - find from node */
674*d6b92ffaSHans Petter Selasky if (!(node_cache =
675*d6b92ffaSHans Petter Selasky _find_node(fabric_cache, fabric_cache->from_node_guid))) {
676*d6b92ffaSHans Petter Selasky IBND_DEBUG("Cache invalid: cannot find from node\n");
677*d6b92ffaSHans Petter Selasky goto cleanup;
678*d6b92ffaSHans Petter Selasky }
679*d6b92ffaSHans Petter Selasky f_int->fabric.from_node = node_cache->node;
680*d6b92ffaSHans Petter Selasky
681*d6b92ffaSHans Petter Selasky if (_rebuild_nodes(fabric_cache) < 0)
682*d6b92ffaSHans Petter Selasky goto cleanup;
683*d6b92ffaSHans Petter Selasky
684*d6b92ffaSHans Petter Selasky if (_rebuild_ports(fabric_cache) < 0)
685*d6b92ffaSHans Petter Selasky goto cleanup;
686*d6b92ffaSHans Petter Selasky
687*d6b92ffaSHans Petter Selasky if (group_nodes(&f_int->fabric))
688*d6b92ffaSHans Petter Selasky goto cleanup;
689*d6b92ffaSHans Petter Selasky
690*d6b92ffaSHans Petter Selasky _destroy_ibnd_fabric_cache(fabric_cache);
691*d6b92ffaSHans Petter Selasky close(fd);
692*d6b92ffaSHans Petter Selasky return (ibnd_fabric_t *)&f_int->fabric;
693*d6b92ffaSHans Petter Selasky
694*d6b92ffaSHans Petter Selasky cleanup:
695*d6b92ffaSHans Petter Selasky ibnd_destroy_fabric((ibnd_fabric_t *)f_int);
696*d6b92ffaSHans Petter Selasky _destroy_ibnd_fabric_cache(fabric_cache);
697*d6b92ffaSHans Petter Selasky close(fd);
698*d6b92ffaSHans Petter Selasky return NULL;
699*d6b92ffaSHans Petter Selasky }
700*d6b92ffaSHans Petter Selasky
ibnd_write(int fd,const void * buf,size_t count)701*d6b92ffaSHans Petter Selasky static ssize_t ibnd_write(int fd, const void *buf, size_t count)
702*d6b92ffaSHans Petter Selasky {
703*d6b92ffaSHans Petter Selasky size_t count_done = 0;
704*d6b92ffaSHans Petter Selasky ssize_t ret;
705*d6b92ffaSHans Petter Selasky
706*d6b92ffaSHans Petter Selasky while ((count - count_done) > 0) {
707*d6b92ffaSHans Petter Selasky ret = write(fd, ((char *) buf) + count_done, count - count_done);
708*d6b92ffaSHans Petter Selasky if (ret < 0) {
709*d6b92ffaSHans Petter Selasky if (errno == EINTR)
710*d6b92ffaSHans Petter Selasky continue;
711*d6b92ffaSHans Petter Selasky else {
712*d6b92ffaSHans Petter Selasky IBND_DEBUG("write: %s\n", strerror(errno));
713*d6b92ffaSHans Petter Selasky return -1;
714*d6b92ffaSHans Petter Selasky }
715*d6b92ffaSHans Petter Selasky }
716*d6b92ffaSHans Petter Selasky count_done += ret;
717*d6b92ffaSHans Petter Selasky }
718*d6b92ffaSHans Petter Selasky return count_done;
719*d6b92ffaSHans Petter Selasky }
720*d6b92ffaSHans Petter Selasky
_marshall8(uint8_t * outbuf,uint8_t num)721*d6b92ffaSHans Petter Selasky static size_t _marshall8(uint8_t * outbuf, uint8_t num)
722*d6b92ffaSHans Petter Selasky {
723*d6b92ffaSHans Petter Selasky outbuf[0] = num;
724*d6b92ffaSHans Petter Selasky
725*d6b92ffaSHans Petter Selasky return (sizeof(num));
726*d6b92ffaSHans Petter Selasky }
727*d6b92ffaSHans Petter Selasky
_marshall16(uint8_t * outbuf,uint16_t num)728*d6b92ffaSHans Petter Selasky static size_t _marshall16(uint8_t * outbuf, uint16_t num)
729*d6b92ffaSHans Petter Selasky {
730*d6b92ffaSHans Petter Selasky outbuf[0] = num & 0x00FF;
731*d6b92ffaSHans Petter Selasky outbuf[1] = (num & 0xFF00) >> 8;
732*d6b92ffaSHans Petter Selasky
733*d6b92ffaSHans Petter Selasky return (sizeof(num));
734*d6b92ffaSHans Petter Selasky }
735*d6b92ffaSHans Petter Selasky
_marshall32(uint8_t * outbuf,uint32_t num)736*d6b92ffaSHans Petter Selasky static size_t _marshall32(uint8_t * outbuf, uint32_t num)
737*d6b92ffaSHans Petter Selasky {
738*d6b92ffaSHans Petter Selasky outbuf[0] = num & 0x000000FF;
739*d6b92ffaSHans Petter Selasky outbuf[1] = (num & 0x0000FF00) >> 8;
740*d6b92ffaSHans Petter Selasky outbuf[2] = (num & 0x00FF0000) >> 16;
741*d6b92ffaSHans Petter Selasky outbuf[3] = (num & 0xFF000000) >> 24;
742*d6b92ffaSHans Petter Selasky
743*d6b92ffaSHans Petter Selasky return (sizeof(num));
744*d6b92ffaSHans Petter Selasky }
745*d6b92ffaSHans Petter Selasky
_marshall64(uint8_t * outbuf,uint64_t num)746*d6b92ffaSHans Petter Selasky static size_t _marshall64(uint8_t * outbuf, uint64_t num)
747*d6b92ffaSHans Petter Selasky {
748*d6b92ffaSHans Petter Selasky outbuf[0] = (uint8_t) num;
749*d6b92ffaSHans Petter Selasky outbuf[1] = (uint8_t) (num >> 8);
750*d6b92ffaSHans Petter Selasky outbuf[2] = (uint8_t) (num >> 16);
751*d6b92ffaSHans Petter Selasky outbuf[3] = (uint8_t) (num >> 24);
752*d6b92ffaSHans Petter Selasky outbuf[4] = (uint8_t) (num >> 32);
753*d6b92ffaSHans Petter Selasky outbuf[5] = (uint8_t) (num >> 40);
754*d6b92ffaSHans Petter Selasky outbuf[6] = (uint8_t) (num >> 48);
755*d6b92ffaSHans Petter Selasky outbuf[7] = (uint8_t) (num >> 56);
756*d6b92ffaSHans Petter Selasky
757*d6b92ffaSHans Petter Selasky return (sizeof(num));
758*d6b92ffaSHans Petter Selasky }
759*d6b92ffaSHans Petter Selasky
_marshall_buf(void * outbuf,const void * inbuf,unsigned int len)760*d6b92ffaSHans Petter Selasky static size_t _marshall_buf(void *outbuf, const void *inbuf, unsigned int len)
761*d6b92ffaSHans Petter Selasky {
762*d6b92ffaSHans Petter Selasky memcpy(outbuf, inbuf, len);
763*d6b92ffaSHans Petter Selasky
764*d6b92ffaSHans Petter Selasky return len;
765*d6b92ffaSHans Petter Selasky }
766*d6b92ffaSHans Petter Selasky
_cache_header_info(int fd,ibnd_fabric_t * fabric)767*d6b92ffaSHans Petter Selasky static int _cache_header_info(int fd, ibnd_fabric_t * fabric)
768*d6b92ffaSHans Petter Selasky {
769*d6b92ffaSHans Petter Selasky uint8_t buf[IBND_FABRIC_CACHE_BUFLEN];
770*d6b92ffaSHans Petter Selasky size_t offset = 0;
771*d6b92ffaSHans Petter Selasky
772*d6b92ffaSHans Petter Selasky /* Store magic number, version, and other important info */
773*d6b92ffaSHans Petter Selasky /* For this caching lib, we always assume cached as little endian */
774*d6b92ffaSHans Petter Selasky
775*d6b92ffaSHans Petter Selasky offset += _marshall32(buf + offset, IBND_FABRIC_CACHE_MAGIC);
776*d6b92ffaSHans Petter Selasky offset += _marshall32(buf + offset, IBND_FABRIC_CACHE_VERSION);
777*d6b92ffaSHans Petter Selasky /* save space for node count */
778*d6b92ffaSHans Petter Selasky offset += _marshall32(buf + offset, 0);
779*d6b92ffaSHans Petter Selasky /* save space for port count */
780*d6b92ffaSHans Petter Selasky offset += _marshall32(buf + offset, 0);
781*d6b92ffaSHans Petter Selasky offset += _marshall64(buf + offset, fabric->from_node->guid);
782*d6b92ffaSHans Petter Selasky offset += _marshall32(buf + offset, fabric->maxhops_discovered);
783*d6b92ffaSHans Petter Selasky
784*d6b92ffaSHans Petter Selasky if (ibnd_write(fd, buf, offset) < 0)
785*d6b92ffaSHans Petter Selasky return -1;
786*d6b92ffaSHans Petter Selasky
787*d6b92ffaSHans Petter Selasky return 0;
788*d6b92ffaSHans Petter Selasky }
789*d6b92ffaSHans Petter Selasky
_cache_header_counts(int fd,unsigned int node_count,unsigned int port_count)790*d6b92ffaSHans Petter Selasky static int _cache_header_counts(int fd, unsigned int node_count,
791*d6b92ffaSHans Petter Selasky unsigned int port_count)
792*d6b92ffaSHans Petter Selasky {
793*d6b92ffaSHans Petter Selasky uint8_t buf[IBND_FABRIC_CACHE_BUFLEN];
794*d6b92ffaSHans Petter Selasky size_t offset = 0;
795*d6b92ffaSHans Petter Selasky
796*d6b92ffaSHans Petter Selasky offset += _marshall32(buf + offset, node_count);
797*d6b92ffaSHans Petter Selasky offset += _marshall32(buf + offset, port_count);
798*d6b92ffaSHans Petter Selasky
799*d6b92ffaSHans Petter Selasky if (lseek(fd, IBND_FABRIC_CACHE_COUNT_OFFSET, SEEK_SET) < 0) {
800*d6b92ffaSHans Petter Selasky IBND_DEBUG("lseek: %s\n", strerror(errno));
801*d6b92ffaSHans Petter Selasky return -1;
802*d6b92ffaSHans Petter Selasky }
803*d6b92ffaSHans Petter Selasky
804*d6b92ffaSHans Petter Selasky if (ibnd_write(fd, buf, offset) < 0)
805*d6b92ffaSHans Petter Selasky return -1;
806*d6b92ffaSHans Petter Selasky
807*d6b92ffaSHans Petter Selasky return 0;
808*d6b92ffaSHans Petter Selasky }
809*d6b92ffaSHans Petter Selasky
_cache_node(int fd,ibnd_node_t * node)810*d6b92ffaSHans Petter Selasky static int _cache_node(int fd, ibnd_node_t * node)
811*d6b92ffaSHans Petter Selasky {
812*d6b92ffaSHans Petter Selasky uint8_t buf[IBND_FABRIC_CACHE_BUFLEN];
813*d6b92ffaSHans Petter Selasky size_t offset = 0;
814*d6b92ffaSHans Petter Selasky size_t ports_stored_offset = 0;
815*d6b92ffaSHans Petter Selasky uint8_t ports_stored_count = 0;
816*d6b92ffaSHans Petter Selasky int i;
817*d6b92ffaSHans Petter Selasky
818*d6b92ffaSHans Petter Selasky offset += _marshall16(buf + offset, node->smalid);
819*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, node->smalmc);
820*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, (uint8_t) node->smaenhsp0);
821*d6b92ffaSHans Petter Selasky offset += _marshall_buf(buf + offset, node->switchinfo,
822*d6b92ffaSHans Petter Selasky IB_SMP_DATA_SIZE);
823*d6b92ffaSHans Petter Selasky offset += _marshall64(buf + offset, node->guid);
824*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, (uint8_t) node->type);
825*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, (uint8_t) node->numports);
826*d6b92ffaSHans Petter Selasky offset += _marshall_buf(buf + offset, node->info, IB_SMP_DATA_SIZE);
827*d6b92ffaSHans Petter Selasky offset += _marshall_buf(buf + offset, node->nodedesc, IB_SMP_DATA_SIZE);
828*d6b92ffaSHans Petter Selasky /* need to come back later and store number of stored ports
829*d6b92ffaSHans Petter Selasky * because port entries can be NULL or (in the case of switches)
830*d6b92ffaSHans Petter Selasky * there is an additional port 0 not accounted for in numports.
831*d6b92ffaSHans Petter Selasky */
832*d6b92ffaSHans Petter Selasky ports_stored_offset = offset;
833*d6b92ffaSHans Petter Selasky offset += sizeof(uint8_t);
834*d6b92ffaSHans Petter Selasky
835*d6b92ffaSHans Petter Selasky for (i = 0; i <= node->numports; i++) {
836*d6b92ffaSHans Petter Selasky if (node->ports[i]) {
837*d6b92ffaSHans Petter Selasky offset += _marshall64(buf + offset,
838*d6b92ffaSHans Petter Selasky node->ports[i]->guid);
839*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset,
840*d6b92ffaSHans Petter Selasky (uint8_t) node->ports[i]->portnum);
841*d6b92ffaSHans Petter Selasky ports_stored_count++;
842*d6b92ffaSHans Petter Selasky }
843*d6b92ffaSHans Petter Selasky }
844*d6b92ffaSHans Petter Selasky
845*d6b92ffaSHans Petter Selasky /* go back and store number of port keys stored */
846*d6b92ffaSHans Petter Selasky _marshall8(buf + ports_stored_offset, ports_stored_count);
847*d6b92ffaSHans Petter Selasky
848*d6b92ffaSHans Petter Selasky if (ibnd_write(fd, buf, offset) < 0)
849*d6b92ffaSHans Petter Selasky return -1;
850*d6b92ffaSHans Petter Selasky
851*d6b92ffaSHans Petter Selasky return 0;
852*d6b92ffaSHans Petter Selasky }
853*d6b92ffaSHans Petter Selasky
_cache_port(int fd,ibnd_port_t * port)854*d6b92ffaSHans Petter Selasky static int _cache_port(int fd, ibnd_port_t * port)
855*d6b92ffaSHans Petter Selasky {
856*d6b92ffaSHans Petter Selasky uint8_t buf[IBND_FABRIC_CACHE_BUFLEN];
857*d6b92ffaSHans Petter Selasky size_t offset = 0;
858*d6b92ffaSHans Petter Selasky
859*d6b92ffaSHans Petter Selasky offset += _marshall64(buf + offset, port->guid);
860*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, (uint8_t) port->portnum);
861*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, (uint8_t) port->ext_portnum);
862*d6b92ffaSHans Petter Selasky offset += _marshall16(buf + offset, port->base_lid);
863*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, port->lmc);
864*d6b92ffaSHans Petter Selasky offset += _marshall_buf(buf + offset, port->info, IB_SMP_DATA_SIZE);
865*d6b92ffaSHans Petter Selasky offset += _marshall64(buf + offset, port->node->guid);
866*d6b92ffaSHans Petter Selasky if (port->remoteport) {
867*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, 1);
868*d6b92ffaSHans Petter Selasky offset += _marshall64(buf + offset, port->remoteport->guid);
869*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, (uint8_t) port->remoteport->portnum);
870*d6b92ffaSHans Petter Selasky } else {
871*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, 0);
872*d6b92ffaSHans Petter Selasky offset += _marshall64(buf + offset, 0);
873*d6b92ffaSHans Petter Selasky offset += _marshall8(buf + offset, 0);
874*d6b92ffaSHans Petter Selasky }
875*d6b92ffaSHans Petter Selasky
876*d6b92ffaSHans Petter Selasky if (ibnd_write(fd, buf, offset) < 0)
877*d6b92ffaSHans Petter Selasky return -1;
878*d6b92ffaSHans Petter Selasky
879*d6b92ffaSHans Petter Selasky return 0;
880*d6b92ffaSHans Petter Selasky }
881*d6b92ffaSHans Petter Selasky
ibnd_cache_fabric(ibnd_fabric_t * fabric,const char * file,unsigned int flags)882*d6b92ffaSHans Petter Selasky int ibnd_cache_fabric(ibnd_fabric_t * fabric, const char *file,
883*d6b92ffaSHans Petter Selasky unsigned int flags)
884*d6b92ffaSHans Petter Selasky {
885*d6b92ffaSHans Petter Selasky struct stat statbuf;
886*d6b92ffaSHans Petter Selasky ibnd_node_t *node = NULL;
887*d6b92ffaSHans Petter Selasky ibnd_node_t *node_next = NULL;
888*d6b92ffaSHans Petter Selasky unsigned int node_count = 0;
889*d6b92ffaSHans Petter Selasky ibnd_port_t *port = NULL;
890*d6b92ffaSHans Petter Selasky ibnd_port_t *port_next = NULL;
891*d6b92ffaSHans Petter Selasky unsigned int port_count = 0;
892*d6b92ffaSHans Petter Selasky int fd;
893*d6b92ffaSHans Petter Selasky int i;
894*d6b92ffaSHans Petter Selasky
895*d6b92ffaSHans Petter Selasky if (!fabric) {
896*d6b92ffaSHans Petter Selasky IBND_DEBUG("fabric parameter NULL\n");
897*d6b92ffaSHans Petter Selasky return -1;
898*d6b92ffaSHans Petter Selasky }
899*d6b92ffaSHans Petter Selasky
900*d6b92ffaSHans Petter Selasky if (!file) {
901*d6b92ffaSHans Petter Selasky IBND_DEBUG("file parameter NULL\n");
902*d6b92ffaSHans Petter Selasky return -1;
903*d6b92ffaSHans Petter Selasky }
904*d6b92ffaSHans Petter Selasky
905*d6b92ffaSHans Petter Selasky if (!(flags & IBND_CACHE_FABRIC_FLAG_NO_OVERWRITE)) {
906*d6b92ffaSHans Petter Selasky if (!stat(file, &statbuf)) {
907*d6b92ffaSHans Petter Selasky if (unlink(file) < 0) {
908*d6b92ffaSHans Petter Selasky IBND_DEBUG("error removing '%s': %s\n",
909*d6b92ffaSHans Petter Selasky file, strerror(errno));
910*d6b92ffaSHans Petter Selasky return -1;
911*d6b92ffaSHans Petter Selasky }
912*d6b92ffaSHans Petter Selasky }
913*d6b92ffaSHans Petter Selasky }
914*d6b92ffaSHans Petter Selasky else {
915*d6b92ffaSHans Petter Selasky if (!stat(file, &statbuf)) {
916*d6b92ffaSHans Petter Selasky IBND_DEBUG("file '%s' already exists\n", file);
917*d6b92ffaSHans Petter Selasky return -1;
918*d6b92ffaSHans Petter Selasky }
919*d6b92ffaSHans Petter Selasky }
920*d6b92ffaSHans Petter Selasky
921*d6b92ffaSHans Petter Selasky if ((fd = open(file, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) {
922*d6b92ffaSHans Petter Selasky IBND_DEBUG("open: %s\n", strerror(errno));
923*d6b92ffaSHans Petter Selasky return -1;
924*d6b92ffaSHans Petter Selasky }
925*d6b92ffaSHans Petter Selasky
926*d6b92ffaSHans Petter Selasky if (_cache_header_info(fd, fabric) < 0)
927*d6b92ffaSHans Petter Selasky goto cleanup;
928*d6b92ffaSHans Petter Selasky
929*d6b92ffaSHans Petter Selasky node = fabric->nodes;
930*d6b92ffaSHans Petter Selasky while (node) {
931*d6b92ffaSHans Petter Selasky node_next = node->next;
932*d6b92ffaSHans Petter Selasky
933*d6b92ffaSHans Petter Selasky if (_cache_node(fd, node) < 0)
934*d6b92ffaSHans Petter Selasky goto cleanup;
935*d6b92ffaSHans Petter Selasky
936*d6b92ffaSHans Petter Selasky node_count++;
937*d6b92ffaSHans Petter Selasky node = node_next;
938*d6b92ffaSHans Petter Selasky }
939*d6b92ffaSHans Petter Selasky
940*d6b92ffaSHans Petter Selasky for (i = 0; i < HTSZ; i++) {
941*d6b92ffaSHans Petter Selasky port = fabric->portstbl[i];
942*d6b92ffaSHans Petter Selasky while (port) {
943*d6b92ffaSHans Petter Selasky port_next = port->htnext;
944*d6b92ffaSHans Petter Selasky
945*d6b92ffaSHans Petter Selasky if (_cache_port(fd, port) < 0)
946*d6b92ffaSHans Petter Selasky goto cleanup;
947*d6b92ffaSHans Petter Selasky
948*d6b92ffaSHans Petter Selasky port_count++;
949*d6b92ffaSHans Petter Selasky port = port_next;
950*d6b92ffaSHans Petter Selasky }
951*d6b92ffaSHans Petter Selasky }
952*d6b92ffaSHans Petter Selasky
953*d6b92ffaSHans Petter Selasky if (_cache_header_counts(fd, node_count, port_count) < 0)
954*d6b92ffaSHans Petter Selasky goto cleanup;
955*d6b92ffaSHans Petter Selasky
956*d6b92ffaSHans Petter Selasky if (close(fd) < 0) {
957*d6b92ffaSHans Petter Selasky IBND_DEBUG("close: %s\n", strerror(errno));
958*d6b92ffaSHans Petter Selasky goto cleanup;
959*d6b92ffaSHans Petter Selasky }
960*d6b92ffaSHans Petter Selasky
961*d6b92ffaSHans Petter Selasky return 0;
962*d6b92ffaSHans Petter Selasky
963*d6b92ffaSHans Petter Selasky cleanup:
964*d6b92ffaSHans Petter Selasky unlink(file);
965*d6b92ffaSHans Petter Selasky close(fd);
966*d6b92ffaSHans Petter Selasky return -1;
967*d6b92ffaSHans Petter Selasky }
968