]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd_wnbd/wnbd_handler.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / tools / rbd_wnbd / wnbd_handler.h
CommitLineData
f67539c2
TL
1/*
2 * Ceph - scalable distributed file system
3 *
4 * Copyright (C) 2020 SUSE LINUX GmbH
5 *
6 * This is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License version 2.1, as published by the Free Software
9 * Foundation. See file COPYING.
10 *
11 */
12
13#ifndef WNBD_HANDLER_H
14#define WNBD_HANDLER_H
15
16#include <wnbd.h>
17
18#include "common/admin_socket.h"
19#include "common/ceph_context.h"
20#include "common/Thread.h"
21
22#include "include/rbd/librbd.hpp"
23#include "include/xlist.h"
24
25#include "global/global_context.h"
26
27// TODO: make this configurable.
28#define RBD_WNBD_MAX_TRANSFER 2 * 1024 * 1024
29#define SOFT_REMOVE_RETRY_INTERVAL 2
30#define DEFAULT_SOFT_REMOVE_TIMEOUT 15
31#define DEFAULT_IO_WORKER_COUNT 4
32
33// Not defined by mingw.
34#ifndef SCSI_ADSENSE_UNRECOVERED_ERROR
35#define SCSI_ADSENSE_UNRECOVERED_ERROR 0x11
36#endif
37
38// The following will be assigned to the "Owner" field of the WNBD
39// parameters, which can be used to determine the application managing
40// a disk. We'll ignore other disks.
41#define RBD_WNBD_OWNER_NAME "ceph-rbd-wnbd"
42
43class WnbdHandler;
44
45class WnbdAdminHook : public AdminSocketHook {
46 WnbdHandler *m_handler;
47
48public:
49 explicit WnbdAdminHook(WnbdHandler *handler) :
50 m_handler(handler) {
51 g_ceph_context->get_admin_socket()->register_command(
52 "wnbd stats", this, "get WNBD stats");
53 }
54 ~WnbdAdminHook() override {
55 g_ceph_context->get_admin_socket()->unregister_commands(this);
56 }
57
58 int call(std::string_view command, const cmdmap_t& cmdmap,
39ae355f
TL
59 const bufferlist&,
60 Formatter *f, std::ostream& errss, bufferlist& out) override;
f67539c2
TL
61};
62
63
64class WnbdHandler
65{
66private:
67 librbd::Image &image;
68 std::string instance_name;
69 uint64_t block_count;
70 uint32_t block_size;
71 bool readonly;
72 bool rbd_cache_enabled;
73 uint32_t io_req_workers;
74 uint32_t io_reply_workers;
75 WnbdAdminHook* admin_hook;
76 boost::asio::thread_pool* reply_tpool;
77
78public:
79 WnbdHandler(librbd::Image& _image, std::string _instance_name,
80 uint64_t _block_count, uint32_t _block_size,
81 bool _readonly, bool _rbd_cache_enabled,
82 uint32_t _io_req_workers,
83 uint32_t _io_reply_workers)
84 : image(_image)
85 , instance_name(_instance_name)
86 , block_count(_block_count)
87 , block_size(_block_size)
88 , readonly(_readonly)
89 , rbd_cache_enabled(_rbd_cache_enabled)
90 , io_req_workers(_io_req_workers)
91 , io_reply_workers(_io_reply_workers)
92 {
93 admin_hook = new WnbdAdminHook(this);
94 // Instead of relying on librbd's own thread pool, we're going to use a
95 // separate one. This allows us to make assumptions on the threads that
96 // are going to send the IO replies and thus be able to cache Windows
97 // OVERLAPPED structures.
98 reply_tpool = new boost::asio::thread_pool(_io_reply_workers);
99 }
100
1e59de90 101 int resize(uint64_t new_size);
f67539c2
TL
102 int start();
103 // Wait for the handler to stop, which normally happens when the driver
104 // passes the "Disconnect" request.
105 int wait();
106 void shutdown();
107
108 int dump_stats(Formatter *f);
109
110 ~WnbdHandler();
111
112 static VOID LogMessage(
113 WnbdLogLevel LogLevel,
114 const char* Message,
115 const char* FileName,
116 UINT32 Line,
117 const char* FunctionName);
118
119private:
120 ceph::mutex shutdown_lock = ceph::make_mutex("WnbdHandler::DisconnectLocker");
121 bool started = false;
122 bool terminated = false;
123 WNBD_DISK* wnbd_disk = nullptr;
124
125 struct IOContext
126 {
127 xlist<IOContext*>::item item;
128 WnbdHandler *handler = nullptr;
129 WNBD_STATUS wnbd_status = {0};
130 WnbdRequestType req_type = WnbdReqTypeUnknown;
131 uint64_t req_handle = 0;
132 uint32_t err_code = 0;
133 size_t req_size;
134 uint64_t req_from;
135 bufferlist data;
136
137 IOContext()
138 : item(this)
139 {}
140
141 void set_sense(uint8_t sense_key, uint8_t asc, uint64_t info);
142 void set_sense(uint8_t sense_key, uint8_t asc);
143 };
144
145 friend std::ostream &operator<<(std::ostream &os, const IOContext &ctx);
146
147 void send_io_response(IOContext *ctx);
148
149 static void aio_callback(librbd::completion_t cb, void *arg);
150
151 // WNBD IO entry points
152 static void Read(
153 PWNBD_DISK Disk,
154 UINT64 RequestHandle,
155 PVOID Buffer,
156 UINT64 BlockAddress,
157 UINT32 BlockCount,
158 BOOLEAN ForceUnitAccess);
159 static void Write(
160 PWNBD_DISK Disk,
161 UINT64 RequestHandle,
162 PVOID Buffer,
163 UINT64 BlockAddress,
164 UINT32 BlockCount,
165 BOOLEAN ForceUnitAccess);
166 static void Flush(
167 PWNBD_DISK Disk,
168 UINT64 RequestHandle,
169 UINT64 BlockAddress,
170 UINT32 BlockCount);
171 static void Unmap(
172 PWNBD_DISK Disk,
173 UINT64 RequestHandle,
174 PWNBD_UNMAP_DESCRIPTOR Descriptors,
175 UINT32 Count);
176
177 static constexpr WNBD_INTERFACE RbdWnbdInterface =
178 {
179 Read,
180 Write,
181 Flush,
182 Unmap,
183 };
184};
185
186std::ostream &operator<<(std::ostream &os, const WnbdHandler::IOContext &ctx);
187
188#endif // WNBD_HANDLER_H