]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-wnbd: wait for disks to become available 53136/head
authorLucian Petrut <lpetrut@cloudbasesolutions.com>
Thu, 24 Aug 2023 11:41:01 +0000 (11:41 +0000)
committerLucian Petrut <lpetrut@cloudbasesolutions.com>
Tue, 29 Aug 2023 09:59:22 +0000 (09:59 +0000)
After a WNBD mapping is created, the driver informs Storport that
the bus changed, expecting it to rescan the bus and expose the disk.
This is an asynchronous process and it usually takes a matter of
milliseconds, up to a few seconds under significant load.

The fsx librbd test ocasionally fails to open the disk as it isn't
ready yet. Unlike the Python rbd-wnbd test, it doesn't perform
any polling.

For convenience, WNBD now includes a helper function called
WnbdPollDiskNumber. We're going to use it to wait for the new
disk attachments to become available.

Signed-off-by: Lucian Petrut <lpetrut@cloudbasesolutions.com>
src/tools/rbd_wnbd/rbd_wnbd.cc
src/tools/rbd_wnbd/rbd_wnbd.h

index e7d5ecea0665e3c2d0f537c712dc36be217ae462..bb899e022bda84ec6c50669ce990857cc7d56967 100644 (file)
@@ -482,6 +482,13 @@ int map_device_using_suprocess(std::string arguments, int timeout_ms)
   clean_process:
     if (!is_process_running(pi.dwProcessId)) {
       GetExitCodeProcess(pi.hProcess, (PDWORD)&exit_code);
+      if (!exit_code) {
+        // Child terminated unexpectedly.
+        exit_code = -ECHILD;
+      } else if (exit_code > 0) {
+        // Make sure to return a negative error code.
+        exit_code = -exit_code;
+      }
       derr << "Daemon failed with: " << cpp_strerror(exit_code) << dendl;
     } else {
       // The process closed the pipe without notifying us or exiting.
@@ -1197,6 +1204,28 @@ boost::intrusive_ptr<CephContext> do_global_init(
   return cct;
 }
 
+// Wait for the mapped disk to become available.
+static int wait_mapped_disk(Config *cfg)
+{
+  DWORD status = WnbdPollDiskNumber(
+    cfg->devpath.c_str(),
+    TRUE, // ExpectMapped
+    TRUE, // TryOpen
+    cfg->image_map_timeout,
+    DISK_STATUS_POLLING_INTERVAL_MS,
+    (PDWORD) &cfg->disk_number);
+  if (status) {
+    derr << "WNBD disk unavailable, error: "
+         << win32_strerror(status) << dendl;
+    return -EINVAL;
+  }
+  dout(0) << "Successfully mapped image: " << cfg->devpath
+          << ". Windows disk path: "
+          << "\\\\.\\PhysicalDrive" + std::to_string(cfg->disk_number)
+          << dendl;
+  return 0;
+}
+
 static int do_map(Config *cfg)
 {
   int r;
@@ -1210,7 +1239,12 @@ static int do_map(Config *cfg)
   int err = 0;
 
   if (g_conf()->daemonize && cfg->parent_pipe.empty()) {
-    return send_map_request(get_cli_args());
+    r = send_map_request(get_cli_args());
+    if (r < 0) {
+      return r;
+    }
+
+    return wait_mapped_disk(cfg);
   }
 
   dout(0) << "Mapping RBD image: " << cfg->devpath << dendl;
@@ -1296,6 +1330,13 @@ static int do_map(Config *cfg)
     goto close_ret;
   }
 
+  // TODO: consider substracting the time it took to perform the
+  // above operations from cfg->image_map_timeout in wait_mapped_disk().
+  r = wait_mapped_disk(cfg);
+  if (r < 0) {
+    goto close_ret;
+  }
+
   // We're informing the parent processes that the initialization
   // was successful.
   if (!cfg->parent_pipe.empty()) {
index ac298e3180f1dd7474ab53fa126b76f9389eeb4a..5cb3301fb7c132ba8445c8f0faf028d57dfe6d5c 100644 (file)
@@ -33,6 +33,7 @@
 
 #define DEFAULT_SERVICE_START_TIMEOUT 120
 #define DEFAULT_IMAGE_MAP_TIMEOUT 20
+#define DISK_STATUS_POLLING_INTERVAL_MS 500
 
 #define HELP_INFO 1
 #define VERSION_INFO 2