]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: replayer: Added image-deleter thread to replayer
authorRicardo Dias <rdias@suse.com>
Thu, 28 Apr 2016 10:49:43 +0000 (11:49 +0100)
committerJason Dillaman <dillaman@redhat.com>
Sun, 22 May 2016 20:13:20 +0000 (16:13 -0400)
Fixes: http://tracker.ceph.com/issues/14421
Signed-off-by: Ricardo Dias <rdias@suse.com>
src/librbd/internal.h
src/tools/rbd_mirror/ImageReplayer.cc
src/tools/rbd_mirror/ImageReplayer.h
src/tools/rbd_mirror/Mirror.cc
src/tools/rbd_mirror/PoolWatcher.cc
src/tools/rbd_mirror/PoolWatcher.h
src/tools/rbd_mirror/Replayer.cc
src/tools/rbd_mirror/Replayer.h

index e33532f9c77f24f2369db88a6a037e0c3b5419c0..71f4d6a998a7fa2c0aa1413299cb3b2a447a03bc 100644 (file)
@@ -90,6 +90,8 @@ namespace librbd {
 
   int snap_set(ImageCtx *ictx, const char *snap_name);
 
+  int list_images_v2(librados::IoCtx& io_ctx,
+      std::map<std::string, std::string>& images);
   int list(librados::IoCtx& io_ctx, std::vector<std::string>& names);
   int list_children(ImageCtx *ictx,
                    std::set<std::pair<std::string, std::string> > & names);
index 6a10c0e62a413433e8e8bbb44550c073847ec436..392eeecd836da7a19d542b432353ce3b4177fe90 100644 (file)
@@ -394,6 +394,10 @@ void ImageReplayer<I>::handle_bootstrap(int r) {
   {
     Mutex::Locker locker(m_lock);
     m_bootstrap_request = nullptr;
+    if (m_local_image_ctx) {
+      m_local_image_id = m_local_image_ctx->id;
+      m_local_image_name = m_local_image_ctx->name;
+    }
   }
 
   if (r == -EREMOTEIO) {
index 3dc12879683033d07efb5ccac6025f927c798a22..280218350776ee781d738d22135d55152e7129c8 100644 (file)
@@ -88,6 +88,10 @@ public:
 
   std::string get_name() { Mutex::Locker l(m_lock); return m_name; };
   void set_state_description(int r, const std::string &desc);
+  inline uint64_t get_local_pool_id() { return m_local_pool_id; }
+  inline const std::string get_local_image_id() { return m_local_image_id; }
+  inline const std::string get_global_image_id() { return m_global_image_id; }
+  inline const std::string get_local_image_name() { return m_local_image_name; }
 
   void start(Context *on_finish = nullptr,
             const BootstrapParams *bootstrap_params = nullptr,
index a5bc849acdccadc9093128f770ea1129468bdf7c..3177bb7c3cd55f90bbdd8d28c5384b134fe109ad 100644 (file)
@@ -345,8 +345,8 @@ void Mirror::update_replayers(const map<peer_t, set<int64_t> > &peer_configs)
     const peer_t &peer = kv.first;
     if (m_replayers.find(peer) == m_replayers.end()) {
       dout(20) << "starting replayer for " << peer << dendl;
-      unique_ptr<Replayer> replayer(new Replayer(m_threads, m_local, peer,
-                                                m_args));
+      unique_ptr<Replayer> replayer(new Replayer(m_threads, m_image_deleter,
+                                                 m_local, peer, m_args));
       // TODO: make async, and retry connecting within replayer
       int r = replayer->init();
       if (r < 0) {
index 0117cabe11f6b51ae6993156b0e761268b6cc25c..a525b004401c8f84970893325809b3278fbdfa9f 100644 (file)
@@ -103,6 +103,18 @@ void PoolWatcher::refresh_images(bool reschedule)
       continue;
     }
 
+    std::map<std::string, std::string> images_map;
+    r = librbd::list_images_v2(ioctx, images_map);
+    if (r < 0) {
+      derr << "error retrieving image names from pool " << pool_name << ": "
+           << cpp_strerror(r) << dendl;
+    }
+
+    std::map<std::string, std::string> image_id_to_name;
+    for (const auto& img_pair : images_map) {
+      image_id_to_name.insert(std::make_pair(img_pair.second, img_pair.first));
+    }
+
     std::set<ImageIds> image_ids;
     std::string last_read = "";
     int max_read = 1024;
@@ -115,7 +127,12 @@ void PoolWatcher::refresh_images(bool reschedule)
         continue;
       }
       for (auto it = mirror_images.begin(); it != mirror_images.end(); ++it) {
-        image_ids.insert(ImageIds(it->first, it->second));
+        boost::optional<std::string> image_name(boost::none);
+        auto it2 = image_id_to_name.find(it->first);
+        if (it2 != image_id_to_name.end()) {
+          image_name = it2->second;
+        }
+        image_ids.insert(ImageIds(it->first, image_name, it->second));
       }
       if (!mirror_images.empty()) {
         last_read = mirror_images.rbegin()->first;
index 0ab45b41e849a51cf9e51bbbb531e89d3a78ae2e..9eeb1015bbeb5a0ac48d376147d2700014bd4b80 100644 (file)
@@ -26,14 +26,17 @@ class PoolWatcher {
 public:
   struct ImageIds {
     std::string id;
+    boost::optional<std::string> name;
     std::string global_id;
 
-    ImageIds(const std::string &id, const std::string &global_id = "")
-      : id(id), global_id(global_id) {
+    ImageIds(const std::string &id,
+             const boost::optional<std::string> &name = boost::none,
+             const std::string &global_id = "")
+      : id(id), name(name), global_id(global_id) {
     }
 
     inline bool operator==(const ImageIds &rhs) const {
-      return (id == rhs.id && global_id == rhs.global_id);
+      return (id == rhs.id && name == rhs.name && global_id == rhs.global_id);
     }
     inline bool operator<(const ImageIds &rhs) const {
       return id < rhs.id;
index da9aa0e0ede1d867dc28fbc12e8f963262d00b39..370b527b50789ed8705f06ae4abf59430d83edbd 100644 (file)
@@ -257,6 +257,8 @@ int Replayer::init()
 {
   dout(20) << "replaying for " << m_peer << dendl;
 
+  m_image_deleter.reset(new ImageDeleter(m_peer.cluster_name, m_local));
+
   // NOTE: manually bootstrap a CephContext here instead of via
   // the librados API to avoid mixing global singletons between
   // the librados shared library and the daemon
@@ -344,6 +346,8 @@ void Replayer::run()
   }
 
   // Stopping
+  m_image_deleter.reset();
+
   PoolImageIds empty_sources;
   while (true) {
     Mutex::Locker l(m_lock);
@@ -375,6 +379,13 @@ void Replayer::print_status(Formatter *f, stringstream *ss)
     }
   }
 
+  if (f) {
+    f->close_section();
+    f->open_object_section("image_deleter");
+  }
+
+  m_image_deleter->print_status(f, ss);
+
   if (f) {
     f->close_section();
     f->close_section();
@@ -578,7 +589,7 @@ void Replayer::set_sources(const PoolImageIds &pool_image_ids)
         dout(20) << "starting image replayer for "
                  << it->second->get_global_image_id() << dendl;
       }
-      start_image_replayer(it->second);
+      start_image_replayer(it->second, image_id.name);
     }
   }
 }
@@ -628,13 +639,25 @@ void Replayer::mirror_image_status_shut_down(int64_t pool_id) {
   m_status_watchers.erase(watcher_it);
 }
 
-void Replayer::start_image_replayer(unique_ptr<ImageReplayer<> > &image_replayer)
+void Replayer::start_image_replayer(unique_ptr<ImageReplayer<> > &image_replayer,
+                                    const boost::optional<std::string>& image_name)
 {
   if (!image_replayer->is_stopped()) {
     return;
   }
 
-  image_replayer->start();
+  if (image_name) {
+    FunctionContext *ctx = new FunctionContext(
+        [&] (int r) {
+          if (r >= 0) {
+            image_replayer->start();
+          } else {
+            start_image_replayer(image_replayer, image_name);
+          }
+       }
+    );
+    m_image_deleter->wait_for_scheduled_deletion(image_name.get(), ctx, false);
+  }
 }
 
 bool Replayer::stop_image_replayer(unique_ptr<ImageReplayer<> > &image_replayer)
@@ -644,7 +667,18 @@ bool Replayer::stop_image_replayer(unique_ptr<ImageReplayer<> > &image_replayer)
   }
 
   if (image_replayer->is_running()) {
-    image_replayer->stop();
+    FunctionContext *ctx = new FunctionContext(
+        [&image_replayer, this] (int r) {
+          if (m_image_deleter) {
+            m_image_deleter->schedule_image_delete(
+                          image_replayer->get_local_pool_id(),
+                          image_replayer->get_local_image_id(),
+                          image_replayer->get_local_image_name(),
+                          image_replayer->get_global_image_id());
+          }
+        }
+    );
+    image_replayer->stop(ctx);
   } else {
     // TODO: check how long it is stopping and alert if it is too long.
   }
index 0dcd5ed72dc75d7be6162a2ca1cf343b5c717273..460f9cf83cbdbebe9d9f972ddef9bebb3661a070 100644 (file)
@@ -18,6 +18,7 @@
 #include "ClusterWatcher.h"
 #include "ImageReplayer.h"
 #include "PoolWatcher.h"
+#include "ImageDeleter.h"
 #include "types.h"
 
 namespace rbd {
@@ -53,7 +54,8 @@ private:
 
   void set_sources(const PoolImageIds &pool_image_ids);
 
-  void start_image_replayer(unique_ptr<ImageReplayer<> > &image_replayer);
+  void start_image_replayer(unique_ptr<ImageReplayer<> > &image_replayer,
+                            const boost::optional<std::string>& image_name);
   bool stop_image_replayer(unique_ptr<ImageReplayer<> > &image_replayer);
 
   int mirror_image_status_init(int64_t pool_id, librados::IoCtx& ioctx);
@@ -75,6 +77,7 @@ private:
                             std::unique_ptr<ImageReplayer<> > > > m_images;
   std::map<int64_t, std::unique_ptr<MirrorStatusWatchCtx> > m_status_watchers;
   ReplayerAdminSocketHook *m_asok_hook;
+  std::unique_ptr<ImageDeleter> m_image_deleter;
 
   class ReplayerThread : public Thread {
     Replayer *m_replayer;