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)
{
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)
{
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,
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
}
}
+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);
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,
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);
case NOTIFY_OP_REBUILD_OBJECT_MAP:
payload = RebuildObjectMapPayload();
break;
+ case NOTIFY_OP_SNAP_RENAME:
+ payload = SnapRenamePayload();
+ break;
default:
payload = UnknownPayload();
break;
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;
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 {
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) {}
FlattenPayload,
ResizePayload,
SnapCreatePayload,
+ SnapRenamePayload,
SnapRemovePayload,
RebuildObjectMapPayload,
UnknownPayload> Payload;
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)
{
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)
{
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);