summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Durgin <josh.durgin@inktank.com>2012-12-11 16:39:43 -0800
committerJosh Durgin <josh.durgin@inktank.com>2012-12-11 16:39:59 -0800
commit326dd34726ab231ca443c378a125b38f8b7169b9 (patch)
treed4bd211fc3dcaf8b68e9a7a25c63d2799d9e9beb
parentcaea0cbf9f63d74506d69a596dd3f78097d68da5 (diff)
parent39501822680633b2921925addb24d2498690c781 (diff)
downloadceph-326dd34726ab231ca443c378a125b38f8b7169b9.tar.gz
Merge remote branch 'origin/wip-double-notify' into next
Reviewed-by: Sage Weil <sage.weil@inktank.com>
-rw-r--r--src/osdc/Objecter.cc21
-rw-r--r--src/osdc/Objecter.h3
-rw-r--r--src/test/system/st_rados_watch.cc10
3 files changed, 29 insertions, 5 deletions
diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc
index 2491ea7ab41..9d7fe67cf9d 100644
--- a/src/osdc/Objecter.cc
+++ b/src/osdc/Objecter.cc
@@ -267,7 +267,7 @@ void Objecter::send_linger(LingerOp *info)
o->snapid = info->snap;
// do not resend this; we will send a new op to reregister
- o->should_resend = false;
+ o->should_resend = !info->is_watch;
if (info->session) {
int r = recalc_op_target(o);
@@ -278,7 +278,7 @@ void Objecter::send_linger(LingerOp *info)
if (info->register_tid) {
// repeat send. cancel old registeration op, if any.
- if (ops.count(info->register_tid)) {
+ if (info->is_watch && ops.count(info->register_tid)) {
Op *o = ops[info->register_tid];
cancel_op(o);
}
@@ -335,6 +335,11 @@ void Objecter::unregister_linger(uint64_t linger_id)
}
}
+/**
+ * Note that this is meant to handle a watch OR a notify, but not both in the same ObjectOperation.
+ * This is because watches need to be resent with a new tid on map changes, while notifies
+ * need to resend using the old tid.
+ */
tid_t Objecter::linger(const object_t& oid, const object_locator_t& oloc,
ObjectOperation& op,
snapid_t snap, bufferlist& inbl, bufferlist *poutbl, int flags,
@@ -349,6 +354,18 @@ tid_t Objecter::linger(const object_t& oid, const object_locator_t& oloc,
info->snap = snap;
info->flags = flags;
info->ops = op.ops;
+ bool saw_notify = false;
+ for (vector<OSDOp>::const_iterator it = info->ops.begin();
+ it != info->ops.end(); ++it) {
+ if (it->op.op == CEPH_OSD_OP_WATCH)
+ info->is_watch = true;
+ if (it->op.op == CEPH_OSD_OP_NOTIFY)
+ saw_notify = true;
+ if (info->is_watch)
+ assert(it->op.op != CEPH_OSD_OP_NOTIFY);
+ if (saw_notify)
+ assert(it->op.op != CEPH_OSD_OP_WATCH);
+ }
info->inbl = inbl;
info->poutbl = poutbl;
info->pobjver = objver;
diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h
index 9a20849d574..e23f32a8d0f 100644
--- a/src/osdc/Objecter.h
+++ b/src/osdc/Objecter.h
@@ -816,13 +816,14 @@ public:
tid_t register_tid;
epoch_t map_dne_bound;
+ bool is_watch;
LingerOp() : linger_id(0), flags(0), poutbl(NULL), pobjver(NULL),
registered(false),
on_reg_ack(NULL), on_reg_commit(NULL),
session(NULL), session_item(this),
register_tid(0),
- map_dne_bound(0) {}
+ map_dne_bound(0), is_watch(false) {}
// no copy!
const LingerOp &operator=(const LingerOp& r);
diff --git a/src/test/system/st_rados_watch.cc b/src/test/system/st_rados_watch.cc
index d6647ded8dc..991dde8ea77 100644
--- a/src/test/system/st_rados_watch.cc
+++ b/src/test/system/st_rados_watch.cc
@@ -73,10 +73,16 @@ run()
m_notify_sem->wait();
m_notify_sem->post();
- RETURN1_IF_NOT_VAL(m_num_notifies, num_notifies);
+ int r = 0;
+ if (num_notifies < m_num_notifies) {
+ printf("Received fewer notifies than expected: %d < %d\n",
+ num_notifies, m_num_notifies);
+ r = 1;
+ }
+
rados_unwatch(io_ctx, m_obj_name.c_str(), handle);
rados_ioctx_destroy(io_ctx);
rados_shutdown(cl);
- return 0;
+ return r;
}