1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "common/errno.h"
5 #include "cls/rbd/cls_rbd_client.h"
6 #include "librbd/api/Mirror.h"
7 #include "librbd/api/Namespace.h"
8 #include "librbd/ImageCtx.h"
10 #define dout_subsys ceph_subsys_rbd
12 #define dout_prefix *_dout << "librbd::api::Namespace: " << __func__ << ": "
19 const std::list
<std::string
> POOL_OBJECTS
{
29 } // anonymous namespace
32 int Namespace
<I
>::create(librados::IoCtx
& io_ctx
, const std::string
& name
)
34 CephContext
*cct
= (CephContext
*)io_ctx
.cct();
35 ldout(cct
, 5) << "name=" << name
<< dendl
;
41 librados::Rados
rados(io_ctx
);
42 int8_t require_osd_release
;
43 int r
= rados
.get_min_compatible_osd(&require_osd_release
);
45 lderr(cct
) << "failed to retrieve min OSD release: " << cpp_strerror(r
)
50 if (require_osd_release
< CEPH_RELEASE_NAUTILUS
) {
51 ldout(cct
, 1) << "namespace support requires nautilus or later OSD"
57 librados::IoCtx default_ns_ctx
;
58 default_ns_ctx
.dup(io_ctx
);
59 default_ns_ctx
.set_namespace("");
61 r
= cls_client::namespace_add(&default_ns_ctx
, name
);
63 lderr(cct
) << "failed to add namespace: " << cpp_strerror(r
) << dendl
;
67 librados::IoCtx ns_ctx
;
69 ns_ctx
.set_namespace(name
);
71 r
= cls_client::dir_state_set(&ns_ctx
, RBD_DIRECTORY
,
72 cls::rbd::DIRECTORY_STATE_READY
);
74 lderr(cct
) << "failed to initialize image directory: " << cpp_strerror(r
)
82 int ret_val
= cls_client::namespace_remove(&default_ns_ctx
, name
);
84 lderr(cct
) << "failed to remove namespace: " << cpp_strerror(ret_val
) << dendl
;
91 int Namespace
<I
>::remove(librados::IoCtx
& io_ctx
, const std::string
& name
)
93 CephContext
*cct
= (CephContext
*)io_ctx
.cct();
94 ldout(cct
, 5) << "name=" << name
<< dendl
;
100 librados::IoCtx default_ns_ctx
;
101 default_ns_ctx
.dup(io_ctx
);
102 default_ns_ctx
.set_namespace("");
104 librados::IoCtx ns_ctx
;
106 ns_ctx
.set_namespace(name
);
108 std::map
<std::string
, cls::rbd::TrashImageSpec
> trash_entries
;
110 librados::ObjectWriteOperation dir_op
;
111 librbd::cls_client::dir_state_set(
112 &dir_op
, cls::rbd::DIRECTORY_STATE_ADD_DISABLED
);
115 int r
= ns_ctx
.operate(RBD_DIRECTORY
, &dir_op
);
117 ldout(cct
, 5) << "image directory not empty" << dendl
;
119 } else if (r
< 0 && r
!= -ENOENT
) {
120 lderr(cct
) << "failed to disable the namespace: " << cpp_strerror(r
)
125 r
= cls_client::trash_list(&ns_ctx
, "", 1, &trash_entries
);
126 if (r
< 0 && r
!= -ENOENT
) {
127 lderr(cct
) << "failed to list trash directory: " << cpp_strerror(r
)
130 } else if (!trash_entries
.empty()) {
131 ldout(cct
, 5) << "image trash not empty" << dendl
;
135 r
= Mirror
<I
>::mode_set(ns_ctx
, RBD_MIRROR_MODE_DISABLED
);
137 lderr(cct
) << "failed to disable mirroring: " << cpp_strerror(r
)
142 for (auto& oid
: POOL_OBJECTS
) {
143 r
= ns_ctx
.remove(oid
);
144 if (r
< 0 && r
!= -ENOENT
) {
145 lderr(cct
) << "failed to remove object '" << oid
<< "': "
146 << cpp_strerror(r
) << dendl
;
151 r
= cls_client::namespace_remove(&default_ns_ctx
, name
);
153 lderr(cct
) << "failed to remove namespace: " << cpp_strerror(r
) << dendl
;
161 r
= librbd::cls_client::dir_state_set(
162 &ns_ctx
, RBD_DIRECTORY
, cls::rbd::DIRECTORY_STATE_READY
);
164 lderr(cct
) << "failed to restore directory state: " << cpp_strerror(r
)
171 template <typename I
>
172 int Namespace
<I
>::list(IoCtx
& io_ctx
, vector
<string
> *names
)
174 CephContext
*cct
= (CephContext
*)io_ctx
.cct();
175 ldout(cct
, 5) << dendl
;
177 librados::IoCtx default_ns_ctx
;
178 default_ns_ctx
.dup(io_ctx
);
179 default_ns_ctx
.set_namespace("");
183 std::string last_read
= "";
185 std::list
<std::string
> name_list
;
186 r
= cls_client::namespace_list(&default_ns_ctx
, last_read
, max_read
,
191 lderr(cct
) << "error listing namespaces: " << cpp_strerror(r
) << dendl
;
195 names
->insert(names
->end(), name_list
.begin(), name_list
.end());
196 if (!name_list
.empty()) {
197 last_read
= name_list
.back();
199 r
= name_list
.size();
200 } while (r
== max_read
);
205 template <typename I
>
206 int Namespace
<I
>::exists(librados::IoCtx
& io_ctx
, const std::string
& name
, bool *exists
)
208 CephContext
*cct
= (CephContext
*)io_ctx
.cct();
209 ldout(cct
, 5) << "name=" << name
<< dendl
;
216 librados::IoCtx ns_ctx
;
218 ns_ctx
.set_namespace(name
);
220 int r
= librbd::cls_client::dir_state_assert(&ns_ctx
, RBD_DIRECTORY
,
221 cls::rbd::DIRECTORY_STATE_READY
);
224 } else if (r
!= -ENOENT
) {
225 lderr(cct
) << "error asserting namespace: " << cpp_strerror(r
) << dendl
;
233 } // namespace librbd
235 template class librbd::api::Namespace
<librbd::ImageCtx
>;