rgw: tie otp meta get/put to meta log, objv_tracker

still need to have the radosgw-admin mfa tools to go through meta
instrumentation.

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
Yehuda Sadeh 2017-11-22 18:14:00 -08:00
parent 45ee591d14
commit fbe7c01e00
6 changed files with 104 additions and 53 deletions

View File

@ -96,8 +96,13 @@ namespace rados {
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;
@ -105,11 +110,16 @@ namespace rados {
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();
@ -124,12 +134,13 @@ namespace rados {
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;
}
@ -141,9 +152,9 @@ namespace rados {
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

View File

@ -20,11 +20,14 @@ namespace rados {
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);

View File

@ -5,6 +5,7 @@
#define CEPH_RGW_METADATA_H
#include <string>
#include <utility>
#include <boost/optional.hpp>
#include "include/types.h"
@ -342,6 +343,11 @@ public:
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,
@ -369,4 +375,31 @@ public:
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

View File

@ -16,6 +16,7 @@
#include "include/types.h"
#include "rgw_common.h"
#include "rgw_tools.h"
#define dout_subsys ceph_subsys_rgw
@ -48,11 +49,10 @@ public:
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;
@ -68,49 +68,24 @@ public:
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 {

View File

@ -14237,7 +14237,7 @@ int RGWRados::get_mfa(const rgw_user& user, const string& id, rados::cls::otp::o
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;
}
@ -14254,7 +14254,7 @@ int RGWRados::list_mfa(const rgw_user& user, list<rados::cls::otp::otp_info_t> *
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;
}
@ -14262,7 +14262,8 @@ int RGWRados::list_mfa(const rgw_user& user, list<rados::cls::otp::otp_info_t> *
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;
@ -14270,6 +14271,21 @@ int RGWRados::set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>
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) {
@ -14277,6 +14293,7 @@ int RGWRados::set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>
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) {
@ -14287,7 +14304,8 @@ int RGWRados::set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>
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;
@ -14295,10 +14313,19 @@ int RGWRados::list_mfa(const string& oid, list<rados::cls::otp::otp_info_t> *res
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;
}

View File

@ -3724,8 +3724,10 @@ public:
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