1 // vim: ts=8 sw=2 smarttab ft=cpp
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2022 Red Hat, Inc.
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "common/dout.h"
16 #include "common/errno.h"
18 #include "driver/rados/config/store.h"
22 namespace rgw::rados
{
25 constexpr std::string_view zonegroup_names_oid_prefix
= "zonegroups_names.";
26 constexpr std::string_view zonegroup_info_oid_prefix
= "zonegroup_info.";
27 constexpr std::string_view default_zonegroup_info_oid
= "default.zonegroup";
29 static std::string
zonegroup_info_oid(std::string_view zonegroup_id
)
31 return string_cat_reserve(zonegroup_info_oid_prefix
, zonegroup_id
);
33 static std::string
zonegroup_name_oid(std::string_view zonegroup_id
)
35 return string_cat_reserve(zonegroup_names_oid_prefix
, zonegroup_id
);
37 static std::string
default_zonegroup_oid(const ceph::common::ConfigProxy
& conf
,
38 std::string_view realm_id
)
40 const auto prefix
= name_or_default(conf
->rgw_default_zonegroup_info_oid
,
41 default_zonegroup_info_oid
);
42 return fmt::format("{}.{}", prefix
, realm_id
);
46 int RadosConfigStore::write_default_zonegroup_id(const DoutPrefixProvider
* dpp
,
49 std::string_view realm_id
,
50 std::string_view zonegroup_id
)
52 const auto& pool
= impl
->zonegroup_pool
;
53 const auto oid
= default_zonegroup_oid(dpp
->get_cct()->_conf
, realm_id
);
54 const auto create
= exclusive
? Create::MustNotExist
: Create::MayExist
;
56 RGWDefaultSystemMetaObjInfo default_info
;
57 default_info
.default_id
= zonegroup_id
;
59 return impl
->write(dpp
, y
, pool
, oid
, create
, default_info
, nullptr);
62 int RadosConfigStore::read_default_zonegroup_id(const DoutPrefixProvider
* dpp
,
64 std::string_view realm_id
,
65 std::string
& zonegroup_id
)
67 const auto& pool
= impl
->zonegroup_pool
;
68 const auto oid
= default_zonegroup_oid(dpp
->get_cct()->_conf
, realm_id
);
70 RGWDefaultSystemMetaObjInfo default_info
;
71 int r
= impl
->read(dpp
, y
, pool
, oid
, default_info
, nullptr);
73 zonegroup_id
= default_info
.default_id
;
78 int RadosConfigStore::delete_default_zonegroup_id(const DoutPrefixProvider
* dpp
,
80 std::string_view realm_id
)
82 const auto& pool
= impl
->zonegroup_pool
;
83 const auto oid
= default_zonegroup_oid(dpp
->get_cct()->_conf
, realm_id
);
84 return impl
->remove(dpp
, y
, pool
, oid
, nullptr);
88 class RadosZoneGroupWriter
: public sal::ZoneGroupWriter
{
90 RGWObjVersionTracker objv
;
91 std::string zonegroup_id
;
92 std::string zonegroup_name
;
94 RadosZoneGroupWriter(ConfigImpl
* impl
, RGWObjVersionTracker objv
,
95 std::string_view zonegroup_id
,
96 std::string_view zonegroup_name
)
97 : impl(impl
), objv(std::move(objv
)),
98 zonegroup_id(zonegroup_id
), zonegroup_name(zonegroup_name
)
102 int write(const DoutPrefixProvider
* dpp
, optional_yield y
,
103 const RGWZoneGroup
& info
) override
105 if (zonegroup_id
!= info
.get_id() || zonegroup_name
!= info
.get_name()) {
106 return -EINVAL
; // can't modify zonegroup id or name directly
109 const auto& pool
= impl
->zonegroup_pool
;
110 const auto info_oid
= zonegroup_info_oid(info
.get_id());
111 return impl
->write(dpp
, y
, pool
, info_oid
, Create::MustExist
, info
, &objv
);
114 int rename(const DoutPrefixProvider
* dpp
, optional_yield y
,
115 RGWZoneGroup
& info
, std::string_view new_name
) override
117 if (zonegroup_id
!= info
.get_id() || zonegroup_name
!= info
.get_name()) {
118 return -EINVAL
; // can't modify zonegroup id or name directly
120 if (new_name
.empty()) {
121 ldpp_dout(dpp
, 0) << "zonegroup cannot have an empty name" << dendl
;
125 const auto& pool
= impl
->zonegroup_pool
;
126 const auto name
= RGWNameToId
{info
.get_id()};
127 const auto info_oid
= zonegroup_info_oid(info
.get_id());
128 const auto old_oid
= zonegroup_name_oid(info
.get_name());
129 const auto new_oid
= zonegroup_name_oid(new_name
);
132 RGWObjVersionTracker new_objv
;
133 new_objv
.generate_new_write_ver(dpp
->get_cct());
134 int r
= impl
->write(dpp
, y
, pool
, new_oid
, Create::MustNotExist
,
140 // write the info with updated name
141 info
.set_name(std::string
{new_name
});
142 r
= impl
->write(dpp
, y
, pool
, info_oid
, Create::MustExist
, info
, &objv
);
144 // on failure, unlink the new name
145 (void) impl
->remove(dpp
, y
, pool
, new_oid
, &new_objv
);
149 // unlink the old name
150 (void) impl
->remove(dpp
, y
, pool
, old_oid
, nullptr);
152 zonegroup_name
= new_name
;
156 int remove(const DoutPrefixProvider
* dpp
, optional_yield y
) override
158 const auto& pool
= impl
->zonegroup_pool
;
159 const auto info_oid
= zonegroup_info_oid(zonegroup_id
);
160 int r
= impl
->remove(dpp
, y
, pool
, info_oid
, &objv
);
164 const auto name_oid
= zonegroup_name_oid(zonegroup_name
);
165 (void) impl
->remove(dpp
, y
, pool
, name_oid
, nullptr);
168 }; // RadosZoneGroupWriter
171 int RadosConfigStore::create_zonegroup(const DoutPrefixProvider
* dpp
,
172 optional_yield y
, bool exclusive
,
173 const RGWZoneGroup
& info
,
174 std::unique_ptr
<sal::ZoneGroupWriter
>* writer
)
176 if (info
.get_id().empty()) {
177 ldpp_dout(dpp
, 0) << "zonegroup cannot have an empty id" << dendl
;
180 if (info
.get_name().empty()) {
181 ldpp_dout(dpp
, 0) << "zonegroup cannot have an empty name" << dendl
;
185 const auto& pool
= impl
->zonegroup_pool
;
186 const auto create
= exclusive
? Create::MustNotExist
: Create::MayExist
;
188 // write the zonegroup info
189 const auto info_oid
= zonegroup_info_oid(info
.get_id());
190 RGWObjVersionTracker objv
;
191 objv
.generate_new_write_ver(dpp
->get_cct());
193 int r
= impl
->write(dpp
, y
, pool
, info_oid
, create
, info
, &objv
);
198 // write the zonegroup name
199 const auto name_oid
= zonegroup_name_oid(info
.get_name());
200 const auto name
= RGWNameToId
{info
.get_id()};
201 RGWObjVersionTracker name_objv
;
202 name_objv
.generate_new_write_ver(dpp
->get_cct());
204 r
= impl
->write(dpp
, y
, pool
, name_oid
, create
, name
, &name_objv
);
206 (void) impl
->remove(dpp
, y
, pool
, info_oid
, &objv
);
211 *writer
= std::make_unique
<RadosZoneGroupWriter
>(
212 impl
.get(), std::move(objv
), info
.get_id(), info
.get_name());
217 int RadosConfigStore::read_zonegroup_by_id(const DoutPrefixProvider
* dpp
,
219 std::string_view zonegroup_id
,
221 std::unique_ptr
<sal::ZoneGroupWriter
>* writer
)
223 const auto& pool
= impl
->zonegroup_pool
;
224 const auto info_oid
= zonegroup_info_oid(zonegroup_id
);
225 RGWObjVersionTracker objv
;
227 int r
= impl
->read(dpp
, y
, pool
, info_oid
, info
, &objv
);
233 *writer
= std::make_unique
<RadosZoneGroupWriter
>(
234 impl
.get(), std::move(objv
), info
.get_id(), info
.get_name());
239 int RadosConfigStore::read_zonegroup_by_name(const DoutPrefixProvider
* dpp
,
241 std::string_view zonegroup_name
,
243 std::unique_ptr
<sal::ZoneGroupWriter
>* writer
)
245 const auto& pool
= impl
->zonegroup_pool
;
247 // look up zonegroup id by name
249 const auto name_oid
= zonegroup_name_oid(zonegroup_name
);
250 int r
= impl
->read(dpp
, y
, pool
, name_oid
, name
, nullptr);
255 const auto info_oid
= zonegroup_info_oid(name
.obj_id
);
256 RGWObjVersionTracker objv
;
257 r
= impl
->read(dpp
, y
, pool
, info_oid
, info
, &objv
);
263 *writer
= std::make_unique
<RadosZoneGroupWriter
>(
264 impl
.get(), std::move(objv
), info
.get_id(), info
.get_name());
269 int RadosConfigStore::read_default_zonegroup(const DoutPrefixProvider
* dpp
,
271 std::string_view realm_id
,
273 std::unique_ptr
<sal::ZoneGroupWriter
>* writer
)
275 const auto& pool
= impl
->zonegroup_pool
;
277 // read default zonegroup id
278 RGWDefaultSystemMetaObjInfo default_info
;
279 const auto default_oid
= default_zonegroup_oid(dpp
->get_cct()->_conf
, realm_id
);
280 int r
= impl
->read(dpp
, y
, pool
, default_oid
, default_info
, nullptr);
285 const auto info_oid
= zonegroup_info_oid(default_info
.default_id
);
286 RGWObjVersionTracker objv
;
287 r
= impl
->read(dpp
, y
, pool
, info_oid
, info
, &objv
);
293 *writer
= std::make_unique
<RadosZoneGroupWriter
>(
294 impl
.get(), std::move(objv
), info
.get_id(), info
.get_name());
299 int RadosConfigStore::list_zonegroup_names(const DoutPrefixProvider
* dpp
,
301 const std::string
& marker
,
302 std::span
<std::string
> entries
,
303 sal::ListResult
<std::string
>& result
)
305 const auto& pool
= impl
->zonegroup_pool
;
306 constexpr auto prefix
= [] (std::string oid
) -> std::string
{
307 if (!oid
.starts_with(zonegroup_names_oid_prefix
)) {
310 return oid
.substr(zonegroup_names_oid_prefix
.size());
312 return impl
->list(dpp
, y
, pool
, marker
, prefix
, entries
, result
);
315 } // namespace rgw::rados