2 * Ceph - scalable distributed file system
4 * Copyright (C) 2020 SUSE LINUX GmbH
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.
13 #ifndef WNBD_HANDLER_H
14 #define WNBD_HANDLER_H
18 #include "common/admin_socket.h"
19 #include "common/ceph_context.h"
20 #include "common/Thread.h"
22 #include "include/rbd/librbd.hpp"
23 #include "include/xlist.h"
25 #include "global/global_context.h"
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
33 // Not defined by mingw.
34 #ifndef SCSI_ADSENSE_UNRECOVERED_ERROR
35 #define SCSI_ADSENSE_UNRECOVERED_ERROR 0x11
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"
45 class WnbdAdminHook
: public AdminSocketHook
{
46 WnbdHandler
*m_handler
;
49 explicit WnbdAdminHook(WnbdHandler
*handler
) :
51 g_ceph_context
->get_admin_socket()->register_command(
52 "wnbd stats", this, "get WNBD stats");
54 ~WnbdAdminHook() override
{
55 g_ceph_context
->get_admin_socket()->unregister_commands(this);
58 int call(std::string_view command
, const cmdmap_t
& cmdmap
,
59 Formatter
*f
, std::ostream
& errss
, bufferlist
& out
) override
;
67 std::string instance_name
;
71 bool rbd_cache_enabled
;
72 uint32_t io_req_workers
;
73 uint32_t io_reply_workers
;
74 WnbdAdminHook
* admin_hook
;
75 boost::asio::thread_pool
* reply_tpool
;
78 WnbdHandler(librbd::Image
& _image
, std::string _instance_name
,
79 uint64_t _block_count
, uint32_t _block_size
,
80 bool _readonly
, bool _rbd_cache_enabled
,
81 uint32_t _io_req_workers
,
82 uint32_t _io_reply_workers
)
84 , instance_name(_instance_name
)
85 , block_count(_block_count
)
86 , block_size(_block_size
)
88 , rbd_cache_enabled(_rbd_cache_enabled
)
89 , io_req_workers(_io_req_workers
)
90 , io_reply_workers(_io_reply_workers
)
92 admin_hook
= new WnbdAdminHook(this);
93 // Instead of relying on librbd's own thread pool, we're going to use a
94 // separate one. This allows us to make assumptions on the threads that
95 // are going to send the IO replies and thus be able to cache Windows
96 // OVERLAPPED structures.
97 reply_tpool
= new boost::asio::thread_pool(_io_reply_workers
);
101 // Wait for the handler to stop, which normally happens when the driver
102 // passes the "Disconnect" request.
106 int dump_stats(Formatter
*f
);
110 static VOID
LogMessage(
111 WnbdLogLevel LogLevel
,
113 const char* FileName
,
115 const char* FunctionName
);
118 ceph::mutex shutdown_lock
= ceph::make_mutex("WnbdHandler::DisconnectLocker");
119 bool started
= false;
120 bool terminated
= false;
121 WNBD_DISK
* wnbd_disk
= nullptr;
125 xlist
<IOContext
*>::item item
;
126 WnbdHandler
*handler
= nullptr;
127 WNBD_STATUS wnbd_status
= {0};
128 WnbdRequestType req_type
= WnbdReqTypeUnknown
;
129 uint64_t req_handle
= 0;
130 uint32_t err_code
= 0;
139 void set_sense(uint8_t sense_key
, uint8_t asc
, uint64_t info
);
140 void set_sense(uint8_t sense_key
, uint8_t asc
);
143 friend std::ostream
&operator<<(std::ostream
&os
, const IOContext
&ctx
);
145 void send_io_response(IOContext
*ctx
);
147 static void aio_callback(librbd::completion_t cb
, void *arg
);
149 // WNBD IO entry points
152 UINT64 RequestHandle
,
156 BOOLEAN ForceUnitAccess
);
159 UINT64 RequestHandle
,
163 BOOLEAN ForceUnitAccess
);
166 UINT64 RequestHandle
,
171 UINT64 RequestHandle
,
172 PWNBD_UNMAP_DESCRIPTOR Descriptors
,
175 static constexpr WNBD_INTERFACE RbdWnbdInterface
=
184 std::ostream
&operator<<(std::ostream
&os
, const WnbdHandler::IOContext
&ctx
);
186 #endif // WNBD_HANDLER_H