Skip to content

Commit

Permalink
Merge branch 'wip-16773' into wip-mgolub-testing
Browse files Browse the repository at this point in the history
 librbd: interlock image refresh and exclusive lock operations #10770
  • Loading branch information
Mykola Golub committed Aug 18, 2016
2 parents a373578 + f9d6663 commit 68e6b4e
Show file tree
Hide file tree
Showing 29 changed files with 1,411 additions and 172 deletions.
92 changes: 92 additions & 0 deletions src/cls/lock/cls_lock.cc
Expand Up @@ -45,6 +45,7 @@ cls_method_handle_t h_break_lock;
cls_method_handle_t h_get_info;
cls_method_handle_t h_list_locks;
cls_method_handle_t h_assert_locked;
cls_method_handle_t h_set_cookie;

#define LOCK_PREFIX "lock."

Expand Down Expand Up @@ -512,6 +513,94 @@ int assert_locked(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
return 0;
}

/**
* Update the cookie associated with an object lock
*
* Input:
* @param cls_lock_set_cookie_op request input
*
* Output:
* @param none
*
* @return 0 on success, -errno on failure.
*/
int set_cookie(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
{
CLS_LOG(20, "set_cookie");

cls_lock_set_cookie_op op;
try {
bufferlist::iterator iter = in->begin();
::decode(op, iter);
} catch (const buffer::error& err) {
return -EINVAL;
}

if (op.type != LOCK_EXCLUSIVE && op.type != LOCK_SHARED) {
return -EINVAL;
}

if (op.name.empty()) {
return -EINVAL;
}

// see if there's already a locker
lock_info_t linfo;
int r = read_lock(hctx, op.name, &linfo);
if (r < 0) {
CLS_ERR("Could not read lock info: %s", cpp_strerror(r).c_str());
return r;
}

if (linfo.lockers.empty()) {
CLS_LOG(20, "object not locked");
return -EBUSY;
}

if (linfo.lock_type != op.type) {
CLS_LOG(20, "lock type mismatch: current=%s, assert=%s",
cls_lock_type_str(linfo.lock_type), cls_lock_type_str(op.type));
return -EBUSY;
}

if (linfo.tag != op.tag) {
CLS_LOG(20, "lock tag mismatch: current=%s, assert=%s", linfo.tag.c_str(),
op.tag.c_str());
return -EBUSY;
}

entity_inst_t inst;
r = cls_get_request_origin(hctx, &inst);
assert(r == 0);

locker_id_t id;
id.cookie = op.cookie;
id.locker = inst.name;

map<locker_id_t, locker_info_t>::iterator iter = linfo.lockers.find(id);
if (iter == linfo.lockers.end()) {
CLS_LOG(20, "not locked by client");
return -EBUSY;
}

id.cookie = op.new_cookie;
if (linfo.lockers.count(id) != 0) {
CLS_LOG(20, "lock cookie in-use");
return -EBUSY;
}

locker_info_t locker_info(iter->second);
linfo.lockers.erase(iter);

linfo.lockers[id] = locker_info;
r = write_lock(hctx, op.name, linfo);
if (r < 0) {
CLS_ERR("Could not update lock info: %s", cpp_strerror(r).c_str());
return r;
}
return 0;
}

void __cls_init()
{
CLS_LOG(20, "Loaded lock class!");
Expand All @@ -535,6 +624,9 @@ void __cls_init()
cls_register_cxx_method(h_class, "assert_locked",
CLS_METHOD_RD | CLS_METHOD_PROMOTE,
assert_locked, &h_assert_locked);
cls_register_cxx_method(h_class, "set_cookie",
CLS_METHOD_RD | CLS_METHOD_WR | CLS_METHOD_PROMOTE,
set_cookie, &h_set_cookie);

return;
}
16 changes: 16 additions & 0 deletions src/cls/lock/cls_lock_client.cc
Expand Up @@ -189,6 +189,22 @@ namespace rados {
rados_op->exec("lock", "assert_locked", in);
}

void set_cookie(librados::ObjectWriteOperation *rados_op,
const std::string& name, ClsLockType type,
const std::string& cookie, const std::string& tag,
const std::string& new_cookie)
{
cls_lock_set_cookie_op op;
op.name = name;
op.type = type;
op.cookie = cookie;
op.tag = tag;
op.new_cookie = new_cookie;
bufferlist in;
::encode(op, in);
rados_op->exec("lock", "set_cookie", in);
}

void Lock::assert_locked_exclusive(ObjectOperation *op)
{
assert_locked(op, name, LOCK_EXCLUSIVE, cookie, tag);
Expand Down
5 changes: 5 additions & 0 deletions src/cls/lock/cls_lock_client.h
Expand Up @@ -59,6 +59,11 @@ namespace rados {
const std::string& cookie,
const std::string& tag);

extern void set_cookie(librados::ObjectWriteOperation *rados_op,
const std::string& name, ClsLockType type,
const std::string& cookie, const std::string& tag,
const std::string& new_cookie);

class Lock {
std::string name;
std::string cookie;
Expand Down
21 changes: 21 additions & 0 deletions src/cls/lock/cls_lock_ops.cc
Expand Up @@ -188,3 +188,24 @@ void cls_lock_assert_op::generate_test_instances(list<cls_lock_assert_op*>& o)
o.push_back(new cls_lock_assert_op);
}

void cls_lock_set_cookie_op::dump(Formatter *f) const
{
f->dump_string("name", name);
f->dump_string("type", cls_lock_type_str(type));
f->dump_string("cookie", cookie);
f->dump_string("tag", tag);
f->dump_string("new_cookie", new_cookie);
}

void cls_lock_set_cookie_op::generate_test_instances(list<cls_lock_set_cookie_op*>& o)
{
cls_lock_set_cookie_op *i = new cls_lock_set_cookie_op;
i->name = "name";
i->type = LOCK_SHARED;
i->cookie = "cookie";
i->tag = "tag";
i->new_cookie = "new cookie";
o.push_back(i);
o.push_back(new cls_lock_set_cookie_op);
}

36 changes: 36 additions & 0 deletions src/cls/lock/cls_lock_ops.h
Expand Up @@ -203,4 +203,40 @@ struct cls_lock_assert_op
};
WRITE_CLASS_ENCODER(cls_lock_assert_op)

struct cls_lock_set_cookie_op
{
string name;
ClsLockType type;
string cookie;
string tag;
string new_cookie;

cls_lock_set_cookie_op() : type(LOCK_NONE) {}

void encode(bufferlist &bl) const {
ENCODE_START(1, 1, bl);
::encode(name, bl);
uint8_t t = (uint8_t)type;
::encode(t, bl);
::encode(cookie, bl);
::encode(tag, bl);
::encode(new_cookie, bl);
ENCODE_FINISH(bl);
}
void decode(bufferlist::iterator &bl) {
DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl);
::decode(name, bl);
uint8_t t;
::decode(t, bl);
type = (ClsLockType)t;
::decode(cookie, bl);
::decode(tag, bl);
::decode(new_cookie, bl);
DECODE_FINISH(bl);
}
void dump(Formatter *f) const;
static void generate_test_instances(list<cls_lock_set_cookie_op*>& o);
};
WRITE_CLASS_ENCODER(cls_lock_set_cookie_op)

#endif
2 changes: 2 additions & 0 deletions src/librbd/CMakeLists.txt
Expand Up @@ -27,6 +27,7 @@ set(librbd_internal_srcs
Operations.cc
Utils.cc
exclusive_lock/AcquireRequest.cc
exclusive_lock/ReacquireRequest.cc
exclusive_lock/ReleaseRequest.cc
exclusive_lock/StandardPolicy.cc
image/CloseRequest.cc
Expand All @@ -37,6 +38,7 @@ set(librbd_internal_srcs
image/SetSnapRequest.cc
image_watcher/Notifier.cc
image_watcher/NotifyLockOwner.cc
image_watcher/RewatchRequest.cc
journal/RemoveRequest.cc
journal/CreateRequest.cc
journal/Replay.cc
Expand Down

0 comments on commit 68e6b4e

Please sign in to comment.