CEPH_RBD_API int rbd_mirror_image_resync(rbd_image_t image);
CEPH_RBD_API int rbd_mirror_image_create_snapshot(rbd_image_t image,
uint64_t *snap_id);
+CEPH_RBD_API int rbd_mirror_image_create_snapshot2(rbd_image_t image,
+ uint32_t flags,
+ uint64_t *snap_id);
CEPH_RBD_API int rbd_mirror_image_get_info(rbd_image_t image,
rbd_mirror_image_info_t *mirror_image_info,
size_t info_size);
int mirror_image_demote();
int mirror_image_resync();
int mirror_image_create_snapshot(uint64_t *snap_id);
+ int mirror_image_create_snapshot2(uint32_t flags, uint64_t *snap_id);
int mirror_image_get_info(mirror_image_info_t *mirror_image_info,
size_t info_size);
int mirror_image_get_mode(mirror_image_mode_t *mode);
#include "common/dout.h"
#include "librbd/ImageCtx.h"
#include "librbd/Features.h"
+
+#include <bitset>
#include <random>
#define dout_subsys ceph_subsys_rbd
return 0;
}
+int snap_create_flags_api_to_internal(CephContext *cct, uint32_t api_flags,
+ uint64_t *internal_flags) {
+ *internal_flags = 0;
+
+ if (api_flags & RBD_SNAP_CREATE_SKIP_QUIESCE) {
+ *internal_flags |= SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE;
+ api_flags &= ~RBD_SNAP_CREATE_SKIP_QUIESCE;
+ } else if (api_flags & RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR) {
+ *internal_flags |= SNAP_CREATE_FLAG_IGNORE_NOTIFY_QUIESCE_ERROR;
+ api_flags &= ~RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR;
+ }
+
+ if (api_flags != 0) {
+ lderr(cct) << "invalid snap create flags: "
+ << std::bitset<32>(api_flags) << dendl;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
} // namespace util
} // namespace librbd
const std::optional<std::string>& pool_namespace,
librados::IoCtx* dst_io_ctx);
+int snap_create_flags_api_to_internal(CephContext *cct, uint32_t api_flags,
+ uint64_t *internal_flags);
+
} // namespace util
} // namespace librbd
}
template <typename I>
-int Mirror<I>::image_snapshot_create(I *ictx, uint64_t *snap_id) {
+int Mirror<I>::image_snapshot_create(I *ictx, uint32_t flags,
+ uint64_t *snap_id) {
CephContext *cct = ictx->cct;
ldout(cct, 20) << "ictx=" << ictx << dendl;
- int r = ictx->state->refresh_if_required();
+ uint64_t snap_create_flags = 0;
+ int r = util::snap_create_flags_api_to_internal(cct, flags,
+ &snap_create_flags);
+ if (r < 0) {
+ return r;
+ }
+
+ r = ictx->state->refresh_if_required();
if (r < 0) {
return r;
}
C_SaferCond on_finish;
auto req = mirror::snapshot::CreatePrimaryRequest<I>::create(
- ictx, mirror_image.global_image_id, CEPH_NOSNAP, 0U, snap_id, &on_finish);
+ ictx, mirror_image.global_image_id, CEPH_NOSNAP, snap_create_flags, 0U,
+ snap_id, &on_finish);
req->send();
return on_finish.wait();
}
Context *on_finish);
static int image_get_instance_id(ImageCtxT *ictx, std::string *instance_id);
- static int image_snapshot_create(ImageCtxT *ictx, uint64_t *snap_id);
+ static int image_snapshot_create(ImageCtxT *ictx, uint32_t flags,
+ uint64_t *snap_id);
};
} // namespace api
#include "include/Context.h"
#include "common/Cond.h"
-#include <bitset>
#include <boost/variant.hpp>
#define dout_subsys ceph_subsys_rbd
<< " flags: " << flags << dendl;
uint64_t internal_flags = 0;
-
- if (flags & RBD_SNAP_CREATE_SKIP_QUIESCE) {
- internal_flags |= SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE;
- flags &= ~RBD_SNAP_CREATE_SKIP_QUIESCE;
- } else if (flags & RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR) {
- internal_flags |= SNAP_CREATE_FLAG_IGNORE_NOTIFY_QUIESCE_ERROR;
- flags &= ~RBD_SNAP_CREATE_IGNORE_QUIESCE_ERROR;
- }
-
- if (flags != 0) {
- lderr(ictx->cct) << "invalid snap create flags: " << std::bitset<32>(flags)
- << dendl;
- return -EINVAL;
+ int r = util::snap_create_flags_api_to_internal(ictx->cct, flags,
+ &internal_flags);
+ if (r < 0) {
+ return r;
}
return ictx->operations->snap_create(cls::rbd::UserSnapshotNamespace(),
int Image::mirror_image_create_snapshot(uint64_t *snap_id)
{
ImageCtx *ictx = (ImageCtx *)ctx;
- return librbd::api::Mirror<>::image_snapshot_create(ictx, snap_id);
+ return librbd::api::Mirror<>::image_snapshot_create(ictx, 0, snap_id);
+ }
+
+ int Image::mirror_image_create_snapshot2(uint32_t flags, uint64_t *snap_id)
+ {
+ ImageCtx *ictx = (ImageCtx *)ctx;
+ return librbd::api::Mirror<>::image_snapshot_create(ictx, flags, snap_id);
}
int Image::mirror_image_get_info(mirror_image_info_t *mirror_image_info,
uint64_t *snap_id)
{
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
- return librbd::api::Mirror<>::image_snapshot_create(ictx, snap_id);
+ return librbd::api::Mirror<>::image_snapshot_create(ictx, 0, snap_id);
+}
+
+extern "C" int rbd_mirror_image_create_snapshot2(rbd_image_t image,
+ uint32_t flags,
+ uint64_t *snap_id)
+{
+ librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+ return librbd::api::Mirror<>::image_snapshot_create(ictx, flags, snap_id);
}
extern "C" int rbd_mirror_image_get_info(rbd_image_t image,
auto req = snapshot::CreatePrimaryRequest<I>::create(
m_image_ctx, m_mirror_image.global_image_id,
(m_image_clean ? 0 : CEPH_NOSNAP),
+ SNAP_CREATE_FLAG_IGNORE_NOTIFY_QUIESCE_ERROR,
snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS, &m_snap_id, ctx);
req->send();
}
template <typename I>
CreatePrimaryRequest<I>::CreatePrimaryRequest(
I *image_ctx, const std::string& global_image_id,
- uint64_t clean_since_snap_id, uint32_t flags, uint64_t *snap_id,
- Context *on_finish)
+ uint64_t clean_since_snap_id, uint64_t snap_create_flags, uint32_t flags,
+ uint64_t *snap_id, Context *on_finish)
: m_image_ctx(image_ctx), m_global_image_id(global_image_id),
- m_clean_since_snap_id(clean_since_snap_id), m_flags(flags),
- m_snap_id(snap_id), m_on_finish(on_finish) {
+ m_clean_since_snap_id(clean_since_snap_id),
+ m_snap_create_flags(snap_create_flags), m_flags(flags), m_snap_id(snap_id),
+ m_on_finish(on_finish) {
m_default_ns_ctx.dup(m_image_ctx->md_ctx);
m_default_ns_ctx.set_namespace("");
}
auto ctx = create_context_callback<
CreatePrimaryRequest<I>,
&CreatePrimaryRequest<I>::handle_create_snapshot>(this);
- m_image_ctx->operations->snap_create(ns, m_snap_name, 0, m_prog_ctx, ctx);
+ m_image_ctx->operations->snap_create(ns, m_snap_name, m_snap_create_flags,
+ m_prog_ctx, ctx);
}
template <typename I>
static CreatePrimaryRequest *create(ImageCtxT *image_ctx,
const std::string& global_image_id,
uint64_t clean_since_snap_id,
+ uint64_t snap_create_flags,
uint32_t flags, uint64_t *snap_id,
Context *on_finish) {
return new CreatePrimaryRequest(image_ctx, global_image_id,
- clean_since_snap_id, flags, snap_id,
- on_finish);
+ clean_since_snap_id, snap_create_flags, flags,
+ snap_id, on_finish);
}
CreatePrimaryRequest(ImageCtxT *image_ctx,
const std::string& global_image_id,
- uint64_t clean_since_snap_id, uint32_t flags,
- uint64_t *snap_id, Context *on_finish);
+ uint64_t clean_since_snap_id, uint64_t snap_create_flags,
+ uint32_t flags, uint64_t *snap_id, Context *on_finish);
void send();
ImageCtxT *m_image_ctx;
std::string m_global_image_id;
uint64_t m_clean_since_snap_id;
+ const uint64_t m_snap_create_flags;
const uint32_t m_flags;
uint64_t *m_snap_id;
Context *m_on_finish;
auto req = CreatePrimaryRequest<I>::create(
m_image_ctx, m_global_image_id, CEPH_NOSNAP,
+ SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE,
(snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS |
snapshot::CREATE_PRIMARY_FLAG_DEMOTED), nullptr, ctx);
req->send();
auto req = CreatePrimaryRequest<I>::create(
m_image_ctx, m_global_image_id, CEPH_NOSNAP,
+ SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE,
(snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS |
snapshot::CREATE_PRIMARY_FLAG_FORCE), nullptr, ctx);
req->send();
C_SaferCond ctx;
auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
- 0U, nullptr, &ctx);
+ 0U, 0U, nullptr, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
}
C_SaferCond ctx;
auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
- 0U, nullptr, &ctx);
+ 0U, 0U, nullptr, &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
}
C_SaferCond ctx;
auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
- 0U, nullptr, &ctx);
+ 0U, 0U, nullptr, &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
}
C_SaferCond ctx;
auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
- 0U, nullptr, &ctx);
+ 0U, 0U, nullptr, &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
}
0);
C_SaferCond ctx;
auto req = new MockCreatePrimaryRequest(&mock_image_ctx, "gid", CEPH_NOSNAP,
- 0U, nullptr, &ctx);
+ 0U, 0U, nullptr, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
}
static CreatePrimaryRequest *create(MockTestImageCtx *image_ctx,
const std::string& global_image_id,
uint64_t clean_since_snap_id,
+ uint64_t snap_create_flags,
uint32_t flags, uint64_t *snap_id,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
} else {
uint64_t snap_id = CEPH_NOSNAP;
ASSERT_EQ(0, librbd::api::Mirror<>::image_snapshot_create(
- ictx, &snap_id));
+ ictx, 0, &snap_id));
}
printf("flushed\n");