Whamcloud - gitweb
Land b_smallfix onto HEAD (20040414_1359)
[fs/lustre-release.git] / lustre / ptlbd / client.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (c) 2002, 2003 Cluster File Systems, Inc.
5  *   Author: Zach Brown <zab@clusterfs.com>
6  *
7  *   This file is part of Lustre, http://www.lustre.org.
8  *
9  *   Lustre is free software; you can redistribute it and/or
10  *   modify it under the terms of version 2 of the GNU General Public
11  *   License as published by the Free Software Foundation.
12  *
13  *   Lustre is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with Lustre; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include <linux/version.h>
24 #include <linux/module.h>
25 #include <linux/fs.h>
26
27 #define DEBUG_SUBSYSTEM S_PTLBD
28
29 #include <linux/obd_support.h>
30 #include <linux/obd_class.h>
31 #include <linux/lustre_debug.h>
32 #include <linux/lprocfs_status.h>
33 #include <linux/obd_ptlbd.h>
34
35 static int ptlbd_cl_setup(struct obd_device *obd, obd_count len, void *buf)
36 {
37         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
38         struct lprocfs_static_vars lvars;
39         struct obd_import *imp;
40         struct lustre_cfg* lcfg = buf;
41         ENTRY;
42
43         if (ptlbd->bd_import != NULL)
44                 RETURN(-EALREADY);
45
46         if (lcfg->lcfg_inllen1 < 1) {
47                 CERROR("requires a PTLBD server UUID\n");
48                 RETURN(-EINVAL);
49         }
50
51         if (lcfg->lcfg_inllen1 > 37) {
52                 CERROR("PTLBD server UUID must be less than 38 characters\n");
53                 RETURN(-EINVAL);
54         }
55
56         obd_str2uuid(&ptlbd->bd_server_uuid, lcfg->lcfg_inlbuf1);
57
58         /*
59          * from client_obd_connect.. *shrug*
60          */
61         imp = ptlbd->bd_import = class_new_import();
62         imp->imp_connection = ptlrpc_uuid_to_connection(&ptlbd->bd_server_uuid);
63         if (!imp->imp_connection) {
64                 class_destroy_import(imp);
65                 class_import_put(imp);
66                 RETURN(-ENOENT);
67         }
68         imp->imp_state = LUSTRE_IMP_FULL;
69
70         ptlrpc_init_client(PTLBD_REQUEST_PORTAL, PTLBD_REPLY_PORTAL,
71                         "ptlbd", &ptlbd->bd_client);
72         imp->imp_client = &ptlbd->bd_client;
73         imp->imp_obd = obd;
74         memcpy(imp->imp_target_uuid.uuid, lcfg->lcfg_inlbuf1,
75                lcfg->lcfg_inllen1);
76         ptlbd_blk_register(ptlbd);
77
78         lprocfs_init_vars(ptlbd_cl, &lvars);
79         lprocfs_obd_setup(obd, lvars.obd_vars);
80
81         RETURN(0);
82 }
83
84 static int ptlbd_cl_cleanup(struct obd_device *obd, int flags)
85 {
86         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
87         struct obd_import *imp;
88         ENTRY;
89
90         if ((!ptlbd) || (!(imp = ptlbd->bd_import)))
91                 RETURN(-ENOENT);
92
93         if (!imp->imp_connection)
94                 RETURN(-ENOENT);
95
96         lprocfs_obd_cleanup(obd);
97
98         ptlrpc_cleanup_client(imp);
99         ptlrpc_put_connection(imp->imp_connection);
100
101         class_destroy_import(imp);
102         class_import_put(imp);
103
104         RETURN(0);
105 }
106
107
108 /* modelled after ptlrpc_import_connect() */
109 int ptlbd_cl_connect(struct lustre_handle *conn, struct obd_device *obd,
110                      struct obd_uuid *target_uuid)
111 {
112         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
113         struct obd_import *imp = ptlbd->bd_import;
114         struct obd_export *exp;
115         struct ptlrpc_request *request;
116         int     rc, size[] = {sizeof(imp->imp_target_uuid),
117                               sizeof(obd->obd_uuid),
118                               sizeof(*conn)};
119         char *tmp[] = {imp->imp_target_uuid.uuid,
120                        obd->obd_uuid.uuid,
121                        (char*)conn};
122         ENTRY;
123
124         if (!conn || !obd || !target_uuid)
125                 RETURN(-EINVAL);
126
127         rc = class_connect(conn, obd, target_uuid);
128         if (rc)
129                 RETURN(rc);
130         exp = class_conn2export(conn);
131
132         request = ptlrpc_prep_req(imp, PTLBD_CONNECT, 3, size, tmp);
133         if (!request)
134                 GOTO(out_disco, rc = -ENOMEM);
135         request->rq_send_state = LUSTRE_IMP_NEW;
136         request->rq_replen = lustre_msg_size(0, NULL);
137
138         imp->imp_dlm_handle = *conn;
139
140         imp->imp_state = LUSTRE_IMP_NEW;
141         rc = ptlrpc_queue_wait(request);
142         if (rc)
143                 GOTO(out_req, rc);
144
145         exp->exp_connection = ptlrpc_connection_addref(imp->imp_connection);
146
147         imp->imp_state = LUSTRE_IMP_FULL;
148         imp->imp_remote_handle = request->rq_repmsg->handle;
149
150 out_req:
151         ptlrpc_req_finished(request);
152 out_disco:
153         if (rc)
154                 class_disconnect(exp, 0);
155         class_export_put(exp);
156         RETURN(rc);
157 }
158
159
160 /* modelled after ptlrpc_import_disconnect() */
161 int ptlbd_cl_disconnect(struct obd_export *exp, int failover)
162 {
163         struct obd_device *obd = exp->exp_obd;
164         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
165         struct obd_import *imp = ptlbd->bd_import;
166         struct ptlrpc_request *request;
167         int     rc, err;
168         ENTRY;
169
170         if (!obd)
171                 RETURN(-EINVAL);
172
173         request = ptlrpc_prep_req(imp, PTLBD_DISCONNECT, 0, NULL, NULL);
174         if (!request)
175                 GOTO(out_req, rc = -ENOMEM);
176
177         request->rq_replen = lustre_msg_size(0, NULL);
178         request->rq_send_state = LUSTRE_IMP_FULL;
179
180         rc = ptlrpc_queue_wait(request);
181
182 out_req:
183         if (request)
184                 ptlrpc_req_finished(request);
185         err = class_disconnect(exp, 0);
186         memset(&imp->imp_remote_handle, 0, sizeof(imp->imp_remote_handle));
187         if (!rc && err)
188                 rc = err;
189         RETURN(rc);
190 }
191
192
193 static struct obd_ops ptlbd_cl_obd_ops = {
194         o_owner:        THIS_MODULE,
195         o_setup:        ptlbd_cl_setup,
196         o_cleanup:      ptlbd_cl_cleanup,
197         o_connect:      ptlbd_cl_connect,
198         o_disconnect:   ptlbd_cl_disconnect,
199 };
200
201 static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
202 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
203 LPROCFS_INIT_VARS(ptlbd_cl, lprocfs_module_vars, lprocfs_obd_vars)
204
205 int ptlbd_cl_init(void)
206 {
207         struct lprocfs_static_vars lvars;
208
209         lprocfs_init_vars(ptlbd_cl,&lvars);
210         return class_register_type(&ptlbd_cl_obd_ops, lvars.module_vars,
211                                    OBD_PTLBD_CL_DEVICENAME);
212 }
213
214 void ptlbd_cl_exit(void)
215 {
216         class_unregister_type(OBD_PTLBD_CL_DEVICENAME);
217 }
218
219
220
221 int ptlbd_do_connect(struct ptlbd_obd *ptlbd)
222 {
223         int     rc;
224         struct obd_device       *obd = ptlbd->bd_import->imp_obd;
225         struct lustre_handle conn;
226         ENTRY;
227
228         memset(&conn, 0, sizeof(conn));
229         rc = obd_connect(&conn, obd, &ptlbd->bd_server_uuid);
230         if (rc < 0)
231                 RETURN(rc);
232         ptlbd->bd_exp = class_conn2export(&conn);
233         RETURN(rc);
234 }
235
236
237 int ptlbd_do_disconnect(struct ptlbd_obd *ptlbd)
238 {
239         int     rc;
240         ENTRY;
241
242         rc = obd_disconnect(ptlbd->bd_exp, 0);
243         RETURN(rc);
244 }
245