]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_ggate/Driver.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / tools / rbd_ggate / Driver.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include <stdlib.h>
5
6 #include "common/debug.h"
7 #include "common/errno.h"
8 #include "Driver.h"
9 #include "Request.h"
10
11 #define dout_context g_ceph_context
12 #define dout_subsys ceph_subsys_rbd
13 #undef dout_prefix
14 #define dout_prefix *_dout << "rbd::ggate::Driver: " << this \
15 << " " << __func__ << ": "
16
17 namespace rbd {
18 namespace ggate {
19
20 int Driver::load() {
21
22 return ggate_drv_load();
23 }
24
25 int Driver::kill(const std::string &devname) {
26
27 int r = ggate_drv_kill(devname.c_str());
28
29 return r;
30 }
31
32 int Driver::list(std::map<std::string, DevInfo> *devices) {
33 size_t size = 1024;
34 ggate_drv_info *devs = nullptr;
35 int r;
36
37 while (size <= 1024 * 1024) {
38 devs = static_cast<ggate_drv_info *>(
39 realloc(static_cast<void *>(devs), size * sizeof(*devs)));
40 r = ggate_drv_list(devs, &size);
41 if (r != -ERANGE) {
42 break;
43 }
44 }
45 if (r < 0) {
46 goto free;
47 }
48
49 devices->clear();
50 for (size_t i = 0; i < size; i++) {
51 auto &dev = devs[i];
52 (*devices)[dev.id] = {dev.name, dev.info};
53 }
54
55 free:
56 free(devs);
57
58 return r;
59 }
60
61 Driver::Driver(const std::string &devname, size_t sectorsize, size_t mediasize,
62 bool readonly, const std::string &info)
63 : m_devname(devname), m_sectorsize(sectorsize), m_mediasize(mediasize),
64 m_readonly(readonly), m_info(info) {
65 }
66
67 int Driver::init() {
68 dout(20) << dendl;
69
70 char name[PATH_MAX];
71 size_t namelen;
72
73 if (m_devname.empty()) {
74 name[0] = '\0';
75 namelen = PATH_MAX;
76 } else {
77 namelen = m_devname.size();
78 if (namelen >= PATH_MAX) {
79 return -ENAMETOOLONG;
80 }
81 strncpy(name, m_devname.c_str(), namelen + 1);
82 }
83
84 int r = ggate_drv_create(name, namelen, m_sectorsize, m_mediasize, m_readonly,
85 m_info.c_str(), &m_drv);
86 if (r < 0) {
87 return r;
88 }
89
90 if (m_devname.empty()) {
91 m_devname = name;
92 }
93
94 return 0;
95 }
96
97 std::string Driver::get_devname() const {
98 dout(30) << m_devname << dendl;
99
100 return m_devname;
101 }
102
103 void Driver::shut_down() {
104 dout(20) << dendl;
105
106 ggate_drv_destroy(m_drv);
107 }
108
109 int Driver::resize(size_t newsize) {
110 dout(20) << "newsize=" << newsize << dendl;
111
112 int r = ggate_drv_resize(m_drv, newsize);
113 if (r < 0) {
114 return r;
115 }
116
117 m_mediasize = newsize;
118 return 0;
119 }
120
121 int Driver::recv(Request **req) {
122 dout(20) << dendl;
123
124 ggate_drv_req_t req_;
125
126 int r = ggate_drv_recv(m_drv, &req_);
127 if (r < 0) {
128 return r;
129 }
130
131 *req = new Request(req_);
132
133 dout(20) << "req=" << *req << dendl;
134
135 if (ggate_drv_req_cmd(req_) == GGATE_DRV_CMD_WRITE) {
136 bufferptr ptr(buffer::claim_malloc(
137 ggate_drv_req_length(req_),
138 static_cast<char *>(ggate_drv_req_release_buf(req_))));
139 (*req)->bl.push_back(ptr);
140 }
141
142 return 0;
143 }
144
145 int Driver::send(Request *req) {
146 dout(20) << "req=" << req << dendl;
147
148 if (ggate_drv_req_cmd(req->req) == GGATE_DRV_CMD_READ &&
149 ggate_drv_req_error(req->req) == 0) {
150 ceph_assert(req->bl.length() == ggate_drv_req_length(req->req));
151 // TODO: avoid copying?
152 req->bl.copy(0, ggate_drv_req_length(req->req),
153 static_cast<char *>(ggate_drv_req_buf(req->req)));
154 dout(20) << "copied resulting " << req->bl.length() << " bytes to "
155 << ggate_drv_req_buf(req->req) << dendl;
156 }
157
158 int r = ggate_drv_send(m_drv, req->req);
159
160 delete req;
161 return r;
162 }
163
164 } // namespace ggate
165 } // namespace rbd