]>
git.proxmox.com Git - ceph.git/blob - ceph/src/crimson/os/alienstore/alien_store.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "alien_collection.h"
5 #include "alien_store.h"
9 #include <boost/algorithm/string/trim.hpp>
10 #include <fmt/format.h>
11 #include <fmt/ostream.h>
13 #include <seastar/core/alien.hh>
14 #include <seastar/core/future-util.hh>
15 #include <seastar/core/reactor.hh>
17 #include "common/ceph_context.h"
18 #include "global/global_context.h"
19 #include "include/Context.h"
20 #include "os/bluestore/BlueStore.h"
21 #include "os/ObjectStore.h"
22 #include "os/Transaction.h"
24 #include "crimson/common/log.h"
25 #include "crimson/os/futurized_store.h"
28 seastar::logger
& logger()
30 return crimson::get_logger(ceph_subsys_filestore
);
33 class OnCommit final
: public Context
37 seastar::promise
<> &alien_done
;
41 seastar::promise
<> &done
,
43 ceph::os::Transaction
& txn
)
44 : cpuid(id
), oncommit(oncommit
),
47 void finish(int) final
{
48 return seastar::alien::submit_to(cpuid
, [this] {
49 if (oncommit
) oncommit
->complete(0);
50 alien_done
.set_value();
51 return seastar::make_ready_future
<>();
57 namespace crimson::os
{
59 AlienStore::AlienStore(const std::string
& path
, const ConfigValues
& values
)
62 cct
= std::make_unique
<CephContext
>(CEPH_ENTITY_TYPE_OSD
);
63 g_ceph_context
= cct
.get();
64 cct
->_conf
.set_config_values(values
);
65 store
= std::make_unique
<BlueStore
>(cct
.get(), path
);
66 tp
= std::make_unique
<crimson::thread::ThreadPool
>(1, 128, seastar::engine().cpu_id() + 10);
69 seastar::future
<> AlienStore::start()
74 seastar::future
<> AlienStore::stop()
76 return tp
->submit([this] {
77 for (auto [cid
, ch
]: coll_map
)
78 static_cast<AlienCollection
*>(ch
.get())->collection
.reset();
85 AlienStore::~AlienStore() = default;
87 seastar::future
<> AlienStore::mount()
89 logger().debug("{}", __func__
);
90 return tp
->submit([this] {
91 return store
->mount();
93 return seastar::now();
97 seastar::future
<> AlienStore::umount()
99 logger().debug("{}", __func__
);
100 return transaction_gate
.close().then([this] {
101 return tp
->submit([this] {
102 return store
->umount();
105 return seastar::now();
109 seastar::future
<> AlienStore::mkfs(uuid_d new_osd_fsid
)
111 logger().debug("{}", __func__
);
112 osd_fsid
= new_osd_fsid
;
113 return tp
->submit([this] {
114 return store
->mkfs();
116 return seastar::now();
120 seastar::future
<std::vector
<ghobject_t
>, ghobject_t
>
121 AlienStore::list_objects(CollectionRef ch
,
122 const ghobject_t
& start
,
123 const ghobject_t
& end
,
124 uint64_t limit
) const
126 logger().debug("{}", __func__
);
127 return seastar::do_with(std::vector
<ghobject_t
>(), ghobject_t(),
128 [=] (auto &objects
, auto &next
) {
129 objects
.reserve(limit
);
130 return tp
->submit([=, &objects
, &next
] {
131 auto c
= static_cast<AlienCollection
*>(ch
.get());
132 return store
->collection_list(c
->collection
, start
, end
,
133 store
->get_ideal_list_max(),
135 }).then([&objects
, &next
] (int) {
136 return seastar::make_ready_future
<std::vector
<ghobject_t
>, ghobject_t
>(
137 std::move(objects
), std::move(next
));
142 seastar::future
<CollectionRef
> AlienStore::create_new_collection(const coll_t
& cid
)
144 logger().debug("{}", __func__
);
145 return tp
->submit([this, cid
] {
146 return store
->create_new_collection(cid
);
147 }).then([this, cid
] (ObjectStore::CollectionHandle c
) {
149 auto cp
= coll_map
.find(c
->cid
);
150 if (cp
== coll_map
.end()) {
151 ch
= new AlienCollection(c
);
152 coll_map
[c
->cid
] = ch
;
155 auto ach
= static_cast<AlienCollection
*>(ch
.get());
156 if (ach
->collection
!= c
) {
160 return seastar::make_ready_future
<CollectionRef
>(ch
);
165 seastar::future
<CollectionRef
> AlienStore::open_collection(const coll_t
& cid
)
167 logger().debug("{}", __func__
);
168 return tp
->submit([this, cid
] {
169 return store
->open_collection(cid
);
170 }).then([this] (ObjectStore::CollectionHandle c
) {
172 auto cp
= coll_map
.find(c
->cid
);
173 if (cp
== coll_map
.end()){
174 ch
= new AlienCollection(c
);
175 coll_map
[c
->cid
] = ch
;
178 auto ach
= static_cast<AlienCollection
*>(ch
.get());
179 if (ach
->collection
!= c
){
183 return seastar::make_ready_future
<CollectionRef
>(ch
);
187 seastar::future
<std::vector
<coll_t
>> AlienStore::list_collections()
189 logger().debug("{}", __func__
);
191 return seastar::do_with(std::vector
<coll_t
>{}, [=] (auto &ls
) {
192 return tp
->submit([this, &ls
] {
193 return store
->list_collections(ls
);
194 }).then([&ls
] (int) {
195 return seastar::make_ready_future
<std::vector
<coll_t
>>(std::move(ls
));
200 AlienStore::read_errorator::future
<ceph::bufferlist
>
201 AlienStore::read(CollectionRef ch
,
202 const ghobject_t
& oid
,
207 logger().debug("{}", __func__
);
208 return seastar::do_with(ceph::bufferlist
{}, [=] (auto &bl
) {
209 return tp
->submit([=, &bl
] {
210 auto c
= static_cast<AlienCollection
*>(ch
.get());
211 return store
->read(c
->collection
, oid
, offset
, len
, bl
, op_flags
);
212 }).then([&bl
] (int r
) -> read_errorator::future
<ceph::bufferlist
> {
214 return crimson::ct_error::enoent::make();
215 } else if (r
== -EIO
) {
216 return crimson::ct_error::input_output_error::make();
218 return read_errorator::make_ready_future
<ceph::bufferlist
>(std::move(bl
));
224 AlienStore::get_attr_errorator::future
<ceph::bufferptr
>
225 AlienStore::get_attr(CollectionRef ch
,
226 const ghobject_t
& oid
,
227 std::string_view name
) const
229 logger().debug("{}", __func__
);
230 return seastar::do_with(ceph::bufferptr
{}, [=] (auto &value
) {
231 return tp
->submit([=, &value
] {
232 auto c
=static_cast<AlienCollection
*>(ch
.get());
233 return store
->getattr(c
->collection
, oid
,
234 static_cast<std::string
>(name
).c_str(), value
);
235 }).then([oid
, name
, &value
] (int r
) -> get_attr_errorator::future
<ceph::bufferptr
> {
237 return crimson::ct_error::enoent::make();
238 } else if (r
== -ENODATA
) {
239 return crimson::ct_error::enodata::make();
241 return get_attr_errorator::make_ready_future
<ceph::bufferptr
>(
248 AlienStore::get_attrs_ertr::future
<AlienStore::attrs_t
>
249 AlienStore::get_attrs(CollectionRef ch
,
250 const ghobject_t
& oid
)
252 logger().debug("{}", __func__
);
253 return seastar::do_with(attrs_t
{}, [=] (auto &aset
) {
254 return tp
->submit([=, &aset
] {
255 auto c
= static_cast<AlienCollection
*>(ch
.get());
256 return store
->getattrs(c
->collection
, oid
,
257 reinterpret_cast<map
<string
,bufferptr
>&>(aset
));
258 }).then([&aset
] (int r
) -> get_attrs_ertr::future
<attrs_t
> {
260 return crimson::ct_error::enoent::make();;
262 return get_attrs_ertr::make_ready_future
<attrs_t
>(std::move(aset
));
268 seastar::future
<AlienStore::omap_values_t
>
269 AlienStore::omap_get_values(CollectionRef ch
,
270 const ghobject_t
& oid
,
271 const set
<string
>& keys
)
273 logger().debug("{}", __func__
);
274 return seastar::do_with(omap_values_t
{}, [=] (auto &values
) {
275 return tp
->submit([=, &values
] {
276 auto c
= static_cast<AlienCollection
*>(ch
.get());
277 return store
->omap_get_values(c
->collection
, oid
, keys
,
278 reinterpret_cast<map
<string
, bufferlist
>*>(&values
));
279 }).then([&values
] (int) {
280 return seastar::make_ready_future
<omap_values_t
>(std::move(values
));
285 seastar::future
<bool, AlienStore::omap_values_t
>
286 AlienStore::omap_get_values(CollectionRef ch
,
287 const ghobject_t
&oid
,
288 const std::optional
<string
> &start
)
290 logger().debug("{} with_start", __func__
);
291 return seastar::do_with(omap_values_t
{}, [=] (auto &values
) {
292 return tp
->submit([=, &values
] {
293 auto c
= static_cast<AlienCollection
*>(ch
.get());
294 return store
->omap_get_values(c
->collection
, oid
, start
,
295 reinterpret_cast<map
<string
, bufferlist
>*>(&values
));
296 }).then([&values
] (int r
) {
297 return seastar::make_ready_future
<bool, omap_values_t
>(true, std::move(values
));
302 seastar::future
<> AlienStore::do_transaction(CollectionRef ch
,
303 ceph::os::Transaction
&& txn
)
305 logger().debug("{}", __func__
);
306 auto id
= seastar::engine().cpu_id();
307 auto done
= seastar::promise
<>();
308 return seastar::do_with(
311 [this, ch
, id
] (auto &txn
, auto &done
) {
312 return seastar::with_gate(transaction_gate
, [this, ch
, id
, &txn
, &done
] {
313 return tp_mutex
.lock().then ([this, ch
, id
, &txn
, &done
] {
314 Context
*crimson_wrapper
=
315 ceph::os::Transaction::collect_all_contexts(txn
);
316 return tp
->submit([this, ch
, id
, crimson_wrapper
, &txn
, &done
] {
317 txn
.register_on_commit(new OnCommit(id
, done
, crimson_wrapper
, txn
));
318 auto c
= static_cast<AlienCollection
*>(ch
.get());
319 return store
->queue_transaction(c
->collection
, std::move(txn
));
321 }).then([this, &done
] (int) {
323 return done
.get_future();
329 seastar::future
<> AlienStore::write_meta(const std::string
& key
,
330 const std::string
& value
)
332 logger().debug("{}", __func__
);
333 return tp
->submit([=] {
334 return store
->write_meta(key
, value
);
336 return seastar::make_ready_future
<>();
340 seastar::future
<int, std::string
> AlienStore::read_meta(const std::string
& key
)
342 logger().debug("{}", __func__
);
343 return tp
->submit([this, key
] {
345 int r
= store
->read_meta(key
, &value
);
348 boost::algorithm::trim_right_if(value
,
349 [] (unsigned char c
) {return isspace(c
);});
353 return std::make_pair(r
, value
);
354 }).then([] (auto entry
) {
355 return seastar::make_ready_future
<int, std::string
>(entry
.first
, entry
.second
);
359 uuid_d
AlienStore::get_fsid() const
361 logger().debug("{}", __func__
);
365 seastar::future
<store_statfs_t
> AlienStore::stat() const
367 logger().info("{}", __func__
);
368 return seastar::do_with(store_statfs_t
{}, [this] (store_statfs_t
&st
) {
369 return tp
->submit([this, &st
] {
370 return store
->statfs(&st
, nullptr);
371 }).then([&st
] (int) {
372 return seastar::make_ready_future
<store_statfs_t
>(std::move(st
));
377 unsigned AlienStore::get_max_attr_name_length() const
379 logger().info("{}", __func__
);