Skip to content

Commit

Permalink
librados: add get_inconsistent_snapsets() API
Browse files Browse the repository at this point in the history
Signed-off-by: Kefu Chai <kchai@redhat.com>
  • Loading branch information
tchaikov committed Jan 13, 2016
1 parent b09fd3b commit 5a6f9f1
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 16 deletions.
18 changes: 18 additions & 0 deletions src/include/rados/librados.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,24 @@ namespace librados
AioCompletion *c,
std::vector<inconsistent_obj_t>* objects,
uint32_t* interval);
/**
* List the inconsistent snapsets found in a given PG by last scrub
*
* @param pg the placement group returned by @c pg_list()
* @param start_after the first returned @c objects
* @param max_return the max number of the returned @c objects
* @param c what to do when the operation is complete and safe
* @param snapsets [out] the objects where inconsistencies are found
* @param interval [in,out] an epoch indicating current interval
* @returns if a non-zero @c interval is specified, will return -EAGAIN i
* the current interval begin epoch is different.
*/
int get_inconsistent_snapsets(const PlacementGroup& pg,
const object_id_t &start_after,
unsigned max_return,
AioCompletion *c,
std::vector<inconsistent_snapset_t>* snapset,
uint32_t* interval);

/// get/wait for the most recent osdmap
int wait_for_latest_osdmap();
Expand Down
19 changes: 19 additions & 0 deletions src/librados/IoCtxImpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,25 @@ int librados::IoCtxImpl::get_inconsistent_objects(const pg_t& pg,
return 0;
}

int librados::IoCtxImpl::get_inconsistent_snapsets(const pg_t& pg,
const librados::object_id_t& start_after,
uint64_t max_to_get,
AioCompletionImpl *c,
std::vector<inconsistent_snapset_t>* snapsets,
uint32_t* interval)
{
Context *onack = new C_aio_Ack(c);
c->is_read = true;
c->io = this;

::ObjectOperation op;
op.scrub_ls(start_after, max_to_get, snapsets, interval, nullptr);
object_locator_t oloc{poolid, pg.ps()};
c->tid = objecter->pg_read(oloc.hash, oloc, op, nullptr, CEPH_OSD_FLAG_PGOP, onack,
nullptr, nullptr);
return 0;
}

int librados::IoCtxImpl::tmap_update(const object_t& oid, bufferlist& cmdbl)
{
::ObjectOperation wr;
Expand Down
7 changes: 7 additions & 0 deletions src/librados/IoCtxImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,13 @@ struct librados::IoCtxImpl {
std::vector<inconsistent_obj_t>* objects,
uint32_t* interval);

int get_inconsistent_snapsets(const pg_t& pg,
const librados::object_id_t& start_after,
uint64_t max_to_get,
AioCompletionImpl *c,
std::vector<inconsistent_snapset_t>* snapsets,
uint32_t* interval);

void set_sync_op_version(version_t ver);
int watch(const object_t& oid, uint64_t *cookie, librados::WatchCtx *ctx,
librados::WatchCtx2 *ctx2);
Expand Down
22 changes: 22 additions & 0 deletions src/librados/librados.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2365,6 +2365,28 @@ int librados::Rados::get_inconsistent_objects(const PlacementGroup& pg,
interval);
}

int librados::Rados::get_inconsistent_snapsets(const PlacementGroup& pg,
const object_id_t &start_after,
unsigned max_return,
AioCompletion *c,
std::vector<inconsistent_snapset_t>* snapsets,
uint32_t* interval)
{
IoCtx ioctx;
const pg_t pgid = pg.impl->pgid;
int r = ioctx_create2(pgid.pool(), ioctx);
if (r < 0) {
return r;
}

return ioctx.io_ctx_impl->get_inconsistent_snapsets(pgid,
start_after,
max_return,
c->pc,
snapsets,
interval);
}

