From: Jason Dillaman Date: Tue, 3 Feb 2015 04:24:09 +0000 (-0500) Subject: librbd: added get_flags API methods X-Git-Tag: v0.93~102^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=706a6552cfc3557bfd789d51fa0b796a0ed6d652;p=ceph.git librbd: added get_flags API methods Exposed the RBD image flags bitmask through the API via new methods in the C/C++/Python RBD APIs. Signed-off-by: Jason Dillaman --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index b94faff149ff..625d472b5371 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -157,6 +157,7 @@ CEPH_RBD_API int rbd_get_parent_info(rbd_image_t image, char *parent_name, size_t pnamelen, char *parent_snapname, size_t psnapnamelen); +CEPH_RBD_API int rbd_get_flags(rbd_image_t image, uint64_t *flags); /* exclusive lock feature */ CEPH_RBD_API int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner); diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index b6be508a69b3..569fc77db94c 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -117,6 +117,7 @@ public: int size(uint64_t *size); int features(uint64_t *features); int overlap(uint64_t *overlap); + int get_flags(uint64_t *flags); /* exclusive lock feature */ int is_exclusive_lock_owner(bool *is_owner); diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index 398b49b69dbb..9882634108da 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -415,12 +415,12 @@ namespace librbd { } void ImageCtx::add_snap(string in_snap_name, snap_t id, uint64_t in_size, - uint64_t features, - parent_info parent, - uint8_t protection_status) + uint64_t features, parent_info parent, + uint8_t protection_status, uint64_t flags) { snaps.push_back(id); - SnapInfo info(in_snap_name, in_size, features, parent, protection_status); + SnapInfo info(in_snap_name, in_size, features, parent, protection_status, + flags); snap_info.insert(pair(id, info)); snap_ids.insert(pair(in_snap_name, id)); } @@ -452,6 +452,20 @@ namespace librbd { return -ENOENT; } + int ImageCtx::get_flags(librados::snap_t _snap_id, uint64_t *_flags) const + { + if (_snap_id == CEPH_NOSNAP) { + *_flags = flags; + return 0; + } + const SnapInfo *info = get_snap_info(_snap_id); + if (info) { + *_flags = info->flags; + return 0; + } + return -ENOENT; + } + const parent_info* ImageCtx::get_parent_info(snap_t in_snap_id) const { if (in_snap_id == CEPH_NOSNAP) diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index 5dd5b8adbf9f..13a5bfc2fffb 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -151,10 +151,12 @@ namespace librbd { void add_snap(std::string in_snap_name, librados::snap_t id, uint64_t in_size, uint64_t features, - parent_info parent, uint8_t protection_status); + parent_info parent, uint8_t protection_status, + uint64_t flags); uint64_t get_image_size(librados::snap_t in_snap_id) const; int get_features(librados::snap_t in_snap_id, uint64_t *out_features) const; + int get_flags(librados::snap_t in_snap_id, uint64_t *flags) const; const parent_info* get_parent_info(librados::snap_t in_snap_id) const; int64_t get_parent_pool_id(librados::snap_t in_snap_id) const; std::string get_parent_image_id(librados::snap_t in_snap_id) const; diff --git a/src/librbd/SnapInfo.h b/src/librbd/SnapInfo.h index fd973536d872..a3307ff49075 100644 --- a/src/librbd/SnapInfo.h +++ b/src/librbd/SnapInfo.h @@ -18,10 +18,11 @@ namespace librbd { uint64_t features; parent_info parent; uint8_t protection_status; + uint64_t flags; SnapInfo(std::string _name, uint64_t _size, uint64_t _features, - parent_info _parent, uint8_t _protection_status) : - name(_name), size(_size), features(_features), parent(_parent), - protection_status(_protection_status) {} + parent_info _parent, uint8_t _protection_status, uint64_t _flags) + : name(_name), size(_size), features(_features), parent(_parent), + protection_status(_protection_status), flags(_flags) {} }; } diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 285f0551eebe..1d6c914372f4 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1452,6 +1452,18 @@ reprotect_and_return_err: return 0; } + int get_flags(ImageCtx *ictx, uint64_t *flags) + { + int r = ictx_check(ictx); + if (r < 0) { + return r; + } + + RWLock::RLocker l(ictx->md_lock); + RWLock::RLocker l2(ictx->snap_lock); + return ictx->get_flags(ictx->snap_id, flags); + } + int is_exclusive_lock_owner(ImageCtx *ictx, bool *is_owner) { RWLock::RLocker l(ictx->owner_lock); @@ -1851,6 +1863,7 @@ reprotect_and_return_err: vector snap_features; vector snap_parents; vector snap_protection; + vector snap_flags; { int r; RWLock::WLocker l(ictx->snap_lock); @@ -1918,31 +1931,33 @@ reprotect_and_return_err: return -ENOSYS; } - r = cls_client::get_flags(&ictx->md_ctx, ictx->header_oid, - ictx->snap_id, &ictx->flags); + r = cls_client::get_flags(&ictx->md_ctx, ictx->header_oid, + &ictx->flags, new_snapc.snaps, + &snap_flags); if (r == -EOPNOTSUPP || r == -EIO) { // Older OSD doesn't support RBD flags, need to assume the worst ldout(ictx->cct, 10) << "OSD does not support RBD flags" << dendl; - } else if (r == -ENOENT) { - ldout(ictx->cct, 10) << "Image at invalid snapshot" << dendl; - } else if (r < 0 && r != -ENOENT) { - lderr(cct) << "Error reading flags: " << cpp_strerror(r) << dendl; - return r; - } - if (r < 0) { ictx->flags = 0; if ((ictx->features & RBD_FEATURE_OBJECT_MAP) != 0) { ldout(ictx->cct, 10) << "disabling object map optimizations" << dendl; ictx->flags |= RBD_FLAG_OBJECT_MAP_INVALID; } + + vector default_flags(new_snapc.snaps.size(), ictx->flags); + snap_flags.swap(default_flags); + } else if (r == -ENOENT) { + ldout(ictx->cct, 10) << "Image at invalid snapshot" << dendl; + continue; + } else if (r < 0) { + lderr(cct) << "Error reading flags: " << cpp_strerror(r) << dendl; + return r; } r = cls_client::snapshot_list(&(ictx->md_ctx), ictx->header_oid, new_snapc.snaps, &snap_names, &snap_sizes, &snap_features, - &snap_parents, - &snap_protection); + &snap_parents, &snap_protection); // -ENOENT here means we raced with snapshot deletion if (r < 0 && r != -ENOENT) { lderr(ictx->cct) << "snapc = " << new_snapc << dendl; @@ -1975,13 +1990,14 @@ reprotect_and_return_err: ictx->snap_ids.clear(); for (size_t i = 0; i < new_snapc.snaps.size(); ++i) { uint64_t features = ictx->old_format ? 0 : snap_features[i]; + uint64_t flags = ictx->old_format ? 0 : snap_flags[i]; uint8_t protection_status = ictx->old_format ? (uint8_t)RBD_PROTECTION_STATUS_UNPROTECTED : snap_protection[i]; parent_info parent; if (!ictx->old_format) parent = snap_parents[i]; - ictx->add_snap(snap_names[i], new_snapc.snaps[i].val, - snap_sizes[i], features, parent, protection_status); + ictx->add_snap(snap_names[i], new_snapc.snaps[i].val, snap_sizes[i], + features, parent, protection_status, flags); } r = refresh_parent(ictx); diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 9984b4b663da..1e6f790b2da6 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -104,6 +104,7 @@ namespace librbd { int get_overlap(ImageCtx *ictx, uint64_t *overlap); int get_parent_info(ImageCtx *ictx, std::string *parent_pool_name, std::string *parent_name, std::string *parent_snap_name); + int get_flags(ImageCtx *ictx, uint64_t *flags); int is_exclusive_lock_owner(ImageCtx *ictx, bool *is_owner); int remove(librados::IoCtx& io_ctx, const char *imgname, diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index f2d3dd92d405..2d1e56777a39 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -360,6 +360,15 @@ namespace librbd { return r; } + int Image::get_flags(uint64_t *flags) + { + ImageCtx *ictx = (ImageCtx *)ctx; + tracepoint(librbd, get_flags_enter, ictx); + int r = librbd::get_flags(ictx, flags); + tracepoint(librbd, get_flags_exit, ictx, r, *flags); + return r; + } + int Image::is_exclusive_lock_owner(bool *is_owner) { ImageCtx *ictx = (ImageCtx *)ctx; @@ -1175,6 +1184,15 @@ extern "C" int rbd_get_parent_info(rbd_image_t image, return 0; } +extern "C" int rbd_get_flags(rbd_image_t image, uint64_t *flags) +{ + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + tracepoint(librbd, get_flags_enter, ictx); + int r = librbd::get_flags(ictx, flags); + tracepoint(librbd, get_flags_exit, ictx, r, *flags); + return r; +} + extern "C" int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner) { librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; diff --git a/src/pybind/rbd.py b/src/pybind/rbd.py index a91f7c84d8dd..82f5033e41de 100644 --- a/src/pybind/rbd.py +++ b/src/pybind/rbd.py @@ -29,6 +29,8 @@ RBD_FEATURE_LAYERING = 1 RBD_FEATURE_STRIPINGV2 = 2 RBD_FEATURE_EXCLUSIVE_LOCK = 4 +RBD_FLAG_OBJECT_MAP_INVALID = 1 + class Error(Exception): pass @@ -525,7 +527,24 @@ class Image(object): raise make_ex(ret, 'error getting overlap for image' % (self.name)) return overlap.value + def flags(self): + """ + Gets the flags bitmask of the image. + + :returns: int - the flags bitmask of the image + """ + flags = c_uint64() + reg = self.librbd.rbd_get_flags(self.image, byref(flags)) + if (ret != 0): + raise make_ex(ret, 'error getting flags for image' % (self.name)) + return flags.value + def is_exclusive_lock_owner(self): + """ + Gets the status of the image exclusive lock. + + :returns: bool - true if the image is exclusively locked + """ owner = c_int() ret = self.librbd.rbd_is_exclusive_lock_owner(self.image, byref(owner)) if (ret != 0): diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index 985bcf0c408b..84d5902623b0 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -292,6 +292,10 @@ class TestImage(object): info = self.image.stat() check_stat(info, IMG_SIZE, IMG_ORDER) + def test_flags(self): + flags = self.image.flags() + eq(0, flags) + def test_write(self): data = rand_data(256) self.image.write(data, 0) diff --git a/src/tracing/librbd.tp b/src/tracing/librbd.tp index 6b0580ac6a83..bc0b662cc21d 100644 --- a/src/tracing/librbd.tp +++ b/src/tracing/librbd.tp @@ -1393,6 +1393,26 @@ TRACEPOINT_EVENT(librbd, get_old_format_exit, ) ) +TRACEPOINT_EVENT(librbd, get_flags_enter, + TP_ARGS( + void*, imagectx), + TP_FIELDS( + ctf_integer_hex(void*, imagectx, imagectx) + ) +) + +TRACEPOINT_EVENT(librbd, get_flags_exit, + TP_ARGS( + void*, imagectx, + int, retval, + uint64_t, flags), + TP_FIELDS( + ctf_integer_hex(void*, imagectx, imagectx) + ctf_integer(int, retval, retval) + ctf_integer(uint64_t, flags, flags) + ) +) + TRACEPOINT_EVENT(librbd, is_exclusive_lock_owner_enter, TP_ARGS( void*, imagectx),