mirror of
https://github.com/ceph/ceph
synced 2025-02-23 11:07:35 +00:00
librbd: added trash_get API method to retrieve image status
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
parent
4b48b9fe68
commit
4939ff707b
@ -255,8 +255,14 @@ CEPH_RBD_API int rbd_remove(rados_ioctx_t io, const char *name);
|
||||
CEPH_RBD_API int rbd_remove_with_progress(rados_ioctx_t io, const char *name,
|
||||
librbd_progress_fn_t cb,
|
||||
void *cbdata);
|
||||
CEPH_RBD_API int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname,
|
||||
const char *destname);
|
||||
|
||||
CEPH_RBD_API int rbd_trash_move(rados_ioctx_t io, const char *name,
|
||||
uint64_t delay);
|
||||
CEPH_RBD_API int rbd_trash_get(rados_ioctx_t io, const char *id,
|
||||
rbd_trash_image_info_t *info);
|
||||
CEPH_RBD_API void rbd_trash_get_cleanup(rbd_trash_image_info_t *info);
|
||||
CEPH_RBD_API int rbd_trash_list(rados_ioctx_t io,
|
||||
rbd_trash_image_info_t *trash_entries,
|
||||
size_t *num_entries);
|
||||
@ -268,8 +274,6 @@ CEPH_RBD_API int rbd_trash_remove_with_progress(rados_ioctx_t io, const char *id
|
||||
void *cbdata);
|
||||
CEPH_RBD_API int rbd_trash_restore(rados_ioctx_t io, const char *id,
|
||||
const char *name);
|
||||
CEPH_RBD_API int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname,
|
||||
const char *destname);
|
||||
|
||||
/* pool mirroring */
|
||||
CEPH_RBD_API int rbd_mirror_mode_get(rados_ioctx_t io_ctx,
|
||||
|
@ -158,15 +158,16 @@ public:
|
||||
IoCtx& c_ioctx, const char *c_name, ImageOptions& opts);
|
||||
int remove(IoCtx& io_ctx, const char *name);
|
||||
int remove_with_progress(IoCtx& io_ctx, const char *name, ProgressContext& pctx);
|
||||
int rename(IoCtx& src_io_ctx, const char *srcname, const char *destname);
|
||||
|
||||
int trash_move(IoCtx &io_ctx, const char *name, uint64_t delay);
|
||||
int trash_get(IoCtx &io_ctx, const char *id, trash_image_info_t *info);
|
||||
int trash_list(IoCtx &io_ctx, std::vector<trash_image_info_t> &entries);
|
||||
int trash_remove(IoCtx &io_ctx, const char *image_id, bool force);
|
||||
int trash_remove_with_progress(IoCtx &io_ctx, const char *image_id, bool force,
|
||||
ProgressContext &pctx);
|
||||
int trash_remove_with_progress(IoCtx &io_ctx, const char *image_id,
|
||||
bool force, ProgressContext &pctx);
|
||||
int trash_restore(IoCtx &io_ctx, const char *id, const char *name);
|
||||
|
||||
int rename(IoCtx& src_io_ctx, const char *srcname, const char *destname);
|
||||
|
||||
// RBD pool mirroring support functions
|
||||
int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode);
|
||||
int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode);
|
||||
|
@ -1433,6 +1433,28 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trash_get(IoCtx &io_ctx, const std::string &id,
|
||||
trash_image_info_t *info) {
|
||||
CephContext *cct((CephContext *)io_ctx.cct());
|
||||
ldout(cct, 20) << __func__ << " " << &io_ctx << dendl;
|
||||
|
||||
cls::rbd::TrashImageSpec spec;
|
||||
int r = cls_client::trash_get(&io_ctx, id, &spec);
|
||||
if (r == -ENOENT) {
|
||||
return r;
|
||||
} else if (r < 0) {
|
||||
lderr(cct) << "error retrieving trash entry: " << cpp_strerror(r)
|
||||
<< dendl;
|
||||
return r;
|
||||
}
|
||||
|
||||
rbd_trash_image_source_t source = static_cast<rbd_trash_image_source_t>(
|
||||
spec.source);
|
||||
*info = trash_image_info_t{id, spec.name, source, spec.deletion_time.sec(),
|
||||
spec.deferment_end_time.sec()};
|
||||
return 0;
|
||||
}
|
||||
|
||||
int trash_list(IoCtx &io_ctx, vector<trash_image_info_t> &entries) {
|
||||
CephContext *cct((CephContext *)io_ctx.cct());
|
||||
ldout(cct, 20) << "trash_list " << &io_ctx << dendl;
|
||||
|
@ -143,8 +143,10 @@ namespace librbd {
|
||||
int remove(librados::IoCtx& io_ctx, const std::string &image_name,
|
||||
const std::string &image_id, ProgressContext& prog_ctx,
|
||||
bool force=false, bool from_trash_remove=false);
|
||||
|
||||
int trash_move(librados::IoCtx &io_ctx, rbd_trash_image_source_t source,
|
||||
const std::string &image_name, uint64_t delay);
|
||||
int trash_get(IoCtx &io_ctx, const std::string &id, trash_image_info_t *info);
|
||||
int trash_list(librados::IoCtx &io_ctx,
|
||||
std::vector<trash_image_info_t> &entries);
|
||||
int trash_remove(librados::IoCtx &io_ctx, const std::string &image_id,
|
||||
|
@ -184,6 +184,15 @@ void mirror_image_status_cpp_to_c(const librbd::mirror_image_status_t &cpp_statu
|
||||
c_status->up = cpp_status.up;
|
||||
}
|
||||
|
||||
void trash_image_info_cpp_to_c(const librbd::trash_image_info_t &cpp_info,
|
||||
rbd_trash_image_info_t *c_info) {
|
||||
c_info->id = strdup(cpp_info.id.c_str());
|
||||
c_info->name = strdup(cpp_info.name.c_str());
|
||||
c_info->source = cpp_info.source;
|
||||
c_info->deletion_time = cpp_info.deletion_time;
|
||||
c_info->deferment_end_time = cpp_info.deferment_end_time;
|
||||
}
|
||||
|
||||
struct C_MirrorImageGetInfo : public Context {
|
||||
rbd_mirror_image_info_t *mirror_image_info;
|
||||
Context *on_finish;
|
||||
@ -551,6 +560,10 @@ namespace librbd {
|
||||
return r;
|
||||
}
|
||||
|
||||
int RBD::trash_get(IoCtx &io_ctx, const char *id, trash_image_info_t *info) {
|
||||
return librbd::trash_get(io_ctx, id, info);
|
||||
}
|
||||
|
||||
int RBD::trash_list(IoCtx &io_ctx, vector<trash_image_info_t> &entries) {
|
||||
TracepointProvider::initialize<tracepoint_traits>(get_cct(io_ctx));
|
||||
tracepoint(librbd, trash_list_enter,
|
||||
@ -2295,6 +2308,26 @@ extern "C" int rbd_trash_move(rados_ioctx_t p, const char *name,
|
||||
return r;
|
||||
}
|
||||
|
||||
extern "C" int rbd_trash_get(rados_ioctx_t io, const char *id,
|
||||
rbd_trash_image_info_t *info) {
|
||||
librados::IoCtx io_ctx;
|
||||
librados::IoCtx::from_rados_ioctx_t(io, io_ctx);
|
||||
|
||||
librbd::trash_image_info_t cpp_info;
|
||||
int r = librbd::trash_get(io_ctx, id, &cpp_info);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
|
||||
trash_image_info_cpp_to_c(cpp_info, info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void rbd_trash_get_cleanup(rbd_trash_image_info_t *info) {
|
||||
free(info->id);
|
||||
free(info->name);
|
||||
}
|
||||
|
||||
extern "C" int rbd_trash_list(rados_ioctx_t p, rbd_trash_image_info_t *entries,
|
||||
size_t *num_entries) {
|
||||
librados::IoCtx io_ctx;
|
||||
@ -2318,12 +2351,7 @@ extern "C" int rbd_trash_list(rados_ioctx_t p, rbd_trash_image_info_t *entries,
|
||||
|
||||
int i=0;
|
||||
for (const auto &entry : cpp_entries) {
|
||||
entries[i].id = strdup(entry.id.c_str());
|
||||
entries[i].name = strdup(entry.name.c_str());
|
||||
entries[i].source = entry.source;
|
||||
entries[i].deletion_time = entry.deletion_time;
|
||||
entries[i].deferment_end_time = entry.deferment_end_time;
|
||||
i++;
|
||||
trash_image_info_cpp_to_c(entry, &entries[i++]);
|
||||
}
|
||||
*num_entries = cpp_entries.size();
|
||||
|
||||
@ -2333,8 +2361,7 @@ extern "C" int rbd_trash_list(rados_ioctx_t p, rbd_trash_image_info_t *entries,
|
||||
extern "C" void rbd_trash_list_cleanup(rbd_trash_image_info_t *entries,
|
||||
size_t num_entries) {
|
||||
for (size_t i=0; i < num_entries; i++) {
|
||||
free(entries[i].id);
|
||||
free(entries[i].name);
|
||||
rbd_trash_get_cleanup(&entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,9 @@ cdef extern from "rbd/librbd.h" nogil:
|
||||
const char *destname)
|
||||
|
||||
int rbd_trash_move(rados_ioctx_t io, const char *name, uint64_t delay)
|
||||
int rbd_trash_get(rados_ioctx_t io, const char *id,
|
||||
rbd_trash_image_info_t *info)
|
||||
void rbd_trash_get_cleanup(rbd_trash_image_info_t *info)
|
||||
int rbd_trash_list(rados_ioctx_t io, rbd_trash_image_info_t *trash_entries,
|
||||
size_t *num_entries)
|
||||
void rbd_trash_list_cleanup(rbd_trash_image_info_t *trash_entries,
|
||||
@ -920,6 +923,49 @@ class RBD(object):
|
||||
if ret != 0:
|
||||
raise make_ex(ret, 'error deleting image from trash')
|
||||
|
||||
def trash_get(self, ioctx, image_id):
|
||||
"""
|
||||
Retrieve RBD image info from trash
|
||||
:param ioctx: determines which RADOS pool the image is in
|
||||
:type ioctx: :class:`rados.Ioctx`
|
||||
:param image_id: the id of the image to restore
|
||||
:type image_id: str
|
||||
:returns: dict - contains the following keys:
|
||||
|
||||
* ``id`` (str) - image id
|
||||
|
||||
* ``name`` (str) - image name
|
||||
|
||||
* ``source`` (str) - source of deletion
|
||||
|
||||
* ``deletion_time`` (datetime) - time of deletion
|
||||
|
||||
* ``deferment_end_time`` (datetime) - time that an image is allowed
|
||||
to be removed from trash
|
||||
|
||||
:raises: :class:`ImageNotFound`
|
||||
"""
|
||||
image_id = cstr(image_id, 'image_id')
|
||||
cdef:
|
||||
rados_ioctx_t _ioctx = convert_ioctx(ioctx)
|
||||
char *_image_id = image_id
|
||||
rbd_trash_image_info_t c_info
|
||||
with nogil:
|
||||
ret = rbd_trash_get(_ioctx, _image_id, &c_info)
|
||||
if ret != 0:
|
||||
raise make_ex(ret, 'error restoring image from trash')
|
||||
|
||||
__source_string = ['USER', 'MIRRORING']
|
||||
info = {
|
||||
'id' : decode_cstr(c_info.id),
|
||||
'name' : decode_cstr(c_info.name),
|
||||
'source' : __source_string[c_info.source],
|
||||
'deletion_time' : datetime.fromtimestamp(c_info.deletion_time),
|
||||
'deferment_end_time' : datetime.fromtimestamp(c_info.deferment_end_time)
|
||||
}
|
||||
rbd_trash_get_cleanup(&c_info)
|
||||
return info
|
||||
|
||||
def trash_list(self, ioctx):
|
||||
"""
|
||||
Lists all entries from trash.
|
||||
|
@ -5738,6 +5738,11 @@ TEST_F(TestLibRBD, TestTrashMoveAndPurge) {
|
||||
ASSERT_TRUE(image != name);
|
||||
}
|
||||
|
||||
librbd::trash_image_info_t info;
|
||||
ASSERT_EQ(-ENOENT, rbd.trash_get(ioctx, "dummy image id", &info));
|
||||
ASSERT_EQ(0, rbd.trash_get(ioctx, image_id.c_str(), &info));
|
||||
ASSERT_EQ(image_id, info.id);
|
||||
|
||||
std::vector<librbd::trash_image_info_t> entries;
|
||||
ASSERT_EQ(0, rbd.trash_list(ioctx, entries));
|
||||
ASSERT_FALSE(entries.empty());
|
||||
|
@ -1501,6 +1501,21 @@ class TestTrash(object):
|
||||
RBD().trash_move(ioctx, image_name, 0)
|
||||
RBD().trash_remove(ioctx, image_id)
|
||||
|
||||
def test_get(self):
|
||||
create_image()
|
||||
with Image(ioctx, image_name) as image:
|
||||
image_id = image.id()
|
||||
|
||||
RBD().trash_move(ioctx, image_name, 1000)
|
||||
|
||||
info = RBD().trash_get(ioctx, image_id)
|
||||
eq(image_id, info['id'])
|
||||
eq(image_name, info['name'])
|
||||
eq('USER', info['source'])
|
||||
assert(info['deferment_end_time'] > info['deletion_time'])
|
||||
|
||||
RBD().trash_remove(ioctx, image_id, True)
|
||||
|
||||
def test_list(self):
|
||||
create_image()
|
||||
with Image(ioctx, image_name) as image:
|
||||
|
Loading…
Reference in New Issue
Block a user