return 0;
}
- int OTP::get(librados::IoCtx& ioctx, const string& oid,
- const list<string> *ids, bool get_all, list<otp_info_t> *result) {
+ int OTP::get(librados::ObjectReadOperation *rop,
+ librados::IoCtx& ioctx, const string& oid,
+ const list<string> *ids, bool get_all, list<otp_info_t> *result) {
+ librados::ObjectReadOperation _rop;
+ if (!rop) {
+ rop = &_rop;
+ }
cls_otp_get_otp_op op;
if (ids) {
op.ids = *ids;
op.get_all = get_all;
bufferlist in;
bufferlist out;
+ int op_ret;
::encode(op, in);
- int r = ioctx.exec(oid, "otp", "otp_get", in, out);
+ rop->exec("otp", "otp_get", in, &out, &op_ret);
+ int r = ioctx.operate(oid, rop, nullptr);
if (r < 0) {
return r;
}
+ if (op_ret < 0) {
+ return op_ret;
+ }
cls_otp_get_otp_reply ret;
auto iter = out.begin();
return 0;
}
- int OTP::get(librados::IoCtx& ioctx, const string& oid,
+ int OTP::get(librados::ObjectReadOperation *op,
+ librados::IoCtx& ioctx, const string& oid,
const string& id, otp_info_t *result) {
list<string> ids{ id };
list<otp_info_t> ret;
- int r = get(ioctx, oid, &ids, false, &ret);
+ int r = get(op, ioctx, oid, &ids, false, &ret);
if (r < 0) {
return r;
}
return 0;
}
- int OTP::get_all(librados::IoCtx& ioctx, const string& oid,
+ int OTP::get_all(librados::ObjectReadOperation *op, librados::IoCtx& ioctx, const string& oid,
list<otp_info_t> *result) {
- return get(ioctx, oid, nullptr, true, result);
+ return get(op, ioctx, oid, nullptr, true, result);
}
} // namespace otp
static void create(librados::ObjectWriteOperation *op, const otp_info_t& config);
static void set(librados::ObjectWriteOperation *op, const list<otp_info_t>& entries);
static void remove(librados::ObjectWriteOperation *op, const string& id);
- static int get(librados::IoCtx& ioctx, const string& oid,
+ static int get(librados::ObjectReadOperation *op,
+ librados::IoCtx& ioctx, const string& oid,
const list<string> *ids, bool get_all, list<otp_info_t> *result);
- static int get(librados::IoCtx& ioctx, const string& oid,
+ static int get(librados::ObjectReadOperation *op,
+ librados::IoCtx& ioctx, const string& oid,
const string& id, otp_info_t *result);
- static int get_all(librados::IoCtx& ioctx, const string& oid,
+ static int get_all(librados::ObjectReadOperation *op,
+ librados::IoCtx& ioctx, const string& oid,
list<otp_info_t> *result);
static int check(CephContext *cct, librados::IoCtx& ioctx, const string& oid,
const string& id, const string& val, otp_check_t *result);
#define CEPH_RGW_METADATA_H
#include <string>
+#include <utility>
#include <boost/optional.hpp>
#include "include/types.h"
int register_handler(RGWMetadataHandler *handler);
+ template <typename F>
+ int operate(RGWMetadataHandler *handler, const string& key,
+ RGWObjVersionTracker *objv_tracker, RGWMDLogStatus op_type,
+ F&& f);
+
RGWMetadataHandler *get_handler(const string& type);
int put_entry(RGWMetadataHandler *handler, const string& key, bufferlist& bl, bool exclusive,
int get_log_shard_id(const string& section, const string& key, int *shard_id);
};
+template <typename F>
+int RGWMetadataManager::operate(RGWMetadataHandler *handler, const string& key,
+ RGWObjVersionTracker *objv_tracker, RGWMDLogStatus op_type,
+ F&& f)
+{
+ string section;
+ RGWMetadataLogData log_data;
+ int ret = pre_modify(handler, section, key, log_data, objv_tracker, MDLOG_STATUS_WRITE);
+ if (ret < 0)
+ return ret;
+
+ string oid;
+ rgw_pool pool;
+
+ handler->get_pool_and_oid(store, key, pool, oid);
+
+ ret = std::forward<F>(f)();
+
+ /* cascading ret into post_modify() */
+
+ ret = post_modify(handler, section, key, log_data, objv_tracker, ret);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
#endif
#include "include/types.h"
#include "rgw_common.h"
+#include "rgw_tools.h"
#define dout_subsys ceph_subsys_rgw
real_time mtime;
list<rados::cls::otp::otp_info_t> result;
- int r = store->list_mfa(entry, &result);
+ int r = store->list_mfa(entry, &result, &objv_tracker, &mtime);
if (r < 0) {
return r;
}
-
RGWOTPMetadataObject *mdo = new RGWOTPMetadataObject(result, objv_tracker.read_version, mtime);
*obj = mdo;
return 0;
return -EINVAL;
}
- int r = store->set_mfa(entry, devices, true);
- if (r < 0) {
- return r;
- }
-
- return STATUS_APPLIED;
-
-#if 0
- RGWUserCompleteInfo uci;
-
- try {
- decode_json_obj(uci, obj);
- } catch (JSONDecoder::err& e) {
- return -EINVAL;
- }
-
- map<string, bufferlist> *pattrs = NULL;
- if (uci.has_attrs) {
- pattrs = &uci.attrs;
- }
-
- rgw_user uid(entry);
-
- RGWUserInfo old_info;
+ bufferlist bl;
real_time orig_mtime;
- int ret = rgw_get_user_info_by_uid(store, uid, old_info, &objv_tracker, &orig_mtime);
- if (ret < 0 && ret != -ENOENT)
+ RGWObjectCtx obj_ctx(store);
+ int ret = rgw_get_system_obj(store, obj_ctx, store->get_zone_params().otp_pool,
+ entry, bl, &objv_tracker, &orig_mtime, nullptr, nullptr);
+ if (ret < 0 && ret != -ENOENT) {
return ret;
-
- // are we actually going to perform this put, or is it too old?
+ }
if (ret != -ENOENT &&
!check_versions(objv_tracker.read_version, orig_mtime,
objv_tracker.write_version, mtime, sync_mode)) {
return STATUS_NO_APPLY;
}
-
- ret = rgw_store_user_info(store, uci.info, &old_info, &objv_tracker, mtime, false, pattrs);
- if (ret < 0) {
- return ret;
- }
+ store->meta_mgr->operate(this, entry, &objv_tracker, MDLOG_STATUS_WRITE, [&] {
+ return store->set_mfa(entry, devices, true, &objv_tracker);
+ });
return STATUS_APPLIED;
-#endif
}
int remove(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker) override {
return r;
}
- r = rados::cls::otp::OTP::get(ref.ioctx, ref.oid, id, result);
+ r = rados::cls::otp::OTP::get(nullptr, ref.ioctx, ref.oid, id, result);
if (r < 0) {
return r;
}
return r;
}
- r = rados::cls::otp::OTP::get_all(ref.ioctx, ref.oid, result);
+ r = rados::cls::otp::OTP::get_all(nullptr, ref.ioctx, ref.oid, result);
if (r < 0) {
return r;
}
return 0;
}
-int RGWRados::set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>& entries, bool reset_obj)
+int RGWRados::set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>& entries,
+ bool reset_obj, RGWObjVersionTracker *objv_tracker)
{
rgw_raw_obj obj(get_zone_params().otp_pool, oid);
rgw_rados_ref ref;
if (r < 0) {
return r;
}
+ RGWObjVersionTracker ot;
+
+ if (objv_tracker) {
+ ot = *objv_tracker;
+ }
+
+ if (ot.write_version.tag.empty()) {
+ if (ot.read_version.tag.empty()) {
+ ot.generate_new_write_ver(cct);
+ } else {
+ ot.write_version = ot.read_version;
+ ot.write_version.ver++;
+ }
+ }
+
librados::ObjectWriteOperation op;
if (reset_obj) {
op.set_op_flags2(LIBRADOS_OP_FLAG_FAILOK);
op.create(false);
}
+ ot.prepare_op_for_write(&op);
rados::cls::otp::OTP::set(&op, entries);
r = ref.ioctx.operate(ref.oid, &op);
if (r < 0) {
return 0;
}
-int RGWRados::list_mfa(const string& oid, list<rados::cls::otp::otp_info_t> *result)
+int RGWRados::list_mfa(const string& oid, list<rados::cls::otp::otp_info_t> *result,
+ RGWObjVersionTracker *objv_tracker, ceph::real_time *pmtime)
{
rgw_raw_obj obj(get_zone_params().otp_pool, oid);
rgw_rados_ref ref;
if (r < 0) {
return r;
}
- r = rados::cls::otp::OTP::get_all(ref.ioctx, ref.oid, result);
+ librados::ObjectReadOperation op;
+ struct timespec mtime_ts;
+ if (pmtime) {
+ op.stat2(nullptr, &mtime_ts, nullptr);
+ }
+ objv_tracker->prepare_op_for_read(&op);
+ r = rados::cls::otp::OTP::get_all(&op, ref.ioctx, ref.oid, result);
if (r < 0) {
return r;
}
+ if (pmtime) {
+ *pmtime = ceph::real_clock::from_timespec(mtime_ts);
+ }
return 0;
}
int list_mfa(const rgw_user& user, list<rados::cls::otp::otp_info_t> *result);
/* mfa interfaces used by metadata engine */
- int set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>& entries, bool reset_obj);
- int list_mfa(const string& oid, list<rados::cls::otp::otp_info_t> *result);
+ int set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>& entries, bool reset_obj,
+ RGWObjVersionTracker *objv_tracker);
+ int list_mfa(const string& oid, list<rados::cls::otp::otp_info_t> *result,
+ RGWObjVersionTracker *objv_tracker, ceph::real_time *pmtime);
private:
/**
* This is a helper method, it generates a list of bucket index objects with the given