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);
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);
}
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<snap_t, SnapInfo>(id, info));
snap_ids.insert(pair<string, snap_t>(in_snap_name, id));
}
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)
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;
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) {}
};
}
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);
vector<uint64_t> snap_features;
vector<parent_info> snap_parents;
vector<uint8_t> snap_protection;
+ vector<uint64_t> snap_flags;
{
int r;
RWLock::WLocker l(ictx->snap_lock);
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<uint64_t> 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;
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);
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,
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;
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;
RBD_FEATURE_STRIPINGV2 = 2
RBD_FEATURE_EXCLUSIVE_LOCK = 4
+RBD_FLAG_OBJECT_MAP_INVALID = 1
+
class Error(Exception):
pass
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):
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)
)
)
+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),