]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rbd: close image when bench is interrupted
authorMykola Golub <mgolub@suse.com>
Thu, 28 Feb 2019 12:48:00 +0000 (12:48 +0000)
committerMykola Golub <mgolub@suse.com>
Thu, 28 Feb 2019 12:57:19 +0000 (12:57 +0000)
Previously when `rbd bench` was interrupted it left the lock and
watcher and one had to wait for them to expire before reusing or
removing the image.

As a bonus now it prints the benchmark summary on exit even if it
is interrupted.

Signed-off-by: Mykola Golub <mgolub@suse.com>
src/tools/rbd/action/Bench.cc

index ca69b880d22147601e469b230772d4d608ec2af9..e08c3d3fb7b22e38a4e5309526a2c5067bcd8936 100644 (file)
@@ -8,6 +8,7 @@
 #include "common/strtol.h"
 #include "common/Cond.h"
 #include "common/Mutex.h"
+#include "global/signal_handler.h"
 #include <iostream>
 #include <boost/accumulators/accumulators.hpp>
 #include <boost/accumulators/statistics/stats.hpp>
 
 using namespace std::chrono;
 
+static std::atomic<bool> terminating;
+static void handle_signal(int signum)
+{
+  ceph_assert(signum == SIGINT || signum == SIGTERM);
+  terminating = true;
+}
+
 namespace rbd {
 namespace action {
 namespace bench {
@@ -128,7 +136,7 @@ struct rbd_bencher {
       write_bl.push_back(bp);
     }
   }
-    
+
   void start_io(int max, uint64_t off, uint64_t len, int op_flags, bool read_flag)
   {
     {
@@ -149,13 +157,15 @@ struct rbd_bencher {
     }
   }
 
-  void wait_for(int max) {
+  int wait_for(int max) {
     Mutex::Locker l(lock);
-    while (in_flight > max) {
+    while (in_flight > max && !terminating) {
       utime_t dur;
       dur.set_from_double(.2);
       cond.WaitInterval(lock, dur);
     }
+
+    return terminating ? -EINTR : 0;
   }
 
 };
@@ -278,10 +288,14 @@ int do_bench(librbd::Image& image, io_type_t io_type,
   for (off = 0; off < io_bytes; ) {
     // Issue I/O
     i = 0;
+    int r = 0;
     while (i < io_threads && off < io_bytes) {
       bool read_flag = should_read(read_proportion);
 
-      b.wait_for(io_threads - 1);
+      r = b.wait_for(io_threads - 1);
+      if (r < 0) {
+        break;
+      }
       b.start_io(io_threads, thread_offset[i], io_size, op_flags, read_flag);
 
       ++i;
@@ -297,6 +311,10 @@ int do_bench(librbd::Image& image, io_type_t io_type,
         write_ops++;
     }
 
+    if (r < 0) {
+      break;
+    }
+
     // Set the thread_offsets of next I/O
     for (i = 0; i < io_threads; ++i) {
       if (random) {
@@ -468,8 +486,19 @@ int bench_execute(const po::variables_map &vm, io_type_t bench_io_type) {
     return r;
   }
 
+  init_async_signal_handler();
+  register_async_signal_handler(SIGHUP, sighup_handler);
+  register_async_signal_handler_oneshot(SIGINT, handle_signal);
+  register_async_signal_handler_oneshot(SIGTERM, handle_signal);
+
   r = do_bench(image, bench_io_type, bench_io_size, bench_io_threads,
                     bench_bytes, bench_random, bench_read_proportion);
+
+  unregister_async_signal_handler(SIGHUP, sighup_handler);
+  unregister_async_signal_handler(SIGINT, handle_signal);
+  unregister_async_signal_handler(SIGTERM, handle_signal);
+  shutdown_async_signal_handler();
+
   if (r < 0) {
     std::cerr << "bench failed: " << cpp_strerror(r) << std::endl;
     return r;