Whamcloud - gitweb
land v0.9.1 on HEAD, in preparation for a 1.0.x branch
[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 obd_import *imp;
39         struct lustre_cfg* lcfg = buf;
40         ENTRY;
41
42         if (ptlbd->bd_import != NULL)
43                 RETURN(-EALREADY);
44
45         if (lcfg->lcfg_inllen1 < 1) {
46                 CERROR("requires a PTLBD server UUID\n");
47                 RETURN(-EINVAL);
48         }
49
50         if (lcfg->lcfg_inllen1 > 37) {
51                 CERROR("PTLBD server UUID must be less than 38 characters\n");
52                 RETURN(-EINVAL);
53         }
54
55         obd_str2uuid(&ptlbd->bd_server_uuid, lcfg->lcfg_inlbuf1);
56
57         /*
58          * from client_obd_connect.. *shrug*
59          */
60         imp = ptlbd->bd_import = class_new_import();
61         imp->imp_connection = ptlrpc_uuid_to_connection(&ptlbd->bd_server_uuid);
62         if (!imp->imp_connection) {
63                 class_destroy_import(imp);
64                 class_import_put(imp);
65                 RETURN(-ENOENT);
66         }
67         imp->imp_state = LUSTRE_IMP_FULL;
68
69         ptlrpc_init_client(PTLBD_REQUEST_PORTAL, PTLBD_REPLY_PORTAL, 
70                         "ptlbd", &ptlbd->bd_client);
71         imp->imp_client = &ptlbd->bd_client;
72         imp->imp_obd = obd;
73         memcpy(imp->imp_target_uuid.uuid, lcfg->lcfg_inlbuf1, 
74                lcfg->lcfg_inllen1);
75         ptlbd_blk_register(ptlbd);
76
77         RETURN(0);
78 }
79
80 static int ptlbd_cl_cleanup(struct obd_device *obd, int flags)
81 {
82         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
83         struct obd_import *imp;
84         ENTRY;
85
86         if ((!ptlbd) || (!(imp = ptlbd->bd_import)))
87                 RETURN(-ENOENT);
88
89         if (!imp->imp_connection)
90                 RETURN(-ENOENT);
91
92         ptlrpc_cleanup_client(imp);
93         ptlrpc_put_connection(imp->imp_connection);
94
95         class_destroy_import(imp);
96         class_import_put(imp);
97
98         RETURN(0);
99 }
100
101
102 /* modelled after ptlrpc_import_connect() */
103 int ptlbd_cl_connect(struct lustre_handle *conn, struct obd_device *obd,
104                      struct obd_uuid *target_uuid)
105 {
106         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
107         struct obd_import *imp = ptlbd->bd_import;
108         struct obd_export *exp;
109         struct ptlrpc_request *request;
110         int     rc, size[] = {sizeof(imp->imp_target_uuid),
111                               sizeof(obd->obd_uuid),
112                               sizeof(*conn)};
113         char *tmp[] = {imp->imp_target_uuid.uuid, 
114                        obd->obd_uuid.uuid,
115                        (char*)conn};
116         ENTRY;
117
118         if (!conn || !obd || !target_uuid)
119                 RETURN(-EINVAL);
120
121         rc = class_connect(conn, obd, target_uuid);
122         if (rc)
123                 RETURN(rc);
124         exp = class_conn2export(conn);
125
126         request = ptlrpc_prep_req(imp, PTLBD_CONNECT, 3, size, tmp);
127         if (!request)
128                 GOTO(out_disco, rc = -ENOMEM);
129         request->rq_send_state = LUSTRE_IMP_NEW;
130         request->rq_replen = lustre_msg_size(0, NULL);
131
132         imp->imp_dlm_handle = *conn;
133
134         imp->imp_state = LUSTRE_IMP_NEW;
135         rc = ptlrpc_queue_wait(request);
136         if (rc)
137                 GOTO(out_req, rc);
138
139         exp->exp_connection = ptlrpc_connection_addref(request->rq_connection);
140
141         imp->imp_state = LUSTRE_IMP_FULL;
142         imp->imp_remote_handle = request->rq_repmsg->handle;
143         
144 out_req:
145         ptlrpc_req_finished(request);
146 out_disco:
147         if (rc)
148                 class_disconnect(exp, 0);
149         class_export_put(exp);
150         RETURN(rc);
151 }
152
153
154 /* modelled after ptlrpc_import_disconnect() */
155 int ptlbd_cl_disconnect(struct obd_export *exp, int failover)
156 {
157         struct obd_device *obd = exp->exp_obd;
158         struct ptlbd_obd *ptlbd = &obd->u.ptlbd;
159         struct obd_import *imp = ptlbd->bd_import;
160         struct ptlrpc_request *request;
161         int     rc, err;
162         ENTRY;
163
164         if (!obd)
165                 RETURN(-EINVAL);
166
167         request = ptlrpc_prep_req(imp, PTLBD_DISCONNECT, 0, NULL, NULL);
168         if (!request)
169                 GOTO(out_req, rc = -ENOMEM);
170
171         request->rq_replen = lustre_msg_size(0, NULL);
172         request->rq_send_state = LUSTRE_IMP_FULL;
173
174         rc = ptlrpc_queue_wait(request);
175
176 out_req:
177         if (request)
178                 ptlrpc_req_finished(request);
179         err = class_disconnect(exp, 0);
180         memset(&imp->imp_remote_handle, 0, sizeof(imp->imp_remote_handle));
181         if (!rc && err)
182                 rc = err;
183         RETURN(rc);
184 }
185
186
187 static struct obd_ops ptlbd_cl_obd_ops = {
188         o_owner:        THIS_MODULE,
189         o_setup:        ptlbd_cl_setup,
190         o_cleanup:      ptlbd_cl_cleanup,
191         o_connect:      ptlbd_cl_connect,
192         o_disconnect:   ptlbd_cl_disconnect,
193 };
194
195 static struct lprocfs_vars lprocfs_obd_vars[] = { {0} };
196 static struct lprocfs_vars lprocfs_module_vars[] = { {0} };
197 LPROCFS_INIT_VARS(ptlbd_cl, lprocfs_module_vars, lprocfs_obd_vars)
198
199 int ptlbd_cl_init(void)
200 {
201         struct lprocfs_static_vars lvars;
202
203         lprocfs_init_vars(ptlbd_cl,&lvars);
204         return class_register_type(&ptlbd_cl_obd_ops, lvars.module_vars,
205                                    OBD_PTLBD_CL_DEVICENAME);
206 }
207
208 void ptlbd_cl_exit(void)
209 {
210         class_unregister_type(OBD_PTLBD_CL_DEVICENAME);
211 }
212
213
214
215 int ptlbd_do_connect(struct ptlbd_obd *ptlbd)
216 {
217         int     rc;
218         struct obd_device       *obd = ptlbd->bd_import->imp_obd;
219         struct lustre_handle conn;
220         ENTRY;
221
222         memset(&conn, 0, sizeof(conn));
223         rc = obd_connect(&conn, obd, &ptlbd->bd_server_uuid);
224         if (rc < 0)
225                 RETURN(rc);
226         ptlbd->bd_exp = class_conn2export(&conn);
227         RETURN(rc);
228 }
229
230
231 int ptlbd_do_disconnect(struct ptlbd_obd *ptlbd)
232 {
233         int     rc;
234         ENTRY;
235
236         rc = obd_disconnect(ptlbd->bd_exp, 0);
237         RETURN(rc);
238 }
239