]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/services/svc_cls.cc
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
20 static string log_lock_name
= "rgw_log_lock";
22 int RGWSI_Cls::do_start(optional_yield y
, const DoutPrefixProvider
*dpp
)
24 int r
= mfa
.do_start(y
, dpp
);
26 ldpp_dout(dpp
, 0) << "ERROR: failed to start mfa service" << dendl
;
33 int RGWSI_Cls::MFA::get_mfa_obj(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, std::optional
<RGWSI_RADOS::Obj
> *obj
)
35 string oid
= get_mfa_oid(user
);
36 rgw_raw_obj
o(zone_svc
->get_zone_params().otp_pool
, oid
);
38 obj
->emplace(rados_svc
->obj(o
));
39 int r
= (*obj
)->open(dpp
);
41 ldpp_dout(dpp
, 4) << "failed to open rados context for " << o
<< dendl
;
48 int RGWSI_Cls::MFA::get_mfa_ref(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, rgw_rados_ref
*ref
)
50 std::optional
<RGWSI_RADOS::Obj
> obj
;
51 int r
= get_mfa_obj(dpp
, user
, &obj
);
55 *ref
= obj
->get_ref();
59 int RGWSI_Cls::MFA::check_mfa(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, const string
& otp_id
, const string
& pin
, optional_yield y
)
62 int r
= get_mfa_ref(dpp
, user
, &ref
);
67 rados::cls::otp::otp_check_t result
;
69 r
= rados::cls::otp::OTP::check(cct
, ref
.pool
.ioctx(), ref
.obj
.oid
, otp_id
, pin
, &result
);
73 ldpp_dout(dpp
, 20) << "OTP check, otp_id=" << otp_id
<< " result=" << (int)result
.result
<< dendl
;
75 return (result
.result
== rados::cls::otp::OTP_CHECK_SUCCESS
? 0 : -EACCES
);
78 void RGWSI_Cls::MFA::prepare_mfa_write(librados::ObjectWriteOperation
*op
,
79 RGWObjVersionTracker
*objv_tracker
,
80 const ceph::real_time
& mtime
)
82 RGWObjVersionTracker ot
;
88 if (ot
.write_version
.tag
.empty()) {
89 if (ot
.read_version
.tag
.empty()) {
90 ot
.generate_new_write_ver(cct
);
92 ot
.write_version
= ot
.read_version
;
93 ot
.write_version
.ver
++;
97 ot
.prepare_op_for_write(op
);
98 struct timespec mtime_ts
= real_clock::to_timespec(mtime
);
99 op
->mtime2(&mtime_ts
);
102 int RGWSI_Cls::MFA::create_mfa(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, const rados::cls::otp::otp_info_t
& config
,
103 RGWObjVersionTracker
*objv_tracker
, const ceph::real_time
& mtime
, optional_yield y
)
105 std::optional
<RGWSI_RADOS::Obj
> obj
;
106 int r
= get_mfa_obj(dpp
, user
, &obj
);
111 librados::ObjectWriteOperation op
;
112 prepare_mfa_write(&op
, objv_tracker
, mtime
);
113 rados::cls::otp::OTP::create(&op
, config
);
114 r
= obj
->operate(dpp
, &op
, y
);
116 ldpp_dout(dpp
, 20) << "OTP create, otp_id=" << config
.id
<< " result=" << (int)r
<< dendl
;
123 int RGWSI_Cls::MFA::remove_mfa(const DoutPrefixProvider
*dpp
,
124 const rgw_user
& user
, const string
& id
,
125 RGWObjVersionTracker
*objv_tracker
,
126 const ceph::real_time
& mtime
,
129 std::optional
<RGWSI_RADOS::Obj
> obj
;
130 int r
= get_mfa_obj(dpp
, user
, &obj
);
135 librados::ObjectWriteOperation op
;
136 prepare_mfa_write(&op
, objv_tracker
, mtime
);
137 rados::cls::otp::OTP::remove(&op
, id
);
138 r
= obj
->operate(dpp
, &op
, y
);
140 ldpp_dout(dpp
, 20) << "OTP remove, otp_id=" << id
<< " result=" << (int)r
<< dendl
;
147 int RGWSI_Cls::MFA::get_mfa(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, const string
& id
, rados::cls::otp::otp_info_t
*result
,
152 int r
= get_mfa_ref(dpp
, user
, &ref
);
157 r
= rados::cls::otp::OTP::get(nullptr, ref
.pool
.ioctx(), ref
.obj
.oid
, id
, result
);
165 int RGWSI_Cls::MFA::list_mfa(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, list
<rados::cls::otp::otp_info_t
> *result
,
170 int r
= get_mfa_ref(dpp
, user
, &ref
);
175 r
= rados::cls::otp::OTP::get_all(nullptr, ref
.pool
.ioctx(), ref
.obj
.oid
, result
);
183 int RGWSI_Cls::MFA::otp_get_current_time(const DoutPrefixProvider
*dpp
, const rgw_user
& user
, ceph::real_time
*result
,
188 int r
= get_mfa_ref(dpp
, user
, &ref
);
193 r
= rados::cls::otp::OTP::get_current_time(ref
.pool
.ioctx(), ref
.obj
.oid
, result
);
201 int RGWSI_Cls::MFA::set_mfa(const DoutPrefixProvider
*dpp
, const string
& oid
, const list
<rados::cls::otp::otp_info_t
>& entries
,
202 bool reset_obj
, RGWObjVersionTracker
*objv_tracker
,
203 const real_time
& mtime
,
206 rgw_raw_obj
o(zone_svc
->get_zone_params().otp_pool
, oid
);
207 auto obj
= rados_svc
->obj(o
);
208 int r
= obj
.open(dpp
);
210 ldpp_dout(dpp
, 4) << "failed to open rados context for " << o
<< dendl
;
213 librados::ObjectWriteOperation op
;
216 op
.set_op_flags2(LIBRADOS_OP_FLAG_FAILOK
);
219 prepare_mfa_write(&op
, objv_tracker
, mtime
);
220 rados::cls::otp::OTP::set(&op
, entries
);
221 r
= obj
.operate(dpp
, &op
, y
);
223 ldpp_dout(dpp
, 20) << "OTP set entries.size()=" << entries
.size() << " result=" << (int)r
<< dendl
;
230 int RGWSI_Cls::MFA::list_mfa(const DoutPrefixProvider
*dpp
, const string
& oid
, list
<rados::cls::otp::otp_info_t
> *result
,
231 RGWObjVersionTracker
*objv_tracker
, ceph::real_time
*pmtime
,
234 rgw_raw_obj
o(zone_svc
->get_zone_params().otp_pool
, oid
);
235 auto obj
= rados_svc
->obj(o
);
236 int r
= obj
.open(dpp
);
238 ldpp_dout(dpp
, 4) << "failed to open rados context for " << o
<< dendl
;
241 auto& ref
= obj
.get_ref();
242 librados::ObjectReadOperation op
;
243 struct timespec mtime_ts
;
245 op
.stat2(nullptr, &mtime_ts
, nullptr);
247 objv_tracker
->prepare_op_for_read(&op
);
248 r
= rados::cls::otp::OTP::get_all(&op
, ref
.pool
.ioctx(), ref
.obj
.oid
, result
);
253 *pmtime
= ceph::real_clock::from_timespec(mtime_ts
);
259 void RGWSI_Cls::TimeLog::prepare_entry(cls_log_entry
& entry
,
261 const string
& section
,
265 cls_log_add_prepare_entry(entry
, utime_t(ut
), section
, key
, bl
);
268 int RGWSI_Cls::TimeLog::init_obj(const DoutPrefixProvider
*dpp
, const string
& oid
, RGWSI_RADOS::Obj
& obj
)
270 rgw_raw_obj
o(zone_svc
->get_zone_params().log_pool
, oid
);
271 obj
= rados_svc
->obj(o
);
272 return obj
.open(dpp
);
275 int RGWSI_Cls::TimeLog::add(const DoutPrefixProvider
*dpp
,
278 const string
& section
,
283 RGWSI_RADOS::Obj obj
;
285 int r
= init_obj(dpp
, oid
, obj
);
290 librados::ObjectWriteOperation op
;
292 cls_log_add(op
, t
, section
, key
, bl
);
294 return obj
.operate(dpp
, &op
, y
);
297 int RGWSI_Cls::TimeLog::add(const DoutPrefixProvider
*dpp
,
299 std::list
<cls_log_entry
>& entries
,
300 librados::AioCompletion
*completion
,
304 RGWSI_RADOS::Obj obj
;
306 int r
= init_obj(dpp
, oid
, obj
);
311 librados::ObjectWriteOperation op
;
312 cls_log_add(op
, entries
, monotonic_inc
);
315 r
= obj
.operate(dpp
, &op
, y
);
317 r
= obj
.aio_operate(completion
, &op
);
322 int RGWSI_Cls::TimeLog::list(const DoutPrefixProvider
*dpp
,
324 const real_time
& start_time
,
325 const real_time
& end_time
,
326 int max_entries
, std::list
<cls_log_entry
>& entries
,
327 const string
& marker
,
332 RGWSI_RADOS::Obj obj
;
334 int r
= init_obj(dpp
, oid
, obj
);
339 librados::ObjectReadOperation op
;
341 utime_t
st(start_time
);
342 utime_t
et(end_time
);
344 cls_log_list(op
, st
, et
, marker
, max_entries
, entries
,
345 out_marker
, truncated
);
349 int ret
= obj
.operate(dpp
, &op
, &obl
, y
);
356 int RGWSI_Cls::TimeLog::info(const DoutPrefixProvider
*dpp
,
358 cls_log_header
*header
,
361 RGWSI_RADOS::Obj obj
;
363 int r
= init_obj(dpp
, oid
, obj
);
368 librados::ObjectReadOperation op
;
370 cls_log_info(op
, header
);
374 int ret
= obj
.operate(dpp
, &op
, &obl
, y
);
381 int RGWSI_Cls::TimeLog::info_async(const DoutPrefixProvider
*dpp
,
382 RGWSI_RADOS::Obj
& obj
,
384 cls_log_header
*header
,
385 librados::AioCompletion
*completion
)
387 int r
= init_obj(dpp
, oid
, obj
);
392 librados::ObjectReadOperation op
;
394 cls_log_info(op
, header
);
396 int ret
= obj
.aio_operate(completion
, &op
, nullptr);
403 int RGWSI_Cls::TimeLog::trim(const DoutPrefixProvider
*dpp
,
405 const real_time
& start_time
,
406 const real_time
& end_time
,
407 const string
& from_marker
,
408 const string
& to_marker
,
409 librados::AioCompletion
*completion
,
412 RGWSI_RADOS::Obj obj
;
414 int r
= init_obj(dpp
, oid
, obj
);
419 utime_t
st(start_time
);
420 utime_t
et(end_time
);
422 librados::ObjectWriteOperation op
;
423 cls_log_trim(op
, st
, et
, from_marker
, to_marker
);
426 r
= obj
.operate(dpp
, &op
, y
);
428 r
= obj
.aio_operate(completion
, &op
);
433 int RGWSI_Cls::Lock::lock_exclusive(const DoutPrefixProvider
*dpp
,
434 const rgw_pool
& pool
,
439 std::optional
<string
> lock_name
)
441 auto p
= rados_svc
->pool(pool
);
447 uint64_t msec
= std::chrono::duration_cast
<std::chrono::milliseconds
>(duration
).count();
448 utime_t
ut(msec
/ 1000, msec
% 1000);
450 rados::cls::lock::Lock
l(lock_name
.value_or(log_lock_name
));
452 l
.set_cookie(owner_id
);
454 l
.set_may_renew(true);
456 return l
.lock_exclusive(&p
.ioctx(), oid
);
459 int RGWSI_Cls::Lock::unlock(const DoutPrefixProvider
*dpp
,
460 const rgw_pool
& pool
,
464 std::optional
<string
> lock_name
)
466 auto p
= rados_svc
->pool(pool
);
472 rados::cls::lock::Lock
l(lock_name
.value_or(log_lock_name
));
474 l
.set_cookie(owner_id
);
476 return l
.unlock(&p
.ioctx(), oid
);