Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rbd: watch command should unwatch before exiting #3578

Merged
merged 1 commit into from Feb 2, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
88 changes: 51 additions & 37 deletions src/rbd.cc
Expand Up @@ -2106,60 +2106,69 @@ static int do_copy(librbd::Image &src, librados::IoCtx& dest_pp,
return 0;
}

class RbdWatchCtx : public librados::WatchCtx {
string name;
class RbdWatchCtx : public librados::WatchCtx2 {
public:
RbdWatchCtx(const char *imgname) : name(imgname) {}
RbdWatchCtx(librados::IoCtx& io_ctx, const char *image_name,
std::string header_oid)
: m_io_ctx(io_ctx), m_image_name(image_name), m_header_oid(header_oid)
{
}

virtual ~RbdWatchCtx() {}
virtual void notify(uint8_t opcode, uint64_t ver, bufferlist& bl) {
cout << name << " got notification opcode=" << (int)opcode << " ver="
<< ver << " bl.length=" << bl.length() << std::endl;

virtual void handle_notify(uint64_t notify_id,
uint64_t cookie,
uint64_t notifier_id,
bufferlist& bl) {
cout << m_image_name << " received notification: notify_id=" << notify_id
<< ", cookie=" << cookie << ", notifier_id=" << notifier_id
<< ", bl.length=" << bl.length() << std::endl;
bufferlist reply;
m_io_ctx.notify_ack(m_header_oid, notify_id, cookie, reply);
}

virtual void handle_error(uint64_t cookie, int err) {
cerr << m_image_name << " received error: cookie=" << cookie << ", err="
<< cpp_strerror(err) << std::endl;
}
private:
librados::IoCtx m_io_ctx;
const char *m_image_name;
string m_header_oid;
};

static int do_watch(librados::IoCtx& pp, const char *imgname)
static int do_watch(librados::IoCtx& pp, librbd::Image &image,
const char *imgname)
{
string md_oid, dest_md_oid;
uint64_t cookie;
RbdWatchCtx ctx(imgname);

string old_header_oid = imgname;
old_header_oid += RBD_SUFFIX;
string new_id_oid = RBD_ID_PREFIX;
string new_header_oid = RBD_HEADER_PREFIX;
new_id_oid += imgname;
bool old_format = true;

int r = pp.stat(old_header_oid, NULL, NULL);
uint8_t old_format;
int r = image.old_format(&old_format);
if (r < 0) {
r = pp.stat(new_id_oid, NULL, NULL);
if (r < 0)
return r;
old_format = false;
cerr << "failed to query format" << std::endl;
return r;
}

if (!old_format) {
librbd::RBD rbd;
string header_oid;
if (old_format != 0) {
header_oid = string(imgname) + RBD_SUFFIX;
} else {
librbd::image_info_t info;
librbd::Image image;

r = rbd.open_read_only(pp, image, imgname, NULL);
if (r < 0)
return r;

r = image.stat(info, sizeof(info));
if (r < 0)
if (r < 0) {
cerr << "failed to stat image" << std::endl;
return r;
}

char prefix[RBD_MAX_BLOCK_NAME_SIZE + 1];
strncpy(prefix, info.block_name_prefix, RBD_MAX_BLOCK_NAME_SIZE);
prefix[RBD_MAX_BLOCK_NAME_SIZE] = '\0';

new_header_oid.append(prefix + strlen(RBD_DATA_PREFIX));
string image_id(prefix + strlen(RBD_DATA_PREFIX));
header_oid = RBD_HEADER_PREFIX + image_id;
}

r = pp.watch(old_format ? old_header_oid : new_header_oid,
0, &cookie, &ctx);
uint64_t cookie;
RbdWatchCtx ctx(pp, imgname, header_oid);
r = pp.watch2(header_oid, &cookie, &ctx);
if (r < 0) {
cerr << "rbd: watch failed" << std::endl;
return r;
Expand All @@ -2168,6 +2177,11 @@ static int do_watch(librados::IoCtx& pp, const char *imgname)
cout << "press enter to exit..." << std::endl;
getchar();

r = pp.unwatch2(cookie);
if (r < 0) {
cerr << "rbd: unwatch failed" << std::endl;
return r;
}
return 0;
}

Expand Down Expand Up @@ -3006,7 +3020,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \
if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
opt_cmd == OPT_EXPORT || opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY ||
opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST ||
opt_cmd == OPT_STATUS) {
opt_cmd == OPT_STATUS || opt_cmd == OPT_WATCH) {
r = rbd.open_read_only(io_ctx, image, imgname, NULL);
} else {
r = rbd.open(io_ctx, image, imgname);
Expand Down Expand Up @@ -3330,7 +3344,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \
break;

case OPT_WATCH:
r = do_watch(io_ctx, imgname);
r = do_watch(io_ctx, image, imgname);
if (r < 0) {
cerr << "rbd: watch failed: " << cpp_strerror(-r) << std::endl;
return -r;
Expand Down