From ab77dcc0170c0d63795fe0d50427cda630bfd593 Mon Sep 17 00:00:00 2001 From: Li Wang Date: Thu, 7 Dec 2017 22:03:45 +0800 Subject: [PATCH] rbd-nbd: fix ebusy when do map When doing rbd-nbd map, if the Ceph service is not available, the codes will wait on rados.connect(), unless killing the process. In that case, the close_nbd logic is skipped with NBD_CLEAR_SOCK ioctl not called. On the CentOS 7 kernel, it leaves nbd->file not cleared, which causes the subsequent map requests return EBUSY, this patch fixes it by connecting Ceph first prior to calling NBD_SET_SOCK ioctl Fixes: http://tracker.ceph.com/issues/23528 Signed-off-by: Li Wang --- src/tools/rbd_nbd/rbd-nbd.cc | 70 ++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index c4b6fda1255..53442c610f0 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -695,6 +695,41 @@ static int do_map(int argc, const char *argv[], Config *cfg) goto close_ret; } + r = rados.init_with_context(g_ceph_context); + if (r < 0) + goto close_fd; + + r = rados.connect(); + if (r < 0) + goto close_fd; + + r = rados.ioctx_create(cfg->poolname.c_str(), io_ctx); + if (r < 0) + goto close_fd; + + r = rbd.open(io_ctx, image, cfg->imgname.c_str()); + if (r < 0) + goto close_fd; + + if (cfg->exclusive) { + r = image.lock_acquire(RBD_LOCK_MODE_EXCLUSIVE); + if (r < 0) { + cerr << "rbd-nbd: failed to acquire exclusive lock: " << cpp_strerror(r) + << std::endl; + goto close_fd; + } + } + + if (!cfg->snapname.empty()) { + r = image.snap_set(cfg->snapname.c_str()); + if (r < 0) + goto close_fd; + } + + r = image.stat(info, sizeof(info)); + if (r < 0) + goto close_fd; + if (cfg->devpath.empty()) { char dev[64]; bool try_load_module = true; @@ -763,41 +798,6 @@ static int do_map(int argc, const char *argv[], Config *cfg) read_only = 1; } - r = rados.init_with_context(g_ceph_context); - if (r < 0) - goto close_nbd; - - r = rados.connect(); - if (r < 0) - goto close_nbd; - - r = rados.ioctx_create(cfg->poolname.c_str(), io_ctx); - if (r < 0) - goto close_nbd; - - r = rbd.open(io_ctx, image, cfg->imgname.c_str()); - if (r < 0) - goto close_nbd; - - if (cfg->exclusive) { - r = image.lock_acquire(RBD_LOCK_MODE_EXCLUSIVE); - if (r < 0) { - cerr << "rbd-nbd: failed to acquire exclusive lock: " << cpp_strerror(r) - << std::endl; - goto close_nbd; - } - } - - if (!cfg->snapname.empty()) { - r = image.snap_set(cfg->snapname.c_str()); - if (r < 0) - goto close_nbd; - } - - r = image.stat(info, sizeof(info)); - if (r < 0) - goto close_nbd; - r = ioctl(nbd, NBD_SET_BLKSIZE, RBD_NBD_BLKSIZE); if (r < 0) { r = -errno;