2e800d18d9741a3721be6b5ed60f34eb0003c878
[mirror/winof/.git] / ulp / opensm / user / opensm / osm_opensm.c
1 /*
2  * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2005 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 the OpenIB.org BSD license
7  * below:
8  *
9  *     Redistribution and use in source and binary forms, with or
10  *     without modification, are permitted provided that the following
11  *     conditions are met:
12  *
13  *      - Redistributions of source code must retain the above
14  *        copyright notice, this list of conditions and the following
15  *        disclaimer.
16  *
17  *      - Redistributions in binary form must reproduce the above
18  *        copyright notice, this list of conditions and the following
19  *        disclaimer in the documentation and/or other materials
20  *        provided with the distribution.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29  * SOFTWARE.
30  *
31  * $Id$
32  */
33
34
35 /*
36  * Abstract:
37  *    Implementation of osm_opensm_t.
38  * This object represents the opensm super object.
39  * This object is part of the opensm family of objects.
40  *
41  * Environment:
42  *    Linux User Mode
43  *
44  * $Revision: 1.7 $
45  */
46
47 #if HAVE_CONFIG_H
48 #  include <config.h>
49 #endif /* HAVE_CONFIG_H */
50
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <complib/cl_memory.h>
54 #include <complib/cl_signal_osd.h>
55 #include <opensm/cl_dispatcher.h>
56 #include <complib/cl_passivelock.h>
57 #include <vendor/osm_vendor_api.h>
58 #include <opensm/osm_base.h>
59 #include <opensm/osm_opensm.h>
60 #include <opensm/osm_log.h>
61 #include <opensm/osm_subnet.h>
62 #include <opensm/osm_sm.h>
63 #include <opensm/osm_vl15intf.h>
64
65 /**********************************************************************
66  **********************************************************************/
67 void
68 osm_opensm_construct(
69    IN osm_opensm_t * const p_osm )
70 {
71    cl_memclr( p_osm, sizeof( *p_osm ) );
72    osm_subn_construct( &p_osm->subn );
73    osm_sm_construct( &p_osm->sm );
74    osm_sa_construct( &p_osm->sa );
75    osm_db_construct( &p_osm->db );
76    osm_mad_pool_construct( &p_osm->mad_pool );
77    osm_vl15_construct( &p_osm->vl15 );
78    osm_log_construct( &p_osm->log );
79 }
80
81 /**********************************************************************
82  **********************************************************************/
83 void
84 osm_opensm_destroy(
85    IN osm_opensm_t * const p_osm )
86 {
87
88    /* in case of shutdown through exit proc - no ^C */
89    osm_exit_flag = TRUE;
90
91    /* 
92     * First of all - Clear the is_sm bit.
93     */
94    if( p_osm->sm.mad_ctrl.h_bind )
95       osm_vendor_set_sm( p_osm->sm.mad_ctrl.h_bind, FALSE );
96
97    /* shut down the SA
98     * - unbind from Q1 Messages and 
99     */
100    osm_sa_shutdown( &p_osm->sa );
101
102    /* shut down the SM 
103     * - make sure the SM sweeper thread exited
104     * - unbind from Q0 Messages and 
105     */
106    osm_sm_shutdown( &p_osm->sm );
107
108    /* shut down the dispatcher - so no new messages cross */
109    cl_disp_shutdown( &p_osm->disp );
110
111    /* cleanup all messages on VL15 fifo that were not sent yet */
112    osm_vl15_shutdown( &p_osm->vl15, &p_osm->mad_pool );
113
114    /* lock the whole thing so we do not get any requests etc */
115    cl_plock_excl_acquire( &p_osm->lock );
116
117    /* do the destruction in reverse init order */
118    updn_destroy( p_osm->p_updn_ucast_routing );
119    osm_sa_destroy( &p_osm->sa );
120    osm_sm_destroy( &p_osm->sm );
121    osm_db_destroy( &p_osm->db );
122    osm_vl15_destroy( &p_osm->vl15, &p_osm->mad_pool );
123    osm_mad_pool_destroy( &p_osm->mad_pool );
124    osm_vendor_delete( &p_osm->p_vendor );
125    osm_subn_destroy( &p_osm->subn );
126    cl_disp_destroy( &p_osm->disp );
127
128    cl_plock_release( &p_osm->lock );
129    cl_plock_destroy( &p_osm->lock );
130
131    cl_mem_display(  );
132
133    osm_log_destroy( &p_osm->log );
134 }
135
136 /**********************************************************************
137  **********************************************************************/
138 static void
139 osm_opensm_create_mcgroups(
140    IN osm_opensm_t * const p_osm,
141    IN const osm_subn_opt_t * const p_opt )
142 {
143    OSM_LOG_ENTER( &p_osm->log, osm_opensm_create_mcgroups );
144    osm_sa_create_template_record_ipoib( &p_osm->sa, p_opt );
145    OSM_LOG_EXIT( &p_osm->log );
146 }
147
148 /**********************************************************************
149  * SHUT DOWN IS CONTROLLED BY A GLOBAL EXIT FLAG
150  **********************************************************************/
151 #ifndef __WIN__
152 static osm_opensm_t *__p_osm_to_signal;
153
154 void
155 __sig_handler(
156    int signum )
157 {
158    static int got_signal = 0;
159
160    if( signum != SIGHUP )
161    {
162       if( !got_signal )
163       {
164          got_signal++;
165          printf( "OpenSM: Got signal %d - exiting...\n", signum );
166          osm_exit_flag = 1;
167       }
168    }
169    else
170    {
171       /* a HUP signal should only start a new heavy sweep */
172       __p_osm_to_signal->subn.force_immediate_heavy_sweep = TRUE;
173       osm_state_mgr_process( &__p_osm_to_signal->sm.state_mgr,
174                              OSM_SIGNAL_SWEEP );
175    }
176 }
177
178 void
179 osm_reg_sig_handler(
180    IN osm_opensm_t * const p_osm )
181 {
182    __p_osm_to_signal = p_osm;
183    cl_reg_sig_hdl( SIGINT, __sig_handler );
184    cl_reg_sig_hdl( SIGTERM, __sig_handler );
185    cl_reg_sig_hdl( SIGHUP, __sig_handler );
186    osm_exit_flag = 0;
187
188    return;
189 }
190 #endif
191
192 /**********************************************************************
193  **********************************************************************/
194 ib_api_status_t
195 osm_opensm_init(
196    IN osm_opensm_t * const p_osm,
197    IN const osm_subn_opt_t * const p_opt )
198 {
199    ib_api_status_t status;
200
201    /* Can't use log macros here, since we're initializing the log. */
202    osm_opensm_construct( p_osm );
203
204    status = osm_log_init( &p_osm->log, p_opt->force_log_flush,
205                           p_opt->log_flags, p_opt->log_file );
206    if( status != IB_SUCCESS )
207       return ( status );
208
209    /* If there is a log level defined - add the OSM_VERSION to it. */
210    osm_log( &p_osm->log,
211             osm_log_get_level( &p_osm->log ) & ( OSM_LOG_SYS ^ 0xFF ), "%s\n",
212             OSM_VERSION );
213    /* Write the OSM_VERSION to the SYS_LOG */
214    osm_log( &p_osm->log, OSM_LOG_SYS, "%s\n", OSM_VERSION );   /* Format Waived */
215
216    osm_log( &p_osm->log, OSM_LOG_FUNCS, "osm_opensm_init: [\n" ); /* Format Waived */
217
218    status = cl_plock_init( &p_osm->lock );
219    if( status != IB_SUCCESS )
220       goto Exit;
221
222    if( p_opt->single_thread )
223    {
224       osm_log( &p_osm->log, OSM_LOG_INFO,
225                "osm_opensm_init: Forcing single threaded dispatcher.\n" );
226       status = cl_disp_init( &p_osm->disp, 1, "opensm" );
227    }
228    else
229    {
230       /*
231        * Normal behavior is to initialize the dispatcher with
232        * one thread per CPU, as specified by a thread count of '0'.
233        */
234       status = cl_disp_init( &p_osm->disp, 0, "opensm" );
235    }
236
237    if( status != IB_SUCCESS )
238       goto Exit;
239    status = osm_subn_init( &p_osm->subn, p_opt );
240    if( status != IB_SUCCESS )
241       goto Exit;
242
243    p_osm->p_vendor =
244       osm_vendor_new( &p_osm->log, p_opt->transaction_timeout );
245    if( p_osm->p_vendor == NULL )
246    {
247       status = IB_INSUFFICIENT_RESOURCES;
248       goto Exit;
249    }
250
251    status = osm_mad_pool_init( &p_osm->mad_pool, &p_osm->log );
252    if( status != IB_SUCCESS )
253       goto Exit;
254
255    status = osm_vl15_init( &p_osm->vl15,
256                            p_osm->p_vendor,
257                            &p_osm->log, &p_osm->stats, p_opt->max_wire_smps );
258    if( status != IB_SUCCESS )
259       goto Exit;
260
261    /* the DB is in use by the SM and SA so init before */
262    status = osm_db_init( &p_osm->db, &p_osm->log );
263    if( status != IB_SUCCESS )
264       goto Exit;
265
266    status = osm_sm_init( &p_osm->sm,
267                          &p_osm->subn,
268                          &p_osm->db,
269                          p_osm->p_vendor,
270                          &p_osm->mad_pool,
271                          &p_osm->vl15,
272                          &p_osm->log,
273                          &p_osm->stats, &p_osm->disp, &p_osm->lock );
274
275    if( status != IB_SUCCESS )
276       goto Exit;
277
278    status = osm_sa_init( &p_osm->sm,
279                          &p_osm->sa,
280                          &p_osm->subn,
281                          p_osm->p_vendor,
282                          &p_osm->mad_pool,
283                          &p_osm->log,
284                          &p_osm->stats, &p_osm->disp, &p_osm->lock );
285
286    if( status != IB_SUCCESS )
287       goto Exit;
288
289    osm_opensm_create_mcgroups( p_osm, p_opt );
290
291    /* HACK - the UpDown manager should have been a part of the osm_sm_t */
292    /* Init updn struct */
293    p_osm->p_updn_ucast_routing = updn_construct(  );
294    status = updn_init( p_osm->p_updn_ucast_routing );
295    if( status != IB_SUCCESS )
296       goto Exit;
297
298  Exit:
299    osm_log( &p_osm->log, OSM_LOG_FUNCS, "osm_opensm_init: ]\n" ); /* Format Waived */
300    return ( status );
301 }
302
303 /**********************************************************************
304  **********************************************************************/
305 ib_api_status_t
306 osm_opensm_bind(
307    IN osm_opensm_t * const p_osm,
308    IN const ib_net64_t guid )
309 {
310    ib_api_status_t status;
311
312    OSM_LOG_ENTER( &p_osm->log, osm_opensm_bind );
313
314    status = osm_sm_bind( &p_osm->sm, guid );
315    if( status != IB_SUCCESS )
316       goto Exit;
317
318    status = osm_sa_bind( &p_osm->sa, guid );
319    if( status != IB_SUCCESS )
320       goto Exit;
321  Exit:
322    OSM_LOG_EXIT( &p_osm->log );
323    return ( status );
324 }