Whamcloud - gitweb
- and here are the new files with the previous commit
[fs/lustre-release.git] / lustre / ptlrpc / connmgr.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  obd/rpc/recovd.c
5  *
6  *  Lustre High Availability Daemon
7  *
8  *  Copyright (C) 2001, 2002 Cluster File Systems, Inc.
9  *
10  *  This code is issued under the GNU General Public License.
11  *  See the file COPYING in this distribution
12  *
13  *  by Peter Braam <braam@clusterfs.com>
14  *
15  */
16
17 #define EXPORT_SYMTAB
18 #define DEBUG_SUBSYSTEM S_RPC
19
20 #include <linux/kmod.h>
21 #include <linux/lustre_lite.h>
22 #include <linux/lustre_ha.h>
23
24 static int connmgr_unpack_body(struct ptlrpc_request *req)
25 {
26         struct connmgr_body *b = lustre_msg_buf(req->rq_repmsg, 0);
27         if (b == NULL) {
28                 LBUG();
29                 RETURN(-EINVAL);
30         }
31
32         b->generation = NTOH__u32(b->generation);
33
34         return 0;
35 }
36
37 int connmgr_connect(struct recovd_obd *recovd, struct ptlrpc_connection *conn)
38 {
39         struct ptlrpc_request *req;
40         struct ptlrpc_client *cl;
41         struct connmgr_body *body;
42         int rc, size = sizeof(*body);
43         ENTRY;
44
45         if (!recovd) {
46                 CERROR("no manager\n");
47                 LBUG();
48         }
49         cl = recovd->recovd_client;
50
51         req = ptlrpc_prep_req(cl, conn, CONNMGR_CONNECT, 1, &size, NULL);
52         if (!req)
53                 GOTO(out, rc = -ENOMEM);
54
55         body = lustre_msg_buf(req->rq_reqmsg, 0);
56         body->generation = HTON__u32(conn->c_generation);
57         body->conn = (__u64)(unsigned long)conn;
58         body->conn_token = conn->c_token;
59         strncpy(body->conn_uuid, conn->c_local_uuid, sizeof(body->conn_uuid));
60
61         req->rq_replen = lustre_msg_size(1, &size);
62
63         rc = ptlrpc_queue_wait(req);
64         rc = ptlrpc_check_status(req, rc);
65         if (!rc) {
66                 rc = connmgr_unpack_body(req);
67                 if (rc)
68                         GOTO(out_free, rc);
69                 body = lustre_msg_buf(req->rq_repmsg, 0);
70                 CDEBUG(D_NET, "remote generation: %o\n", body->generation);
71                 conn->c_level = LUSTRE_CONN_CON;
72                 conn->c_remote_conn = body->conn;
73                 conn->c_remote_token = body->conn_token;
74                 strncpy(conn->c_remote_uuid, body->conn_uuid,
75                         sizeof(conn->c_remote_uuid));
76         }
77
78         EXIT;
79  out_free:
80         ptlrpc_free_req(req);
81  out:
82         return rc;
83 }
84
85 static int connmgr_handle_connect(struct ptlrpc_request *req)
86 {
87         struct connmgr_body *body;
88         int rc, size = sizeof(*body);
89         ENTRY;
90
91         rc = lustre_pack_msg(1, &size, NULL, &req->rq_replen, &req->rq_repmsg);
92         if (rc) {
93                 CERROR("connmgr: out of memory\n");
94                 req->rq_status = -ENOMEM;
95                 RETURN(0);
96         }
97
98         body = lustre_msg_buf(req->rq_reqmsg, 0);
99         connmgr_unpack_body(req);
100
101         req->rq_connection->c_remote_conn = body->conn;
102         req->rq_connection->c_remote_token = body->conn_token;
103         strncpy(req->rq_connection->c_remote_uuid, body->conn_uuid,
104                 sizeof(req->rq_connection->c_remote_uuid));
105
106         CERROR("incoming generation %d\n", body->generation);
107         body = lustre_msg_buf(req->rq_repmsg, 0);
108         body->generation = 4711;
109         body->conn = (__u64)(unsigned long)req->rq_connection;
110         body->conn_token = req->rq_connection->c_token;
111
112         req->rq_connection->c_level = LUSTRE_CONN_CON;
113         RETURN(0);
114 }
115
116 int connmgr_handle(struct obd_device *dev, struct ptlrpc_service *svc,
117                    struct ptlrpc_request *req)
118 {
119         int rc;
120         ENTRY;
121
122         rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen);
123         if (rc) {
124                 CERROR("Invalid request\n");
125                 GOTO(out, rc);
126         }
127
128         if (req->rq_reqmsg->type != NTOH__u32(PTL_RPC_MSG_REQUEST)) {
129                 CERROR("wrong packet type sent %d\n",
130                        req->rq_reqmsg->type);
131                 GOTO(out, rc = -EINVAL);
132         }
133
134         switch (req->rq_reqmsg->opc) {
135         case CONNMGR_CONNECT:
136                 CDEBUG(D_INODE, "connmgr connect\n");
137                 rc = connmgr_handle_connect(req);
138                 break;
139
140         default:
141                 rc = ptlrpc_error(svc, req);
142                 RETURN(rc);
143         }
144
145         EXIT;
146 out:
147         if (rc) {
148                 ptlrpc_error(svc, req);
149         } else {
150                 CDEBUG(D_NET, "sending reply\n");
151                 ptlrpc_reply(svc, req);
152         }
153
154         return 0;
155 }