1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/image/GetMetadataRequest.h"
5 #include "cls/rbd/cls_rbd_client.h"
6 #include "common/dout.h"
7 #include "common/errno.h"
8 #include "include/ceph_assert.h"
9 #include "librbd/ImageCtx.h"
10 #include "librbd/Utils.h"
11 #include <boost/algorithm/string/predicate.hpp>
13 #define dout_subsys ceph_subsys_rbd
15 #define dout_prefix *_dout << "librbd::image::GetMetadataRequest: " \
16 << this << " " << __func__ << ": "
24 static const std::string INTERNAL_KEY_PREFIX
{".rbd"};
26 } // anonymous namespace
28 using util::create_rados_callback
;
31 GetMetadataRequest
<I
>::GetMetadataRequest(
32 IoCtx
&io_ctx
, const std::string
&oid
, bool filter_internal
,
33 const std::string
& filter_key_prefix
, const std::string
& last_key
,
34 uint32_t max_results
, KeyValues
* key_values
, Context
*on_finish
)
35 : m_io_ctx(io_ctx
), m_oid(oid
), m_filter_internal(filter_internal
),
36 m_filter_key_prefix(filter_key_prefix
), m_last_key(last_key
),
37 m_max_results(max_results
), m_key_values(key_values
),
38 m_on_finish(on_finish
),
39 m_cct(reinterpret_cast<CephContext
*>(m_io_ctx
.cct())) {
43 void GetMetadataRequest
<I
>::send() {
48 void GetMetadataRequest
<I
>::metadata_list() {
49 ldout(m_cct
, 15) << "start_key=" << m_last_key
<< dendl
;
51 m_expected_results
= MAX_KEYS
;
52 if (m_max_results
> 0) {
53 m_expected_results
= std::min
<uint32_t>(
54 m_expected_results
, m_max_results
- m_key_values
->size());
57 librados::ObjectReadOperation op
;
58 cls_client::metadata_list_start(&op
, m_last_key
, m_expected_results
);
60 auto aio_comp
= create_rados_callback
<
61 GetMetadataRequest
<I
>, &GetMetadataRequest
<I
>::handle_metadata_list
>(this);
63 m_io_ctx
.aio_operate(m_oid
, aio_comp
, &op
, &m_out_bl
);
68 void GetMetadataRequest
<I
>::handle_metadata_list(int r
) {
69 ldout(m_cct
, 15) << "r=" << r
<< dendl
;
73 auto it
= m_out_bl
.cbegin();
74 r
= cls_client::metadata_list_finish(&it
, &metadata
);
77 if (r
== -ENOENT
|| r
== -EOPNOTSUPP
) {
81 lderr(m_cct
) << "failed to retrieve image metadata: " << cpp_strerror(r
)
87 for (auto it
= metadata
.begin(); it
!= metadata
.end(); ++it
) {
88 if (m_filter_internal
&&
89 boost::starts_with(it
->first
, INTERNAL_KEY_PREFIX
)) {
91 } else if (!m_filter_key_prefix
.empty() &&
92 !boost::starts_with(it
->first
, m_filter_key_prefix
)) {
95 m_key_values
->insert({it
->first
, std::move(it
->second
)});
97 if (!metadata
.empty()) {
98 m_last_key
= metadata
.rbegin()->first
;
101 if (metadata
.size() == m_expected_results
&&
102 (m_max_results
== 0 || m_key_values
->size() < m_max_results
)) {
110 template <typename I
>
111 void GetMetadataRequest
<I
>::finish(int r
) {
112 ldout(m_cct
, 15) << "r=" << r
<< dendl
;
114 m_on_finish
->complete(r
);
119 } // namespace librbd
121 template class librbd::image::GetMetadataRequest
<librbd::ImageCtx
>;