From: Li Wang Date: Thu, 7 Dec 2017 14:03:45 +0000 (+0800) Subject: rbd-nbd: fix ebusy when do map X-Git-Tag: v12.2.5~39^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F21230%2Fhead;p=ceph.git 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 (cherry picked from commit ab77dcc0170c0d63795fe0d50427cda630bfd593) --- diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index 531af6bbc86b1..098d9925ca29c 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -613,6 +613,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; @@ -681,41 +716,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;