]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
handle snap rename notify
authorxinxin shu <xinxin.shu@intel.com>
Thu, 20 Aug 2015 07:09:11 +0000 (15:09 +0800)
committerxinxin shu <xinxin.shu@intel.com>
Wed, 2 Sep 2015 23:52:22 +0000 (07:52 +0800)
Signed-off-by: xinxin shu <xinxin.shu@intel.com>
src/cls/rbd/cls_rbd_client.cc
src/cls/rbd/cls_rbd_client.h
src/librbd/ImageWatcher.cc
src/librbd/ImageWatcher.h
src/librbd/WatchNotifyTypes.cc
src/librbd/WatchNotifyTypes.h
src/librbd/internal.cc
src/librbd/internal.h

index 0385ec98a1d4082fc88031279bbf2a5fd148a571..e0bbc448078f72679061b9d85d6b9a477bf5c480 100644 (file)
@@ -392,6 +392,15 @@ namespace librbd {
       return ioctx->exec(oid, "rbd", "snapshot_remove", bl, bl2);
     }
 
+    void snapshot_rename(librados::ObjectWriteOperation *op,
+                        snapid_t src_snap_id,
+                        const std::string &dst_name)
+    {
+      bufferlist bl;
+      ::encode(src_snap_id, bl);
+      ::encode(dst_name, bl);
+      op->exec("rbd", "snapshot_rename", bl);
+    }
     int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid,
                        ::SnapContext *snapc)
     {
@@ -484,6 +493,16 @@ namespace librbd {
       return ioctx->exec(oid, "rbd", "snap_add", bl, bl2);
     }
 
+    int old_snapshot_rename(librados::IoCtx *ioctx, const std::string &oid,
+                           snapid_t src_snap_id ,
+                           const std::string &dst_name)
+    {
+      bufferlist bl, bl2;
+      ::encode(src_snap_id, bl);
+      ::encode(dst_name, bl);
+
+      return ioctx->exec(oid, "rbd", "snap_rename", bl, bl2);
+    }
     int old_snapshot_remove(librados::IoCtx *ioctx, const std::string &oid,
                            const std::string &snap_name)
     {
index 486d17f36d8d63f95bf99dda2ef2bdb74c851173..0aec94e0fa8a507a4d1f5e203e71ede9c454c1f5 100644 (file)
@@ -70,6 +70,9 @@ namespace librbd {
                      const std::string &snap_name);
     int snapshot_remove(librados::IoCtx *ioctx, const std::string &oid,
                        snapid_t snap_id);
+    void snapshot_rename(librados::ObjectWriteOperation *op,
+                       snapid_t src_snap_id,
+                       const std::string &dst_name);
     int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid,
                        ::SnapContext *snapc);
     int snapshot_list(librados::IoCtx *ioctx, const std::string &oid,
@@ -144,6 +147,9 @@ namespace librbd {
                          std::vector<string> *names,
                          std::vector<uint64_t> *sizes,
                          ::SnapContext *snapc);
+    int old_snapshot_rename(librados::IoCtx *ioctx, const std::string &oid,
+                           snapid_t src_snap_id,
+                           const std::string &dst_name);
   } // namespace cls_client
 } // namespace librbd
 #endif // CEPH_LIBRBD_CLS_RBD_CLIENT_H
index e0e73c3bff0d1bf1d0535ac2bb070246f97d0556..49d6a34f90e7e09810fad0ed00772d0e63677b25 100644 (file)
@@ -958,6 +958,20 @@ void ImageWatcher::handle_payload(const SnapCreatePayload &payload,
   }
 }
 
