Whamcloud - gitweb
b=596505
[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 DEBUG_SUBSYSTEM S_RPC
18
19 #include <linux/kmod.h>
20 #include <linux/lustre_lite.h>
21 #include <linux/lustre_ha.h>
22
23 static int connmgr_unpack_body(struct ptlrpc_request *req)
24 {
25         struct connmgr_body *b = lustre_msg_buf(req->rq_repmsg, 0);
26         if (b == NULL) {
27                 LBUG();
28                 RETURN(-EINVAL);
29         }
30
31         b->generation = NTOH__u32(b->generation);
32
33         return 0;
34 }
35
36 int connmgr_connect(struct recovd_obd *recovd, struct ptlrpc_connection *conn)
37 {
38         struct ptlrpc_request *req;
39         struct ptlrpc_client *cl;
40         struct connmgr_body *body;
41         int rc, size = sizeof(*body);
42         ENTRY;
43
44         if (!recovd) {
45                 CERROR("no manager\n");
46                 LBUG();
47         }
48         cl = recovd->recovd_client;
49
50         req = ptlrpc_prep_req(cl, conn, CONNMGR_CONNECT, 1, &size, NULL);
51         if (!req)
52                 GOTO(out, rc = -ENOMEM);
53
54         body = lustre_msg_buf(req->rq_reqmsg, 0);
55         body->generation = HTON__u32(conn->c_generation);
56         body->conn = (__u64)(unsigned long)conn;
57         body->conn_token = conn->c_token;
58         strncpy(body->conn_uuid, conn->c_local_uuid, sizeof(body->conn_uuid));
59
60         req->rq_replen = lustre_msg_size(1, &size);
61         req->rq_level = LUSTRE_CONN_NEW;
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 ptlrpc_request *req)
117 {
118         int rc;
119         ENTRY;
120
121         rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen);
122         if (rc) {
123                 CERROR("Invalid request\n");
124                 GOTO(out, rc);
125         }
126
127         if (req->rq_reqmsg->type != NTOH__u32(PTL_RPC_MSG_REQUEST)) {
128                 CERROR("wrong packet type sent %d\n",
129                        req->rq_reqmsg->type);
130                 GOTO(out, rc = -EINVAL);
131         }
132
133         switch (req->rq_reqmsg->opc) {
134         case CONNMGR_CONNECT:
135                 CDEBUG(D_INODE, "connmgr connect\n");
136                 rc = connmgr_handle_connect(req);
137                 break;
138
139         default:
140                 rc = ptlrpc_error(req->rq_svc, req);
141                 RETURN(rc);
142         }
143
144         EXIT;
145 out:
146         if (rc) {
147                 ptlrpc_error(req->rq_svc, req);
148         } else {
149                 CDEBUG(D_NET, "sending reply\n");
150                 ptlrpc_reply(req->rq_svc, req);
151         }
152
153         return 0;
154 }