From: Jason Dillaman Date: Tue, 7 Oct 2014 18:17:50 +0000 (-0400) Subject: librbd: Stub out new exclusive image feature X-Git-Tag: v0.92~20^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fa96bb4db47c500947efcab51892f45a04b03d30;p=ceph.git librbd: Stub out new exclusive image feature When an image is flagged with the exclusive feature, only a single client can modify the image. This is groundwork for an RBD object map optimization and for RBD mirroring. Signed-off-by: Jason Dillaman --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 23f62ab61610..af432d905e12 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -843,7 +843,9 @@ OPTION(rbd_default_format, OPT_INT, 1) 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 diff --git a/src/include/rbd/features.h b/src/include/rbd/features.h index 3f1587f3b40a..9b28b5749953 100644 --- a/src/include/rbd/features.h +++ b/src/include/rbd/features.h @@ -1,10 +1,13 @@ #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 diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 5ff8733b65f9..8d7f23ff2c95 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -155,6 +155,10 @@ CEPH_RBD_API int rbd_get_parent_info(rbd_image_t image, 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); diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index 6b8712fef181..b6be508a69b3 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -117,6 +117,10 @@ public: 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, diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index efbd24d66673..dc60ba94c0b1 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -358,6 +358,17 @@ namespace librbd { 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; @@ -1163,6 +1174,17 @@ extern "C" int rbd_get_parent_info(rbd_image_t image, 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) { diff --git a/src/pybind/rbd.py b/src/pybind/rbd.py index 3d86cd881b64..a91f7c84d8dd 100644 --- a/src/pybind/rbd.py +++ b/src/pybind/rbd.py @@ -27,6 +27,7 @@ ADMIN_AUID = 0 RBD_FEATURE_LAYERING = 1 RBD_FEATURE_STRIPINGV2 = 2 +RBD_FEATURE_EXCLUSIVE_LOCK = 4 class Error(Exception): pass @@ -524,6 +525,13 @@ class Image(object): 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. diff --git a/src/rbd.cc b/src/rbd.cc index 26cb589dc1f1..3e60aeff5379 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -165,6 +165,8 @@ static string feature_str(uint64_t feature) return "layering"; case RBD_FEATURE_STRIPINGV2: return "striping"; + case RBD_FEATURE_EXCLUSIVE_LOCK: + return "exclusive"; default: return ""; } @@ -174,7 +176,7 @@ static string features_str(uint64_t features) { 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()) @@ -188,7 +190,7 @@ static string features_str(uint64_t features) 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)); } @@ -428,7 +430,7 @@ static int do_create(librbd::RBD &rbd, librados::IoCtx& io_ctx, 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)) { diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index 72d435d9e743..e9bccfffb3eb 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -1,16 +1,19 @@ +# 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 @@ -121,7 +124,7 @@ def check_default_params(format, order=None, features=None, stripe_count=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 @@ -888,3 +891,27 @@ class TestClone(object): 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) diff --git a/src/test/run-rbd-tests b/src/test/run-rbd-tests index c06c11e8e61e..7cf9159b3eed 100755 --- a/src/test/run-rbd-tests +++ b/src/test/run-rbd-tests @@ -35,7 +35,7 @@ run_cli_tests 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 diff --git a/src/tracing/librbd.tp b/src/tracing/librbd.tp index b18156bb3deb..6b0580ac6a83 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, 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,