]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/services/svc_cls.cc
984d92a5ee95f7c16c7dc8c202f64c0394018d33
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
9 #include "rgw/rgw_zone.h"
11 #include "cls/otp/cls_otp_client.h"
12 #include "cls/log/cls_log_client.h"
13 #include "cls/lock/cls_lock_client.h"
16 #define dout_subsys ceph_subsys_rgw
18 static string log_lock_name
= "rgw_log_lock";
20 int RGWSI_Cls::do_start(optional_yield y
)
22 int r
= mfa
.do_start(y
);
24 ldout(cct
, 0) << "ERROR: failed to start mfa service" << dendl
;
31 int RGWSI_Cls::MFA::get_mfa_obj(const rgw_user
& user
, std::optional
<RGWSI_RADOS::Obj
> *obj
)
33 string oid
= get_mfa_oid(user
);
34 rgw_raw_obj
o(zone_svc
->get_zone_params().otp_pool
, oid
);
36 obj
->emplace(rados_svc
->obj(o
));
37 int r
= (*obj
)->open();
39 ldout(cct
, 4) << "failed to open rados context for " << o
<< dendl
;
46 int RGWSI_Cls::MFA::get_mfa_ref(const rgw_user
& user
, rgw_rados_ref
*ref
)
48 std::optional
<RGWSI_RADOS::Obj
> obj
;
49 int r
= get_mfa_obj(user
, &obj
);
53 *ref
= obj
->get_ref();
57 int RGWSI_Cls::MFA::check_mfa(const rgw_user
& user
, const string
& otp_id
, const string
& pin
, optional_yield y
)
60 int r
= get_mfa_ref(user
, &ref
);
65 rados::cls::otp::otp_check_t result
;
67 r
= rados::cls::otp::OTP::check(cct
, ref
.pool
.ioctx(), ref
.obj
.oid
, otp_id
, pin
, &result
);
71 ldout(cct
, 20) << "OTP check, otp_id=" << otp_id
<< " result=" << (int)result
.result
<< dendl
;
73 return (result
.result
== rados::cls::otp::OTP_CHECK_SUCCESS
? 0 : -EACCES
);
76 void RGWSI_Cls::MFA::prepare_mfa_write(librados::ObjectWriteOperation
*op
,
77 RGWObjVersionTracker
*objv_tracker
,
78 const ceph::real_time
& mtime
)
80 RGWObjVersionTracker ot
;
86 if (ot
.write_version
.tag
.empty()) {
87 if (ot
.read_version
.tag
.empty()) {
88 ot
.generate_new_write_ver(cct
);
90 ot
.write_version
= ot
.read_version
;
91 ot
.write_version
.ver
++;
95 ot
.prepare_op_for_write(op
);
96 struct timespec mtime_ts
= real_clock::to_timespec(mtime
);
97 op
->mtime2(&mtime_ts
);
100 int RGWSI_Cls::MFA::create_mfa(const rgw_user
& user
, const rados::cls::otp::otp_info_t
& config
,
101 RGWObjVersionTracker
*objv_tracker
, const ceph::real_time
& mtime
, optional_yield y
)
103 std::optional
<RGWSI_RADOS::Obj
> obj
;
104 int r
= get_mfa_obj(user
, &obj
);
109 librados::ObjectWriteOperation op
;
110 prepare_mfa_write(&op
, objv_tracker
, mtime
);
111 rados::cls::otp::OTP::create(&op
, config
);
112 r
= obj
->operate(&op
, y
);
114 ldout(cct
, 20) << "OTP create, otp_id=" << config
.id
<< " result=" << (int)r
<< dendl
;
121 int RGWSI_Cls::MFA::remove_mfa(const rgw_user
& user
, const string
& id
,
122 RGWObjVersionTracker
*objv_tracker
,
123 const ceph::real_time
& mtime
,
126 std::optional
<RGWSI_RADOS::Obj
> obj
;
127 int r
= get_mfa_obj(user
, &obj
);
132 librados::ObjectWriteOperation op
;
133 prepare_mfa_write(&op
, objv_tracker
, mtime
);
134 rados::cls::otp::OTP::remove(&op
, id
);
135 r
= obj
->operate(&op
, y
);
137 ldout(cct
, 20) << "OTP remove, otp_id=" << id
<< " result=" << (int)r
<< dendl
;
144 int RGWSI_Cls::MFA::get_mfa(const rgw_user
& user
, const string
& id
, rados::cls::otp::otp_info_t
*result
,
149 int r
= get_mfa_ref(user
, &ref
);
154 r
= rados::cls::otp::OTP::get(nullptr, ref
.pool
.ioctx(), ref
.obj
.oid
, id
, result
);
162 int RGWSI_Cls::MFA::list_mfa(const rgw_user
& user
, list
<rados::cls::otp::otp_info_t
> *result
,
167 int r
= get_mfa_ref(user
, &ref
);
172 r
= rados::cls::otp::OTP::get_all(nullptr, ref
.pool
.ioctx(), ref
.obj
.oid
, result
);
180 int RGWSI_Cls::MFA::otp_get_current_time(const rgw_user
& user
, ceph::real_time
*result
,
185 int r
= get_mfa_ref(user
, &ref
);
190 r
= rados::cls::otp::OTP::get_current_time(ref
.pool
.ioctx(), ref
.obj
.oid
, result
);
198 int RGWSI_Cls::MFA::set_mfa(const string
& oid
, const list
<rados::cls::otp::otp_info_t
>& entries
,
199 bool reset_obj
, RGWObjVersionTracker
*objv_tracker
,
200 const real_time
& mtime
,
203 rgw_raw_obj
o(zone_svc
->get_zone_params().otp_pool
, oid
);
204 auto obj
= rados_svc
->obj(o
);
207 ldout(cct
, 4) << "failed to open rados context for " << o
<< dendl
;
210 librados::ObjectWriteOperation op
;
213 op
.set_op_flags2(LIBRADOS_OP_FLAG_FAILOK
);
216 prepare_mfa_write(&op
, objv_tracker
, mtime
);
217 rados::cls::otp::OTP::set(&op
, entries
);
218 r
= obj
.operate(&op
, y
);
220 ldout(cct
, 20) << "OTP set entries.size()=" << entries
.size() << " result=" << (int)r
<< dendl
;
227 int RGWSI_Cls::MFA::list_mfa(const string
& oid
, list
<rados::cls::otp::otp_info_t
> *result
,
228 RGWObjVersionTracker
*objv_tracker
, ceph::real_time
*pmtime
,
231 rgw_raw_obj
o(zone_svc
->get_zone_params().otp_pool
, oid
);
232 auto obj
= rados_svc
->obj(o
);
235 ldout(cct
, 4) << "failed to open rados context for " << o
<< dendl
;
238 auto& ref
= obj
.get_ref();
239 librados::ObjectReadOperation op
;
240 struct timespec mtime_ts
;
242 op
.stat2(nullptr, &mtime_ts
, nullptr);
244 objv_tracker
->prepare_op_for_read(&op
);
245 r
= rados::cls::otp::OTP::get_all(&op
, ref
.pool
.ioctx(), ref
.obj
.oid
, result
);
250 *pmtime
= ceph::real_clock::from_timespec(mtime_ts
);
256 void RGWSI_Cls::TimeLog::prepare_entry(cls_log_entry
& entry
,
258 const string
& section
,
262 cls_log_add_prepare_entry(entry
, utime_t(ut
), section
, key
, bl
);
265 int RGWSI_Cls::TimeLog::init_obj(const string
& oid
, RGWSI_RADOS::Obj
& obj
)
267 rgw_raw_obj
o(zone_svc
->get_zone_params().log_pool
, oid
);
268 obj
= rados_svc
->obj(o
);
272 int RGWSI_Cls::TimeLog::add(const string
& oid
,
274 const string
& section
,
279 RGWSI_RADOS::Obj obj
;
281 int r
= init_obj(oid
, obj
);
286 librados::ObjectWriteOperation op
;
288 cls_log_add(op
, t
, section
, key
, bl
);
290 return obj
.operate(&op
, y
);
293 int RGWSI_Cls::TimeLog::add(const string
& oid
,
294 std::list
<cls_log_entry
>& entries
,
295 librados::AioCompletion
*completion
,
299 RGWSI_RADOS::Obj obj
;
301 int r
= init_obj(oid
, obj
);
306 librados::ObjectWriteOperation op
;
307 cls_log_add(op
, entries
, monotonic_inc
);
310 r
= obj
.operate(&op
, y
);
312 r
= obj
.aio_operate(completion
, &op
);
317 int RGWSI_Cls::TimeLog::list(const string
& oid
,
318 const real_time
& start_time
,
319 const real_time
& end_time
,
320 int max_entries
, std::list
<cls_log_entry
>& entries
,
321 const string
& marker
,
326 RGWSI_RADOS::Obj obj
;
328 int r
= init_obj(oid
, obj
);
333 librados::ObjectReadOperation op
;
335 utime_t
st(start_time
);
336 utime_t
et(end_time
);
338 cls_log_list(op
, st
, et
, marker
, max_entries
, entries
,
339 out_marker
, truncated
);
343 int ret
= obj
.operate(&op
, &obl
, y
);
350 int RGWSI_Cls::TimeLog::info(const string
& oid
,
351 cls_log_header
*header
,
354 RGWSI_RADOS::Obj obj
;
356 int r
= init_obj(oid
, obj
);
361 librados::ObjectReadOperation op
;
363 cls_log_info(op
, header
);
367 int ret
= obj
.operate(&op
, &obl
, y
);
374 int RGWSI_Cls::TimeLog::info_async(RGWSI_RADOS::Obj
& obj
,
376 cls_log_header
*header
,
377 librados::AioCompletion
*completion
)
379 int r
= init_obj(oid
, obj
);
384 librados::ObjectReadOperation op
;
386 cls_log_info(op
, header
);
388 int ret
= obj
.aio_operate(completion
, &op
, nullptr);
395 int RGWSI_Cls::TimeLog::trim(const string
& oid
,
396 const real_time
& start_time
,
397 const real_time
& end_time
,
398 const string
& from_marker
,
399 const string
& to_marker
,
400 librados::AioCompletion
*completion
,
403 RGWSI_RADOS::Obj obj
;
405 int r
= init_obj(oid
, obj
);
410 utime_t
st(start_time
);
411 utime_t
et(end_time
);
413 librados::ObjectWriteOperation op
;
414 cls_log_trim(op
, st
, et
, from_marker
, to_marker
);
417 r
= obj
.operate(&op
, y
);
419 r
= obj
.aio_operate(completion
, &op
);
424 int RGWSI_Cls::Lock::lock_exclusive(const rgw_pool
& pool
,
429 std::optional
<string
> lock_name
)
431 auto p
= rados_svc
->pool(pool
);
437 uint64_t msec
= std::chrono::duration_cast
<std::chrono::milliseconds
>(duration
).count();
438 utime_t
ut(msec
/ 1000, msec
% 1000);
440 rados::cls::lock::Lock
l(lock_name
.value_or(log_lock_name
));
442 l
.set_cookie(owner_id
);
444 l
.set_may_renew(true);
446 return l
.lock_exclusive(&p
.ioctx(), oid
);
449 int RGWSI_Cls::Lock::unlock(const rgw_pool
& pool
,
453 std::optional
<string
> lock_name
)
455 auto p
= rados_svc
->pool(pool
);
461 rados::cls::lock::Lock
l(lock_name
.value_or(log_lock_name
));
463 l
.set_cookie(owner_id
);
465 return l
.unlock(&p
.ioctx(), oid
);