]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-nbd: fix ebusy when do map 21142/head
authorLi Wang <laurence.liwang@gmail.com>
Thu, 7 Dec 2017 14:03:45 +0000 (22:03 +0800)
committerLi Wang <laurence.liwang@gmail.com>
Fri, 30 Mar 2018 14:09:03 +0000 (14:09 +0000)
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 <laurence.liwang@gmail.com>
src/tools/rbd_nbd/rbd-nbd.cc

index c4b6fda1255aaf29bfe8614bbbd15c24908f633a..53442c610f01be7b103fcbabdf5c1e0b9d412103 100644 (file)
@@ -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;