@@ -47,6 +47,61 @@ int extent_cb(void* data, const char* metacontext, uint64_t offset,
4747
4848} // anonymous namespace
4949
50+ template <typename >
51+ class NBDClient {
52+ public:
53+ static NBDClient* create () {
54+ return new NBDClient ();
55+ }
56+
57+ const char * get_error () {
58+ return nbd_get_error ();
59+ }
60+
61+ int get_errno () {
62+ return nbd_get_errno ();
63+ }
64+
65+ int init () {
66+ m_handle.reset (nbd_create ());
67+ return m_handle != nullptr ? 0 : -1 ;
68+ }
69+
70+ int add_meta_context (const char * name) {
71+ return nbd_add_meta_context (m_handle.get (), name);
72+ }
73+
74+ int connect_uri (const char * uri) {
75+ return nbd_connect_uri (m_handle.get (), uri);
76+ }
77+
78+ int64_t get_size () {
79+ return nbd_get_size (m_handle.get ());
80+ }
81+
82+ int pread (void * buf, size_t count, uint64_t offset, uint32_t flags) {
83+ return nbd_pread (m_handle.get (), buf, count, offset, flags);
84+ }
85+
86+ int block_status (uint64_t count, uint64_t offset,
87+ nbd_extent_callback extent_callback, uint32_t flags) {
88+ return nbd_block_status (m_handle.get (), count, offset, extent_callback,
89+ flags);
90+ }
91+
92+ int shutdown (uint32_t flags) {
93+ return nbd_shutdown (m_handle.get (), flags);
94+ }
95+
96+ private:
97+ struct nbd_handle_deleter {
98+ void operator ()(nbd_handle* h) {
99+ nbd_close (h);
100+ }
101+ };
102+ std::unique_ptr<nbd_handle, nbd_handle_deleter> m_handle;
103+ };
104+
50105#define dout_subsys ceph_subsys_rbd
51106#undef dout_prefix
52107#define dout_prefix *_dout << " librbd::migration::NBDStream::ReadRequest: " \
@@ -84,14 +139,14 @@ struct NBDStream<I>::ReadRequest {
84139 ldout (cct, 20 ) << " byte_offset=" << byte_offset << " byte_length="
85140 << byte_length << dendl;
86141
142+ auto & nbd_client = nbd_stream->m_nbd_client ;
87143 auto ptr = buffer::ptr_node::create (buffer::create_small_page_aligned (
88144 byte_length));
89- int rc = nbd_pread (nbd_stream->m_nbd , ptr->c_str (), byte_length,
90- byte_offset, 0 );
145+ int rc = nbd_client->pread (ptr->c_str (), byte_length, byte_offset, 0 );
91146 if (rc == -1 ) {
92- rc = nbd_get_errno ();
147+ rc = nbd_client-> get_errno ();
93148 lderr (cct) << " pread " << byte_offset << " ~" << byte_length << " : "
94- << nbd_get_error () << " (errno = " << rc << " )"
149+ << nbd_client-> get_error () << " (errno = " << rc << " )"
95150 << dendl;
96151 finish (from_nbd_errno (rc));
97152 return ;
@@ -160,12 +215,13 @@ struct NBDStream<I>::ListSparseExtentsRequest {
160215 tmp_sparse_extents.insert (byte_offset, byte_length,
161216 {io::SPARSE_EXTENT_STATE_DATA, byte_length});
162217
163- int rc = nbd_block_status (nbd_stream->m_nbd , byte_length, byte_offset,
164- {extent_cb, &tmp_sparse_extents}, 0 );
218+ auto & nbd_client = nbd_stream->m_nbd_client ;
219+ int rc = nbd_client->block_status (byte_length, byte_offset,
220+ {extent_cb, &tmp_sparse_extents}, 0 );
165221 if (rc == -1 ) {
166- rc = nbd_get_errno ();
222+ rc = nbd_client-> get_errno ();
167223 lderr (cct) << " block_status " << byte_offset << " ~" << byte_length << " : "
168- << nbd_get_error () << " (errno = " << rc << " )"
224+ << nbd_client-> get_error () << " (errno = " << rc << " )"
169225 << dendl;
170226 // don't propagate errors -- we are set up to list any missing
171227 // parts of the range as DATA if nbd_block_status() returns less
@@ -201,9 +257,6 @@ NBDStream<I>::NBDStream(I* image_ctx, const json_spirit::mObject& json_object)
201257
202258template <typename I>
203259NBDStream<I>::~NBDStream () {
204- if (m_nbd != nullptr ) {
205- nbd_close (m_nbd);
206- }
207260}
208261
209262template <typename I>
@@ -228,28 +281,29 @@ void NBDStream<I>::open(Context* on_finish) {
228281
229282 ldout (m_cct, 10 ) << " uri=" << uri << dendl;
230283
231- m_nbd = nbd_create ();
232- if (m_nbd == nullptr ) {
233- rc = nbd_get_errno ();
234- lderr (m_cct) << " create: " << nbd_get_error ()
284+ m_nbd_client.reset (NBDClient<I>::create ());
285+ rc = m_nbd_client->init ();
286+ if (rc == -1 ) {
287+ rc = m_nbd_client->get_errno ();
288+ lderr (m_cct) << " init: " << m_nbd_client->get_error ()
235289 << " (errno = " << rc << " )" << dendl;
236290 on_finish->complete (from_nbd_errno (rc));
237291 return ;
238292 }
239293
240- rc = nbd_add_meta_context (m_nbd, LIBNBD_CONTEXT_BASE_ALLOCATION);
294+ rc = m_nbd_client-> add_meta_context ( LIBNBD_CONTEXT_BASE_ALLOCATION);
241295 if (rc == -1 ) {
242- rc = nbd_get_errno ();
243- lderr (m_cct) << " add_meta_context: " << nbd_get_error ()
296+ rc = m_nbd_client-> get_errno ();
297+ lderr (m_cct) << " add_meta_context: " << m_nbd_client-> get_error ()
244298 << " (errno = " << rc << " )" << dendl;
245299 on_finish->complete (from_nbd_errno (rc));
246300 return ;
247301 }
248302
249- rc = nbd_connect_uri (m_nbd, uri.c_str ());
303+ rc = m_nbd_client-> connect_uri ( uri.c_str ());
250304 if (rc == -1 ) {
251- rc = nbd_get_errno ();
252- lderr (m_cct) << " connect_uri: " << nbd_get_error ()
305+ rc = m_nbd_client-> get_errno ();
306+ lderr (m_cct) << " connect_uri: " << m_nbd_client-> get_error ()
253307 << " (errno = " << rc << " )" << dendl;
254308 on_finish->complete (from_nbd_errno (rc));
255309 return ;
@@ -262,15 +316,13 @@ template <typename I>
262316void NBDStream<I>::close(Context* on_finish) {
263317 ldout (m_cct, 20 ) << dendl;
264318
265- if (m_nbd != nullptr ) {
319+ if (m_nbd_client != nullptr ) {
266320 // send a graceful shutdown to the server
267321 // ignore errors -- we are read-only, also from the client's
268322 // POV there is no disadvantage to abruptly closing the socket
269323 // in nbd_close()
270- nbd_shutdown (m_nbd, 0 );
271-
272- nbd_close (m_nbd);
273- m_nbd = nullptr ;
324+ m_nbd_client->shutdown (0 );
325+ m_nbd_client.reset ();
274326 }
275327
276328 on_finish->complete (0 );
@@ -280,10 +332,10 @@ template <typename I>
280332void NBDStream<I>::get_size(uint64_t * size, Context* on_finish) {
281333 ldout (m_cct, 20 ) << dendl;
282334
283- int64_t rc = nbd_get_size (m_nbd );
335+ int64_t rc = m_nbd_client-> get_size ( );
284336 if (rc == -1 ) {
285- rc = nbd_get_errno ();
286- lderr (m_cct) << " get_size: " << nbd_get_error ()
337+ rc = m_nbd_client-> get_errno ();
338+ lderr (m_cct) << " get_size: " << m_nbd_client-> get_error ()
287339 << " (errno = " << rc << " )" << dendl;
288340 on_finish->complete (from_nbd_errno (rc));
289341 return ;
0 commit comments