]> git.proxmox.com Git - ceph.git/blame - ceph/src/msg/async/rdma/RDMAConnTCP.cc
bump version to 12.0.3-pve3
[ceph.git] / ceph / src / msg / async / rdma / RDMAConnTCP.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2016 XSKY <haomai@xsky.com>
7 *
8 * Author: Haomai Wang <haomaiwang@gmail.com>
9 *
10 * This is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License version 2.1, as published by the Free Software
13 * Foundation. See file COPYING.
14 *
15 */
16
17#include "RDMAStack.h"
18#include "Device.h"
19#include "RDMAConnTCP.h"
20
21#define dout_subsys ceph_subsys_ms
22#undef dout_prefix
23#define dout_prefix *_dout << " RDMAConnTCP "
24
25static const uint32_t TCP_MSG_LEN = sizeof("0000:00000000:00000000:00000000:00000000000000000000000000000000");
26
27// 1 means no valid buffer read, 0 means got enough buffer
28// else return < 0 means error
29int RDMAConnTCP::recv_msg(CephContext *cct, int sd, IBSYNMsg& im)
30{
31 char msg[TCP_MSG_LEN];
32 char gid[33];
33 ssize_t r = ::read(sd, &msg, sizeof(msg));
34 // Drop incoming qpt
35 if (cct->_conf->ms_inject_socket_failures && sd >= 0) {
36 if (rand() % cct->_conf->ms_inject_socket_failures == 0) {
37 ldout(cct, 0) << __func__ << " injecting socket failure" << dendl;
38 return -EINVAL;
39 }
40 }
41 if (r < 0) {
42 r = -errno;
43 lderr(cct) << __func__ << " got error " << r << ": "
44 << cpp_strerror(r) << dendl;
45 } else if (r == 0) { // valid disconnect message of length 0
46 ldout(cct, 10) << __func__ << " got disconnect message " << dendl;
47 } else if ((size_t)r != sizeof(msg)) { // invalid message
48 ldout(cct, 1) << __func__ << " got bad length (" << r << ") " << dendl;
49 r = -EINVAL;
50 } else { // valid message
51 sscanf(msg, "%hu:%x:%x:%x:%s", &(im.lid), &(im.qpn), &(im.psn), &(im.peer_qpn),gid);
52 wire_gid_to_gid(gid, &(im.gid));
53 ldout(cct, 5) << __func__ << " recevd: " << im.lid << ", " << im.qpn << ", " << im.psn << ", " << im.peer_qpn << ", " << gid << dendl;
54 }
55 return r;
56}
57
58int RDMAConnTCP::send_msg(CephContext *cct, int sd, IBSYNMsg& im)
59{
60 int retry = 0;
61 ssize_t r;
62
63 char msg[TCP_MSG_LEN];
64 char gid[33];
65retry:
66 gid_to_wire_gid(&(im.gid), gid);
67 sprintf(msg, "%04x:%08x:%08x:%08x:%s", im.lid, im.qpn, im.psn, im.peer_qpn, gid);
68 ldout(cct, 10) << __func__ << " sending: " << im.lid << ", " << im.qpn << ", " << im.psn
69 << ", " << im.peer_qpn << ", " << gid << dendl;
70 r = ::write(sd, msg, sizeof(msg));
71 // Drop incoming qpt
72 if (cct->_conf->ms_inject_socket_failures && sd >= 0) {
73 if (rand() % cct->_conf->ms_inject_socket_failures == 0) {
74 ldout(cct, 0) << __func__ << " injecting socket failure" << dendl;
75 return -EINVAL;
76 }
77 }
78
79 if ((size_t)r != sizeof(msg)) {
80 // FIXME need to handle EAGAIN instead of retry
81 if (r < 0 && (errno == EINTR || errno == EAGAIN) && retry < 3) {
82 retry++;
83 goto retry;
84 }
85 if (r < 0)
86 lderr(cct) << __func__ << " send returned error " << errno << ": "
87 << cpp_strerror(errno) << dendl;
88 else
89 lderr(cct) << __func__ << " send got bad length (" << r << ") " << cpp_strerror(errno) << dendl;
90 return -errno;
91 }
92 return 0;
93}
94
95void RDMAConnTCP::wire_gid_to_gid(const char *wgid, union ibv_gid *gid)
96{
97 char tmp[9];
98 uint32_t v32;
99 int i;
100
101 for (tmp[8] = 0, i = 0; i < 4; ++i) {
102 memcpy(tmp, wgid + i * 8, 8);
103 sscanf(tmp, "%x", &v32);
104 *(uint32_t *)(&gid->raw[i * 4]) = ntohl(v32);
105 }
106}
107
108void RDMAConnTCP::gid_to_wire_gid(const union ibv_gid *gid, char wgid[])
109{
110 for (int i = 0; i < 4; ++i)
111 sprintf(&wgid[i * 8], "%08x", htonl(*(uint32_t *)(gid->raw + i * 4)));
112}
113
114ostream &RDMAConnTCP::print(ostream &out) const
115{
116 return out << "TCP {tcp_fd: " << tcp_fd << "}";
117}