From: xinxin shu Date: Thu, 20 Aug 2015 07:09:11 +0000 (+0800) Subject: handle snap rename notify X-Git-Tag: v10.0.0~10^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6ce8b2a7f6ecdd553fec05b711da39ae32ca9738;p=ceph.git handle snap rename notify Signed-off-by: xinxin shu --- diff --git a/src/cls/rbd/cls_rbd_client.cc b/src/cls/rbd/cls_rbd_client.cc index 0385ec98a1d4..e0bbc448078f 100644 --- a/src/cls/rbd/cls_rbd_client.cc +++ b/src/cls/rbd/cls_rbd_client.cc @@ -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) { diff --git a/src/cls/rbd/cls_rbd_client.h b/src/cls/rbd/cls_rbd_client.h index 486d17f36d8d..0aec94e0fa8a 100644 --- a/src/cls/rbd/cls_rbd_client.h +++ b/src/cls/rbd/cls_rbd_client.h @@ -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 *names, std::vector *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 diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index e0e73c3bff0d..49d6a34f90e7 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -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); diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h index 6ebeb9dfcb84..29645b48778f 100644 --- a/src/librbd/ImageWatcher.h +++ b/src/librbd/ImageWatcher.h @@ -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, diff --git a/src/librbd/WatchNotifyTypes.cc b/src/librbd/WatchNotifyTypes.cc index 6785864d8422..be5ce8892319 100644 --- a/src/librbd/WatchNotifyTypes.cc +++ b/src/librbd/WatchNotifyTypes.cc @@ -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(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(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; diff --git a/src/librbd/WatchNotifyTypes.h b/src/librbd/WatchNotifyTypes.h index 94a2836736a7..b81fc619461f 100644 --- a/src/librbd/WatchNotifyTypes.h +++ b/src/librbd/WatchNotifyTypes.h @@ -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 Payload; diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index e1bccdc516dd..9f4b2ad4a818 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -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::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) { diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 7eaa3c5614fe..6ce385f679ff 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -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);