Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

librbd: add create timestamp metadata for image #15757

Merged
merged 5 commits into from
Jun 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/cls/rbd/cls_rbd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -223,19 +223,23 @@ int create(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
bufferlist featuresbl;
bufferlist object_prefixbl;
bufferlist snap_seqbl;
bufferlist create_timestampbl;
uint64_t snap_seq = 0;
utime_t create_timestamp = ceph_clock_now();
::encode(size, sizebl);
::encode(order, orderbl);
::encode(features, featuresbl);
::encode(object_prefix, object_prefixbl);
::encode(snap_seq, snap_seqbl);
::encode(create_timestamp, create_timestampbl);

map<string, bufferlist> omap_vals;
omap_vals["size"] = sizebl;
omap_vals["order"] = orderbl;
omap_vals["features"] = featuresbl;
omap_vals["object_prefix"] = object_prefixbl;
omap_vals["snap_seq"] = snap_seqbl;
omap_vals["create_timestamp"] = create_timestampbl;

if (features & RBD_FEATURE_DATA_POOL) {
if (data_pool_id == -1) {
Expand Down Expand Up @@ -769,6 +773,32 @@ int set_stripe_unit_count(cls_method_context_t hctx, bufferlist *in, bufferlist
return 0;
}

int get_create_timestamp(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
{
CLS_LOG(20, "get_create_timestamp");

utime_t timestamp;
bufferlist bl;
int r = cls_cxx_map_get_val(hctx, "create_timestamp", &bl);
if (r < 0) {
if (r != -ENOENT) {
CLS_ERR("error reading create_timestamp: %s", cpp_strerror(r).c_str());
return r;
}
} else {
try {
bufferlist::iterator it = bl.begin();
::decode(timestamp, it);
} catch (const buffer::error &err) {
CLS_ERR("could not decode create_timestamp");
return -EIO;
}
}

::encode(timestamp, *out);
return 0;
}

/**
* get the image flags
*
Expand Down Expand Up @@ -5079,6 +5109,7 @@ CLS_INIT(rbd)
cls_method_handle_t h_set_protection_status;
cls_method_handle_t h_get_stripe_unit_count;
cls_method_handle_t h_set_stripe_unit_count;
cls_method_handle_t h_get_create_timestamp;
cls_method_handle_t h_get_flags;
cls_method_handle_t h_set_flags;
cls_method_handle_t h_remove_parent;
Expand Down Expand Up @@ -5227,6 +5258,9 @@ CLS_INIT(rbd)
cls_register_cxx_method(h_class, "set_stripe_unit_count",
CLS_METHOD_RD | CLS_METHOD_WR,
set_stripe_unit_count, &h_set_stripe_unit_count);
cls_register_cxx_method(h_class, "get_create_timestamp",
CLS_METHOD_RD,
get_create_timestamp, &h_get_create_timestamp);
cls_register_cxx_method(h_class, "get_flags",
CLS_METHOD_RD,
get_flags, &h_get_flags);
Expand Down
33 changes: 33 additions & 0 deletions src/cls/rbd/cls_rbd_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,39 @@ namespace librbd {
return ioctx->operate(oid, &op);
}

void get_create_timestamp_start(librados::ObjectReadOperation *op) {
bufferlist empty_bl;
op->exec("rbd", "get_create_timestamp", empty_bl);
}

int get_create_timestamp_finish(bufferlist::iterator *it,
utime_t *timestamp) {
assert(timestamp);

try {
::decode(*timestamp, *it);
} catch (const buffer::error &err) {
return -EBADMSG;
}
return 0;
}

int get_create_timestamp(librados::IoCtx *ioctx, const std::string &oid,
utime_t *timestamp)
{
librados::ObjectReadOperation op;
get_create_timestamp_start(&op);

bufferlist out_bl;
int r = ioctx->operate(oid, &op, &out_bl);
if (r < 0) {
return r;
}

bufferlist::iterator it = out_bl.begin();
return get_create_timestamp_finish(&it, timestamp);
}

/************************ rbd_id object methods ************************/

void get_id_start(librados::ObjectReadOperation *op) {
Expand Down
5 changes: 5 additions & 0 deletions src/cls/rbd/cls_rbd_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ namespace librbd {
uint64_t stripe_unit, uint64_t stripe_count);
int set_stripe_unit_count(librados::IoCtx *ioctx, const std::string &oid,
uint64_t stripe_unit, uint64_t stripe_count);
void get_create_timestamp_start(librados::ObjectReadOperation *op);
int get_create_timestamp_finish(bufferlist::iterator *it,
utime_t *timestamp);
int get_create_timestamp(librados::IoCtx *ioctx, const std::string &oid,
utime_t *timestamp);
int metadata_list(librados::IoCtx *ioctx, const std::string &oid,
const std::string &start, uint64_t max_return,
map<string, bufferlist> *pairs);
Expand Down
4 changes: 4 additions & 0 deletions src/include/rbd/librbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,10 @@ CEPH_RBD_API int rbd_update_features(rbd_image_t image, uint64_t features,
CEPH_RBD_API int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit);
CEPH_RBD_API int rbd_get_stripe_count(rbd_image_t image,
uint64_t *stripe_count);

CEPH_RBD_API int rbd_get_create_timestamp(rbd_image_t image,
struct timespec *timestamp);

CEPH_RBD_API int rbd_get_overlap(rbd_image_t image, uint64_t *overlap);
CEPH_RBD_API int rbd_get_id(rbd_image_t image, char *id, size_t id_len);
CEPH_RBD_API int rbd_get_block_name_prefix(rbd_image_t image,
Expand Down
2 changes: 2 additions & 0 deletions src/include/rbd/librbd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ class CEPH_RBD_API Image
uint64_t get_stripe_unit() const;
uint64_t get_stripe_count() const;

int get_create_timestamp(struct timespec *timestamp);

int flatten();
int flatten_with_progress(ProgressContext &prog_ctx);
/**
Expand Down
5 changes: 5 additions & 0 deletions src/librbd/ImageCtx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,11 @@ struct C_InvalidateCache : public Context {
return stripe_count * (1ull << order);
}

utime_t ImageCtx::get_create_timestamp() const
{
return create_timestamp;
}

int ImageCtx::is_snap_protected(snap_t in_snap_id,
bool *is_protected) const
{
Expand Down
2 changes: 2 additions & 0 deletions src/librbd/ImageCtx.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ namespace librbd {
cls::rbd::GroupSpec group_spec;
uint64_t stripe_unit, stripe_count;
uint64_t flags;
utime_t create_timestamp;

file_layout_t layout;

Expand Down Expand Up @@ -254,6 +255,7 @@ namespace librbd {
uint64_t get_stripe_unit() const;
uint64_t get_stripe_count() const;
uint64_t get_stripe_period() const;
utime_t get_create_timestamp() const;

void add_snap(cls::rbd::SnapshotNamespace in_snap_namespace,
std::string in_snap_name,
Expand Down
39 changes: 39 additions & 0 deletions src/librbd/image/OpenRequest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,45 @@ Context *OpenRequest<I>::handle_v2_get_stripe_unit_count(int *result) {
return nullptr;
}

send_v2_get_create_timestamp();
return nullptr;
}

template <typename I>
void OpenRequest<I>::send_v2_get_create_timestamp() {
CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << dendl;

librados::ObjectReadOperation op;
cls_client::get_create_timestamp_start(&op);

using klass = OpenRequest<I>;
librados::AioCompletion *comp = create_rados_callback<
klass, &klass::handle_v2_get_create_timestamp>(this);
m_out_bl.clear();
m_image_ctx->md_ctx.aio_operate(m_image_ctx->header_oid, comp, &op,
&m_out_bl);
comp->release();
}

template <typename I>
Context *OpenRequest<I>::handle_v2_get_create_timestamp(int *result) {
CephContext *cct = m_image_ctx->cct;
ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl;

if (*result == 0) {
bufferlist::iterator it = m_out_bl.begin();
*result = cls_client::get_create_timestamp_finish(&it,
&m_image_ctx->create_timestamp);
}
if (*result < 0 && *result != -EOPNOTSUPP) {
lderr(cct) << "failed to retrieve create_timestamp: "
<< cpp_strerror(*result)
<< dendl;
send_close_image(*result);
return nullptr;
}

send_v2_get_data_pool();
return nullptr;
}
Expand Down
6 changes: 6 additions & 0 deletions src/librbd/image/OpenRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class OpenRequest {
* V2_GET_STRIPE_UNIT_COUNT |
* | |
* v |
* V2_GET_CREATE_TIMESTAMP |
* | |
* v |
* V2_GET_DATA_POOL |
* | |
* v |
Expand Down Expand Up @@ -105,6 +108,9 @@ class OpenRequest {
void send_v2_get_stripe_unit_count();
Context *handle_v2_get_stripe_unit_count(int *result);

void send_v2_get_create_timestamp();
Context *handle_v2_get_create_timestamp(int *result);

void send_v2_get_data_pool();
Context *handle_v2_get_data_pool(int *result);

Expand Down
23 changes: 23 additions & 0 deletions src/librbd/librbd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,17 @@ namespace librbd {
return stripe_count;
}

int Image::get_create_timestamp(struct timespec *timestamp)
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, get_create_timestamp_enter, ictx, ictx->name.c_str(),
ictx->read_only);
utime_t time = ictx->get_create_timestamp();
time.to_timespec(timestamp);
tracepoint(librbd, get_create_timestamp_exit, 0, timestamp);
return 0;
}

int Image::overlap(uint64_t *overlap)
{
ImageCtx *ictx = (ImageCtx *)ctx;
Expand Down Expand Up @@ -2817,6 +2828,18 @@ extern "C" int rbd_get_stripe_count(rbd_image_t image, uint64_t *stripe_count)
return 0;
}

extern "C" int rbd_get_create_timestamp(rbd_image_t image,
struct timespec *timestamp)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, get_create_timestamp_enter, ictx, ictx->name.c_str(),
ictx->read_only);
utime_t time = ictx->get_create_timestamp();
time.to_timespec(timestamp);
tracepoint(librbd, get_create_timestamp_exit, 0, timestamp);
return 0;
}

extern "C" int rbd_get_overlap(rbd_image_t image, uint64_t *overlap)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
Expand Down
13 changes: 13 additions & 0 deletions src/pybind/rbd/rbd.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ cdef extern from "rbd/librbd.h" nogil:
uint8_t enabled)
int rbd_get_stripe_unit(rbd_image_t image, uint64_t *stripe_unit)
int rbd_get_stripe_count(rbd_image_t image, uint64_t *stripe_count)
int rbd_get_create_timestamp(rbd_image_t image, timespec *timestamp)
int rbd_get_overlap(rbd_image_t image, uint64_t *overlap)
int rbd_get_id(rbd_image_t image, char *id, size_t id_len)
int rbd_get_block_name_prefix(rbd_image_t image, char *prefix,
Expand Down Expand Up @@ -2166,6 +2167,18 @@ written." % (self.name, ret, length))
raise make_ex(ret, 'error getting stripe count for image %s' % (self.name))
return stripe_count

def create_timestamp(self):
"""
Returns the create timestamp for the image.
"""
cdef:
timespec timestamp
with nogil:
ret = rbd_get_create_timestamp(self.image, &timestamp)
if ret != 0:
raise make_ex(ret, 'error getting create timestamp for image: %s' % (self.name))
return datetime.fromtimestamp(timestamp.tv_sec)

def flatten(self):
"""
Flatten clone image (copy all blocks from parent to child)
Expand Down
Loading