int librados::Rados::wait_for_latest_osdmap()
{
return client->wait_for_latest_osdmap();
Expand Down
81 changes: 65 additions & 16 deletions src/osdc/Objecter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5012,13 +5012,18 @@ namespace {
struct C_ObjectOperation_scrub_ls : public Context {
bufferlist bl;
uint32_t *interval;
std::vector<inconsistent_obj_t> *objects;
std::vector<inconsistent_obj_t> *objects = nullptr;
std::vector<inconsistent_snapset_t> *snapsets = nullptr;
int *rval;

C_ObjectOperation_scrub_ls(uint32_t *interval,
std::vector<inconsistent_obj_t> *objects,
int *rval)
: interval(interval), objects(objects), rval(rval) {}
C_ObjectOperation_scrub_ls(uint32_t *interval,
std::vector<inconsistent_snapset_t> *snapsets,
int *rval)
: interval(interval), snapsets(snapsets), rval(rval) {}
void finish(int r) override {
if (r < 0 && r != -EAGAIN)
return;
Expand Down Expand Up @@ -5078,16 +5083,37 @@ namespace {
DECODE_FINISH(bl);
}

static void decode(std::vector<inconsistent_t>& objects,
bufferlist::iterator& bl)
static void decode(librados::inconsistent_snapset_t& inc,
ceph::buffer::list::iterator& bl)
{
DECODE_START(1, bl);
hobject_t hoid;
::decode(hoid, bl);
inc.object = { hoid.oid.name,
hoid.nspace,
hoid.get_key(),
hoid.snap };
::decode(inc.errors, bl);
if (inc.errors & inc.CLONE_MISSING) {
::decode(inc.clones, bl);
::decode(inc.missing, bl);
}
DECODE_FINISH(bl);
}

template <typename T>
static void decode(std::vector<T>& items, bufferlist::iterator& bl)
{
static_assert(std::is_same<T, librados::inconsistent_obj_t>::value ||
std::is_same<T, librados::inconsistent_snapset_t>::value,
"not supported inconsistent type");
vector<bufferlist> vals;
::decode(vals, bl);
for (auto val : vals) {
auto ival = val.begin();
inconsistent_t inc;
T inc;
decode(inc, ival);
objects.emplace_back(inc);
items.emplace_back(inc);
}
}

Expand All @@ -5099,9 +5125,30 @@ namespace {
if (r == -EAGAIN) {
return;
}
decode(*objects, p);
if (objects)
return decode(*objects, p);
else
return decode(*snapsets, p);
}
};

template <typename T>
void do_scrub_ls(::ObjectOperation *op,
const ::ObjectOperation::scrub_ls_arg_t& arg,
std::vector<T> *items,
uint32_t *interval,
int *rval)
{
OSDOp& osd_op = op->add_op(CEPH_OSD_OP_SCRUBLS);
op->flags |= CEPH_OSD_FLAG_PGOP;
assert(interval);
arg.encode(osd_op.indata);
unsigned p = op->ops.size() - 1;
auto *h = new C_ObjectOperation_scrub_ls{interval, items, rval};
op->out_handler[p] = h;
op->out_bl[p] = &h->bl;
op->out_rval[p] = rval;
}
}

void ::ObjectOperation::scrub_ls_arg_t::encode(bufferlist& bl) const
Expand Down Expand Up @@ -5134,14 +5181,16 @@ void ::ObjectOperation::scrub_ls(const librados::object_id_t& start_after,
uint32_t *interval,
int *rval)
{
OSDOp& osd_op = add_op(CEPH_OSD_OP_SCRUBLS);
flags |= CEPH_OSD_FLAG_PGOP;
assert(interval);
scrub_ls_arg_t arg = {*interval, start_after, max_to_get};
arg.encode(osd_op.indata);
unsigned p = ops.size() - 1;
auto *h = new C_ObjectOperation_scrub_ls{interval, objects, rval};
out_handler[p] = h;
out_bl[p] = &h->bl;
out_rval[p] = rval;
scrub_ls_arg_t arg = {*interval, 0, start_after, max_to_get};
do_scrub_ls(this, arg, objects, interval, rval);
}

void ::ObjectOperation::scrub_ls(const librados::object_id_t& start_after,
uint64_t max_to_get,
std::vector<librados::inconsistent_snapset_t> *snapsets,
uint32_t *interval,
int *rval)
{
scrub_ls_arg_t arg = {*interval, 1, start_after, max_to_get};
do_scrub_ls(this, arg, snapsets, interval, rval);
}
5 changes: 5 additions & 0 deletions src/osdc/Objecter.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ struct ObjectOperation {
std::vector<librados::inconsistent_obj_t> *objects,
uint32_t *interval,
int *rval);
void scrub_ls(const librados::object_id_t& start_after,
uint64_t max_to_get,
std::vector<librados::inconsistent_snapset_t> *objects,
uint32_t *interval,
int *rval);

void create(bool excl) {
OSDOp& o = add_op(CEPH_OSD_OP_CREATE);
Expand Down

0 comments on commit 5a6f9f1

Please sign in to comment.