From: Li Wang Date: Thu, 7 Dec 2017 14:03:45 +0000 (+0800) Subject: rbd-nbd: fix ebusy when do map X-Git-Tag: v13.1.0~424^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F21142%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 --- diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index c4b6fda1255a..53442c610f01 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;