OPTION(rbd_default_order, OPT_INT, 22)
OPTION(rbd_default_stripe_count, OPT_U64, 0) // changing requires stripingv2 feature
OPTION(rbd_default_stripe_unit, OPT_U64, 0) // changing to non-object size requires stripingv2 feature
-OPTION(rbd_default_features, OPT_INT, 3) // 1 for layering, 3 for layering+stripingv2. only applies to format 2 images
+OPTION(rbd_default_features, OPT_INT, 7) // only applies to format 2 images
+ // +1 for layering, +2 for stripingv2,
+ // +4 for exclusive lock
OPTION(nss_db_path, OPT_STR, "") // path to nss db
#ifndef CEPH_RBD_FEATURES_H
#define CEPH_RBD_FEATURES_H
-#define RBD_FEATURE_LAYERING (1<<0)
-#define RBD_FEATURE_STRIPINGV2 (1<<1)
+#define RBD_FEATURE_LAYERING (1<<0)
+#define RBD_FEATURE_STRIPINGV2 (1<<1)
+#define RBD_FEATURE_EXCLUSIVE_LOCK (1<<2)
-#define RBD_FEATURES_INCOMPATIBLE (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2)
-#define RBD_FEATURES_ALL (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2)
+#define RBD_FEATURES_INCOMPATIBLE (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2|\
+ RBD_FEATURE_EXCLUSIVE_LOCK)
+#define RBD_FEATURES_ALL (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2|\
+ RBD_FEATURE_EXCLUSIVE_LOCK)
#endif
char *parent_name, size_t pnamelen,
char *parent_snapname,
size_t psnapnamelen);
+
+/* exclusive lock feature */
+CEPH_RBD_API int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner);
+
CEPH_RBD_API int rbd_copy(rbd_image_t image, rados_ioctx_t dest_io_ctx,
const char *destname);
CEPH_RBD_API int rbd_copy2(rbd_image_t src, rbd_image_t dest);
int size(uint64_t *size);
int features(uint64_t *features);
int overlap(uint64_t *overlap);
+
+ /* exclusive lock feature */
+ int is_exclusive_lock_owner(bool *is_owner);
+
int copy(IoCtx& dest_io_ctx, const char *destname);
int copy2(Image& dest);
int copy_with_progress(IoCtx& dest_io_ctx, const char *destname,
return r;
}
+ int Image::is_exclusive_lock_owner(bool *is_owner)
+ {
+ ImageCtx *ictx = (ImageCtx *)ctx;
+ tracepoint(librbd, is_exclusive_lock_owner_enter, ictx);
+ // TODO: implement
+ int r = 0;
+ *is_owner = false;
+ tracepoint(librbd, is_exclusive_lock_owner_exit, ictx, r, *is_owner);
+ return r;
+ }
+
int Image::copy(IoCtx& dest_io_ctx, const char *destname)
{
ImageCtx *ictx = (ImageCtx *)ctx;
return 0;
}
+extern "C" int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner)
+{
+ librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+ tracepoint(librbd, is_exclusive_lock_owner_enter, ictx);
+ // TODO implement
+ int r = 0;
+ *is_owner = 0;
+ tracepoint(librbd, is_exclusive_lock_owner_exit, ictx, r, *is_owner);
+ return r;
+}
+
/* snapshots */
extern "C" int rbd_snap_create(rbd_image_t image, const char *snap_name)
{
RBD_FEATURE_LAYERING = 1
RBD_FEATURE_STRIPINGV2 = 2
+RBD_FEATURE_EXCLUSIVE_LOCK = 4
class Error(Exception):
pass
raise make_ex(ret, 'error getting overlap for image' % (self.name))
return overlap.value
+ def is_exclusive_lock_owner(self):
+ owner = c_int()
+ ret = self.librbd.rbd_is_exclusive_lock_owner(self.image, byref(owner))
+ if (ret != 0):
+ raise make_ex(ret, 'error getting lock status for image' % (self.name))
+ return owner.value == 1
+
def copy(self, dest_ioctx, dest_name):
"""
Copy the image to another location.
return "layering";
case RBD_FEATURE_STRIPINGV2:
return "striping";
+ case RBD_FEATURE_EXCLUSIVE_LOCK:
+ return "exclusive";
default:
return "";
}
{
string s = "";
- for (uint64_t feature = 1; feature <= RBD_FEATURE_STRIPINGV2;
+ for (uint64_t feature = 1; feature <= RBD_FEATURE_EXCLUSIVE_LOCK;
feature <<= 1) {
if (feature & features) {
if (s.size())
static void format_features(Formatter *f, uint64_t features)
{
f->open_array_section("features");
- for (uint64_t feature = 1; feature <= RBD_FEATURE_STRIPINGV2;
+ for (uint64_t feature = 1; feature <= RBD_FEATURE_EXCLUSIVE_LOCK;
feature <<= 1) {
f->dump_string("feature", feature_str(feature));
}
r = rbd.create(io_ctx, imgname, size, order);
} else {
if (features == 0) {
- features = RBD_FEATURE_LAYERING;
+ features = RBD_FEATURE_LAYERING | RBD_FEATURE_EXCLUSIVE_LOCK;
}
if ((stripe_unit || stripe_count) &&
(stripe_unit != (1ull << *order) && stripe_count != 1)) {
+# vim: expandtab smarttab shiftwidth=4 softtabstop=4
import functools
import random
import socket
import struct
import os
+from contextlib import nested
from nose import with_setup, SkipTest
from nose.tools import eq_ as eq, assert_raises
from rados import Rados
from rbd import (RBD, Image, ImageNotFound, InvalidArgument, ImageExists,
ImageBusy, ImageHasSnapshots, ReadOnlyImage,
FunctionNotSupported, ArgumentOutOfRange,
- RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2)
+ RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2,
+ RBD_FEATURE_EXCLUSIVE_LOCK)
rados = None
expected_features = features
if expected_features is None or format == 1:
- expected_features = 0 if format == 1 else 3
+ expected_features = 0 if format == 1 else 7
eq(expected_features, image.features())
expected_stripe_count = stripe_count
self.rbd.remove(ioctx, clone_name3)
self.clone.unprotect_snap('snap2')
self.clone.remove_snap('snap2')
+
+class TestExclusiveLock(object):
+
+ @require_features([RBD_FEATURE_EXCLUSIVE_LOCK])
+ def setUp(self):
+ global rados2
+ rados2 = Rados(conffile='')
+ rados2.connect()
+ global ioctx2
+ ioctx2 = rados2.open_ioctx(pool_name)
+ create_image()
+
+ def tearDown(self):
+ remove_image()
+ global ioctx2
+ ioctx2.__del__()
+ global rados2
+ rados2.shutdown()
+
+ def test_ownership(self):
+ with nested(Image(ioctx, image_name), Image(ioctx2, image_name)) as (
+ image1, image2):
+ eq(image1.is_exclusive_lock_owner(), False)
+ eq(image2.is_exclusive_lock_owner(), False)
RBD_CREATE_ARGS="--format 2"
run_cli_tests
-for i in 0 1
+for i in 0 1 5
do
RBD_FEATURES=$i
run_api_tests
)
)
+TRACEPOINT_EVENT(librbd, is_exclusive_lock_owner_enter,
+ TP_ARGS(
+ void*, imagectx),
+ TP_FIELDS(
+ ctf_integer_hex(void*, imagectx, imagectx)
+ )
+)
+
+TRACEPOINT_EVENT(librbd, is_exclusive_lock_owner_exit,
+ TP_ARGS(
+ void*, imagectx,
+ int, retval,
+ char, is_owner),
+ TP_FIELDS(
+ ctf_integer_hex(void*, imagectx, imagectx)
+ ctf_integer(int, retval, retval)
+ ctf_integer(char, is_owner, is_owner)
+ )
+)
+
TRACEPOINT_EVENT(librbd, stat_enter,
TP_ARGS(
void*, imagectx,