+void ImageWatcher::handle_payload(const SnapRenamePayload &payload,
+                                 bufferlist *out) {
+  RWLock::RLocker l(m_image_ctx.owner_lock);
+  if (m_lock_owner_state == LOCK_OWNER_STATE_LOCKED) {
+    ldout(m_image_ctx.cct, 10) << this << " remote snap_rename request: "
+                              << payload.src_snap_id << " to " 
+                              << payload.dst_snap_name << dendl;
+    int r = librbd::snap_rename_helper(&m_image_ctx, NULL,
+                                       payload.src_snap_id,
+                                       payload.dst_snap_name.c_str());
+
+    ::encode(ResponseMessage(r), *out);
+  }
+}
 void ImageWatcher::handle_payload(const SnapRemovePayload &payload,
                                  bufferlist *out) {
   RWLock::RLocker l(m_image_ctx.owner_lock);
index 6ebeb9dfcb840719d1b2cba108f70123b53812e6..29645b48778f82573064dd1944568d3e393a7505 100644 (file)
@@ -269,6 +269,8 @@ namespace librbd {
                        bufferlist *out);
     void handle_payload(const WatchNotify::SnapCreatePayload& payload,
                        bufferlist *out);
+    void handle_payload(const WatchNotify::SnapRenamePayload& payload,
+                       bufferlist *out);
     void handle_payload(const WatchNotify::SnapRemovePayload& payload,
                        bufferlist *out);
     void handle_payload(const WatchNotify::RebuildObjectMapPayload& payload,
index 6785864d8422aa5a212004e88afacddc3e389b34..be5ce889231975a899eaeb87f849ff4e41bb89dc 100644 (file)
@@ -241,6 +241,22 @@ void SnapCreatePayload::dump(Formatter *f) const {
   f->dump_string("snap_name", snap_name);
 }
 
+void SnapRenamePayload::encode(bufferlist &bl) const {
+  ::encode(static_cast<uint32_t>(NOTIFY_OP_SNAP_RENAME), bl);
+  ::encode(src_snap_id, bl);
+  ::encode(dst_snap_name, bl);
+}
+
+void SnapRenamePayload::decode(__u8 version, bufferlist::iterator &iter) {
+  ::decode(src_snap_id, iter);
+  ::decode(dst_snap_name, iter);
+}
+
+void SnapRenamePayload::dump(Formatter *f) const {
+  f->dump_string("notify_op", stringify(NOTIFY_OP_SNAP_RENAME));
+  f->dump_unsigned("src_snap_id", src_snap_id);
+  f->dump_string("dst_snap_name", dst_snap_name);
+}
 void SnapRemovePayload::encode(bufferlist &bl) const {
   ::encode(static_cast<uint32_t>(NOTIFY_OP_SNAP_REMOVE), bl);
   ::encode(snap_name, bl);
@@ -328,6 +344,9 @@ void NotifyMessage::decode(bufferlist::iterator& iter) {
   case NOTIFY_OP_REBUILD_OBJECT_MAP:
     payload = RebuildObjectMapPayload();
     break;
+  case NOTIFY_OP_SNAP_RENAME:
+    payload = SnapRenamePayload();
+    break;
   default:
     payload = UnknownPayload();
     break;
@@ -413,6 +432,9 @@ std::ostream &operator<<(std::ostream &out,
   case NOTIFY_OP_SNAP_REMOVE:
     out << "SnapRemove";
     break;
+  case NOTIFY_OP_SNAP_RENAME:
+    out << "SnapRename";
+    break;
   case NOTIFY_OP_REBUILD_OBJECT_MAP:
     out << "RebuildObjectMap";
     break;
index 94a2836736a7dcfe810b0d696083e038cead525f..b81fc619461f56645f4d3b2f015d2d388e0f92ba 100644 (file)
@@ -83,7 +83,8 @@ enum NotifyOp {
   NOTIFY_OP_RESIZE             = 7,
   NOTIFY_OP_SNAP_CREATE        = 8,
   NOTIFY_OP_SNAP_REMOVE        = 9,
-  NOTIFY_OP_REBUILD_OBJECT_MAP = 10
+  NOTIFY_OP_REBUILD_OBJECT_MAP = 10,
+  NOTIFY_OP_SNAP_RENAME = 11
 };
 
 struct AcquiredLockPayload {
@@ -187,6 +188,19 @@ struct SnapCreatePayload {
   void dump(Formatter *f) const;
 };
 
+struct SnapRenamePayload {
+  SnapRenamePayload() {}
+  SnapRenamePayload(const uint64_t &src_snap_id, const std::string &dst_name) 
+    : src_snap_id(src_snap_id), dst_snap_name(dst_name) {}
+
+  uint64_t src_snap_id;
+  std::string dst_snap_name;
+
+  void encode(bufferlist &bl) const;
+  void decode(__u8 version, bufferlist::iterator &iter);
+  void dump(Formatter *f) const;
+};
+
 struct SnapRemovePayload {
   SnapRemovePayload() {}
   SnapRemovePayload(const std::string &name) : snap_name(name) {}
@@ -224,6 +238,7 @@ typedef boost::variant<AcquiredLockPayload,
                  FlattenPayload,
                  ResizePayload,
                  SnapCreatePayload,
+                 SnapRenamePayload,
                  SnapRemovePayload,
                  RebuildObjectMapPayload,
                  UnknownPayload> Payload;
index e1bccdc516dd5a4625ea658e123d9292754aa956..9f4b2ad4a818fdb6ec538e0ca5d844398777d47a 100644 (file)
@@ -644,6 +644,32 @@ int invoke_async_request(ImageCtx *ictx, const std::string& request_type,
     return 0;
   }
 
+  int snap_rename_helper(ImageCtx* ictx, Context* ctx,
+                         const uint64_t src_snap_id,
+                         const char* dst_name) {
+    assert(ictx->owner_lock.is_locked());
+    assert(!ictx->image_watcher->is_lock_supported() ||
+          ictx->image_watcher->is_lock_owner());
+
+    ldout(ictx->cct, 20) << __func__ << " " << ictx << " from " 
+                        << src_snap_id << " to " << dst_name << dendl;
+
+    int r = ictx_check(ictx, true);
+    if (r < 0) {
+      return r;
+    }
+    r = rename_snap(ictx, src_snap_id, dst_name);
+
+    if (r < 0) {
+      return r;
+    }
+
+    if (ctx != NULL) {
+      ctx->complete(0);
+    }
+    return 0;
+  }
+
   static int scan_for_parents(ImageCtx *ictx, parent_spec &pspec,
                              snapid_t oursnap_id)
   {
@@ -2102,6 +2128,60 @@ reprotect_and_return_err:
 
     return 0;
   }
+  int rename_snap(ImageCtx *ictx, uint64_t src_snap_id, const char *dst_name)
+  {
+    assert(ictx->owner_lock.is_locked());
+
+    int r;
+    map<snap_t, SnapInfo>::iterator it;
+    {
+      RWLock::RLocker(ictx->snap_lock);
+      it = ictx->snap_info.find(src_snap_id);
+      if (it == ictx->snap_info.end()) {
+        ldout(ictx->cct, 20) << __func__ << " can not find snap with snap id "
+                             << src_snap_id << dendl;
+        return -ENOENT;
+      }
+    }
+    bool lock_owner = ictx->image_watcher->is_lock_owner();
+    if (ictx->image_watcher->is_lock_supported()) {
+      assert(lock_owner);
+    }
+
+
+    if (ictx->old_format) {
+      r = cls_client::old_snapshot_rename(&ictx->md_ctx, ictx->header_oid,
+                                      src_snap_id, dst_name);
+    } else {
+      librados::ObjectWriteOperation op;
+      if (lock_owner) {
+       ictx->image_watcher->assert_header_locked(&op);
+      }
+      cls_client::snapshot_rename(&op, src_snap_id, dst_name);
+      r = ictx->md_ctx.operate(ictx->header_oid, &op);
+    }
+
+    if (r < 0) {
+      lderr(ictx->cct) << "rename snapshot name failed: "
+                      << cpp_strerror(r) << dendl;
+      return r;
+    }
+
+    RWLock::WLocker snap_locker(ictx->snap_lock);
+    if (!ictx->old_format) {
+      if (lock_owner) {
+        it = ictx->snap_info.find(src_snap_id);
+        if (it == ictx->snap_info.end())
+          return -ENOENT;
+        ictx->snap_ids.erase(it->second.name);
+        it->second.name = dst_name;
+        ictx->snap_ids.insert(make_pair(dst_name,it->first));
+        if (ictx->snap_id == src_snap_id)
+          ictx->snap_name = it->second.name;
+      }
+    }
+    return 0;
+  }
 
   int ictx_check(ImageCtx *ictx, bool owner_locked)
   {
index 7eaa3c5614fec2fc1e3d68ca0892a2b1b06dab60..6ce385f679fff9d5a45bac956119e7cad7d2ae20 100644 (file)
@@ -110,12 +110,15 @@ namespace librbd {
                    ProgressContext& prog_ctx);
   int snap_remove(ImageCtx *ictx, const char *snap_name);
   int snap_remove_helper(ImageCtx *ictx, Context* ctx, const char *snap_name);
+  int snap_rename_helper(ImageCtx *ictx, Context* ctx, const uint64_t src_snap_id,
+                        const char *dst_name);
   int snap_protect(ImageCtx *ictx, const char *snap_name);
   int snap_unprotect(ImageCtx *ictx, const char *snap_name);
   int snap_is_protected(ImageCtx *ictx, const char *snap_name,
                        bool *is_protected);
   int add_snap(ImageCtx *ictx, const char *snap_name);
   int rm_snap(ImageCtx *ictx, const char *snap_name, uint64_t snap_id);
+  int rename_snap(ImageCtx *ictx, uint64_t src_snap_id, const char *dst_name);
   int refresh_parent(ImageCtx *ictx);
   int ictx_check(ImageCtx *ictx, bool owner_locked=false);
   int ictx_refresh(ImageCtx *ictx);