Whamcloud - gitweb
e189b2a9d7361aee6fe639d3c5c5ea11d2e4d2ca
[fs/lustre-release.git] / lnet / lnet / module.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  */
34
35 #define DEBUG_SUBSYSTEM S_LNET
36 #include <lnet/lib-lnet.h>
37
38 static int config_on_load = 0;
39 CFS_MODULE_PARM(config_on_load, "i", int, 0444,
40                 "configure network at module load");
41
42 static struct mutex lnet_config_mutex;
43
44 int
45 lnet_configure (void *arg)
46 {
47         /* 'arg' only there so I can be passed to cfs_create_thread() */
48         int    rc = 0;
49
50         LNET_MUTEX_LOCK(&lnet_config_mutex);
51
52         if (!the_lnet.ln_niinit_self) {
53                 rc = LNetNIInit(LUSTRE_SRV_LNET_PID);
54                 if (rc >= 0) {
55                         the_lnet.ln_niinit_self = 1;
56                         rc = 0;
57                 }
58         }
59
60         LNET_MUTEX_UNLOCK(&lnet_config_mutex);
61         return rc;
62 }
63
64 int
65 lnet_unconfigure (void)
66 {
67         int   refcount;
68         
69         LNET_MUTEX_LOCK(&lnet_config_mutex);
70
71         if (the_lnet.ln_niinit_self) {
72                 the_lnet.ln_niinit_self = 0;
73                 LNetNIFini();
74         }
75
76         LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
77         refcount = the_lnet.ln_refcount;
78         LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
79
80         LNET_MUTEX_UNLOCK(&lnet_config_mutex);
81         return (refcount == 0) ? 0 : -EBUSY;
82 }
83
84 int
85 lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data)
86 {
87         int   rc;
88
89         switch (cmd) {
90         case IOC_LIBCFS_CONFIGURE:
91                 return lnet_configure(NULL);
92
93         case IOC_LIBCFS_UNCONFIGURE:
94                 return lnet_unconfigure();
95                 
96         default:
97                 /* Passing LNET_PID_ANY only gives me a ref if the net is up
98                  * already; I'll need it to ensure the net can't go down while
99                  * I'm called into it */
100                 rc = LNetNIInit(LNET_PID_ANY);
101                 if (rc >= 0) {
102                         rc = LNetCtl(cmd, data);
103                         LNetNIFini();
104                 }
105                 return rc;
106         }
107 }
108
109 DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);
110
111 int
112 init_lnet(void)
113 {
114         int                  rc;
115         ENTRY;
116
117         mutex_init(&lnet_config_mutex);
118
119         rc = LNetInit();
120         if (rc != 0) {
121                 CERROR("LNetInit: error %d\n", rc);
122                 RETURN(rc);
123         }
124
125         rc = libcfs_register_ioctl(&lnet_ioctl_handler);
126         LASSERT (rc == 0);
127
128         if (config_on_load) {
129                 /* Have to schedule a separate thread to avoid deadlocking
130                  * in modload */
131                 (void) cfs_create_thread(lnet_configure, NULL, 0);
132         }
133
134         RETURN(0);
135 }
136
137 void
138 fini_lnet(void)
139 {
140         int rc;
141
142         rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);
143         LASSERT (rc == 0);
144
145         LNetFini();
146 }
147
148 MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
149 MODULE_DESCRIPTION("Portals v3.1");
150 MODULE_LICENSE("GPL");
151
152 cfs_module(lnet, "1.0.0", init_lnet, fini_lnet);