"", "", m_remote_io_ctx,
false);
ictx->state->open();
- EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str()));
+ EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str(),
+ cls::rbd::UserSnapshotNamespace()));
EXPECT_EQ(0, ictx->operations->snap_protect(snap_name.c_str()));
ictx->state->close();
}
expect_update_client(mock_remote_journaler, 0);
mock_local_image_ctx.snap_info = {
- {6, librbd::SnapInfo{"snap", 0U, {}, 0U, 0U}}};
+ {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U}}};
m_client_meta.snap_seqs = {{1, 2}, {3, 4}, {5, 6}};
MockEventPreprocessor event_preprocessor(mock_local_image_ctx,
mock_remote_journaler,
mock_local_image_ctx.snap_ids = {{"snap", 6}};
mock_local_image_ctx.snap_info = {
- {6, librbd::SnapInfo{"snap", 0U, {}, 0U, 0U}}};
+ {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U}}};
MockEventPreprocessor event_preprocessor(mock_local_image_ctx,
mock_remote_journaler,
"local mirror uuid",
expect_image_refresh(mock_local_image_ctx, 0);
mock_local_image_ctx.snap_info = {
- {6, librbd::SnapInfo{"snap", 0U, {}, 0U, 0U}}};
+ {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U}}};
m_client_meta.snap_seqs = {{5, 6}};
MockEventPreprocessor event_preprocessor(mock_local_image_ctx,
mock_remote_journaler,
mock_local_image_ctx.snap_ids = {{"snap", 6}};
mock_local_image_ctx.snap_info = {
- {6, librbd::SnapInfo{"snap", 0U, {}, 0U, 0U}}};
+ {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U}}};
MockEventPreprocessor event_preprocessor(mock_local_image_ctx,
mock_remote_journaler,
"local mirror uuid",
static SnapshotCreateRequest* s_instance;
static SnapshotCreateRequest* create(librbd::MockTestImageCtx* image_ctx,
const std::string &snap_name,
+ const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::parent_spec &parent_spec,
uint64_t parent_overlap,
int create_snap(librbd::ImageCtx *image_ctx, const std::string &snap_name,
bool protect = false) {
- int r = image_ctx->operations->snap_create(snap_name.c_str());
+ int r = image_ctx->operations->snap_create(snap_name.c_str(),
+ cls::rbd::UserSnapshotNamespace());
if (r < 0) {
return r;
}
void expect_snap_create(librbd::MockTestImageCtx &mock_image_ctx,
const std::string &snap_name, uint64_t snap_id, int r) {
- EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(StrEq(snap_name), _, 0, true))
+ EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(StrEq(snap_name), _, _, 0, true))
.WillOnce(DoAll(InvokeWithoutArgs([&mock_image_ctx, snap_id, snap_name]() {
inject_snap(mock_image_ctx, snap_id, snap_name);
}),
- WithArg<1>(Invoke([this, r](Context *ctx) {
+ WithArg<2>(Invoke([this, r](Context *ctx) {
m_threads->work_queue->queue(ctx, r);
}))));
}
MockSnapshotCreateRequest *create_request(librbd::MockTestImageCtx &mock_local_image_ctx,
const std::string &snap_name,
+ const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::parent_spec &spec,
uint64_t parent_overlap,
Context *on_finish) {
- return new MockSnapshotCreateRequest(&mock_local_image_ctx, snap_name, size,
+ return new MockSnapshotCreateRequest(&mock_local_image_ctx, snap_name, snap_namespace, size,
spec, parent_overlap, on_finish);
}
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
- "snap1", 123, {}, 0,
+ "snap1",
+ cls::rbd::UserSnapshotNamespace(),
+ 123, {}, 0,
&ctx);
request->send();
ASSERT_EQ(0, ctx.wait());
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
- "snap1", 123, {}, 0,
+ "snap1",
+ cls::rbd::UserSnapshotNamespace(),
+ 123, {}, 0,
&ctx);
request->send();
ASSERT_EQ(-EINVAL, ctx.wait());
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{}, 0, &ctx);
request->send();
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{}, 0, &ctx);
request->send();
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{123, "test", 0}, 0,
&ctx);
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{123, "test", 0}, 0,
&ctx);
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
mock_local_image_ctx.parent_md.spec,
123, &ctx);
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{123, "test", 0}, 0,
&ctx);
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{}, 0, &ctx);
request->send();
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{}, 0, &ctx);
request->send();
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{}, 0, &ctx);
request->send();
C_SaferCond ctx;
MockSnapshotCreateRequest *request = create_request(mock_local_image_ctx,
"snap1",
+ cls::rbd::UserSnapshotNamespace(),
m_local_image_ctx->size,
{}, 0, &ctx);
request->send();
}
void expect_snap_create(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) {
- EXPECT_CALL(*mock_remote_image_ctx.operations, snap_create(_, _))
- .WillOnce(WithArg<1>(CompleteContext(r)));
+ EXPECT_CALL(*mock_remote_image_ctx.operations, snap_create(_, _, _))
+ .WillOnce(WithArg<2>(CompleteContext(r)));
}
MockSyncPointCreateRequest *create_request(librbd::MockTestImageCtx &mock_remote_image_ctx,
#include "include/rados/librados.hpp"
#include "include/rbd/librbd.hpp"
#include "include/stringify.h"
+#include "cls/rbd/cls_rbd_types.h"
#include "cls/rbd/cls_rbd_client.h"
#include "tools/rbd_mirror/ImageDeleter.h"
#include "tools/rbd_mirror/ImageReplayer.h"
EXPECT_EQ(0, ictx->state->open());
promote_image(ictx);
- EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str()));
+ EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str(),
+ cls::rbd::UserSnapshotNamespace()));
if (protect) {
EXPECT_EQ(0, ictx->operations->snap_protect(snap_name.c_str()));
EXPECT_EQ(0, ictx->state->open());
promote_image(ictx);
- EXPECT_EQ(0, ictx->operations->snap_create("snap1"));
+ EXPECT_EQ(0, ictx->operations->snap_create("snap1",
+ cls::rbd::UserSnapshotNamespace()));
EXPECT_EQ(0, ictx->operations->snap_protect("snap1"));
int order = 20;
EXPECT_EQ(0, librbd::clone(m_local_io_ctx, ictx->name.c_str(), "snap1",
#include "include/stringify.h"
#include "cls/journal/cls_journal_types.h"
#include "cls/journal/cls_journal_client.h"
+#include "cls/rbd/cls_rbd_types.h"
#include "cls/rbd/cls_rbd_client.h"
#include "journal/Journaler.h"
#include "librbd/AioCompletion.h"
librbd::ImageCtx *ictx;
open_image(m_local_ioctx, m_image_name, false, &ictx);
ictx->features &= ~RBD_FEATURE_JOURNALING;
- ASSERT_EQ(0, ictx->operations->snap_create("foo"));
+ ASSERT_EQ(0, ictx->operations->snap_create("foo",
+ cls::rbd::UserSnapshotNamespace()));
ASSERT_EQ(0, ictx->operations->snap_protect("foo"));
ASSERT_EQ(0, librbd::cls_client::add_child(&ictx->md_ctx, RBD_CHILDREN,
{ictx->md_ctx.get_id(),
librbd::ImageCtx *ictx;
open_image(m_local_ioctx, m_image_name, false, &ictx);
ictx->features &= ~RBD_FEATURE_JOURNALING;
- ASSERT_EQ(0, ictx->operations->snap_create("foo"));
+ ASSERT_EQ(0, ictx->operations->snap_create("foo",
+ cls::rbd::UserSnapshotNamespace()));
ASSERT_EQ(0, ictx->operations->snap_protect("foo"));
ASSERT_EQ(0, librbd::cls_client::add_child(&ictx->md_ctx, RBD_CHILDREN,
{ictx->md_ctx.get_id(),
#include "include/rados/librados.hpp"
#include "include/rbd/librbd.hpp"
#include "include/stringify.h"
+#include "cls/rbd/cls_rbd_types.h"
#include "cls/rbd/cls_rbd_client.h"
#include "include/rbd_types.h"
#include "librbd/internal.h"
librbd::ImageCtx *ictx = new librbd::ImageCtx(parent_image_name.c_str(),
"", "", pioctx, false);
ictx->state->open();
- EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str()));
+ EXPECT_EQ(0, ictx->operations->snap_create(snap_name.c_str(),
+ cls::rbd::UserSnapshotNamespace()));
EXPECT_EQ(0, ictx->operations->snap_protect(snap_name.c_str()));
ictx->state->close();
}
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
+#include "cls/rbd/cls_rbd_types.h"
#include "test/rbd_mirror/test_fixture.h"
#include "include/stringify.h"
#include "include/rbd/librbd.hpp"
int TestFixture::create_snap(librbd::ImageCtx *image_ctx, const char* snap_name,
librados::snap_t *snap_id) {
- int r = image_ctx->operations->snap_create(snap_name);
+ int r = image_ctx->operations->snap_create(snap_name,
+ cls::rbd::UserSnapshotNamespace());
if (r < 0) {
return r;
}
librados::snap_t local_snap_id = *snap_id_it;
m_local_image_ctx->snap_lock.get_read();
+
bool local_unprotected;
int r = m_local_image_ctx->is_snap_unprotected(local_snap_id,
&local_unprotected);
for (; snap_id_it != m_local_snap_ids.end(); ++snap_id_it) {
librados::snap_t local_snap_id = *snap_id_it;
+ cls::rbd::SnapshotNamespace snap_namespace;
+ m_local_image_ctx->snap_lock.get_read();
+ int r = m_local_image_ctx->get_snap_namespace(local_snap_id, &snap_namespace);
+ m_local_image_ctx->snap_lock.put_read();
+ if (r < 0) {
+ derr << ": failed to retrieve local snap namespace: " << m_snap_name
+ << dendl;
+ finish(r);
+ return;
+ }
+
+ if (boost::get<cls::rbd::UserSnapshotNamespace>(&snap_namespace) == nullptr) {
+ continue;
+ }
+
// if the local snapshot isn't in our mapping table, remove it
auto snap_seq_it = std::find_if(
m_snap_seqs.begin(), m_snap_seqs.end(),
for (; snap_id_it != m_remote_snap_ids.end(); ++snap_id_it) {
librados::snap_t remote_snap_id = *snap_id_it;
+ cls::rbd::SnapshotNamespace snap_namespace;
+ m_remote_image_ctx->snap_lock.get_read();
+ int r = m_remote_image_ctx->get_snap_namespace(remote_snap_id, &snap_namespace);
+ m_remote_image_ctx->snap_lock.put_read();
+ if (r < 0) {
+ derr << ": failed to retrieve remote snap namespace: " << m_snap_name
+ << dendl;
+ finish(r);
+ return;
+ }
+
// if the remote snapshot isn't in our mapping table, create it
- if (m_snap_seqs.find(remote_snap_id) == m_snap_seqs.end()) {
+ if (m_snap_seqs.find(remote_snap_id) == m_snap_seqs.end() &&
+ boost::get<cls::rbd::UserSnapshotNamespace>(&snap_namespace) != nullptr) {
break;
}
}
}
uint64_t size = snap_info_it->second.size;
+ m_snap_namespace = snap_info_it->second.snap_namespace;
librbd::parent_spec parent_spec;
uint64_t parent_overlap = 0;
if (snap_info_it->second.parent.spec.pool_id != -1) {
SnapshotCopyRequest<I>, &SnapshotCopyRequest<I>::handle_snap_create>(
this);
SnapshotCreateRequest<I> *req = SnapshotCreateRequest<I>::create(
- m_local_image_ctx, m_snap_name, size, parent_spec, parent_overlap, ctx);
+ m_local_image_ctx, m_snap_name, m_snap_namespace, size, parent_spec, parent_overlap, ctx);
req->send();
}
librados::snap_t remote_snap_id = *snap_id_it;
m_remote_image_ctx->snap_lock.get_read();
+
bool remote_protected;
int r = m_remote_image_ctx->is_snap_protected(remote_snap_id,
&remote_protected);
librados::snap_t m_prev_snap_id = CEPH_NOSNAP;
std::string m_snap_name;
+ cls::rbd::SnapshotNamespace m_snap_namespace;
librbd::parent_spec m_local_parent_spec;
#include "SnapshotCreateRequest.h"
#include "common/errno.h"
#include "cls/rbd/cls_rbd_client.h"
+#include "cls/rbd/cls_rbd_types.h"
#include "librbd/ObjectMap.h"
#include "librbd/Operations.h"
#include "librbd/Utils.h"
template <typename I>
SnapshotCreateRequest<I>::SnapshotCreateRequest(I *local_image_ctx,
const std::string &snap_name,
+ const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::parent_spec &spec,
uint64_t parent_overlap,
Context *on_finish)
- : m_local_image_ctx(local_image_ctx), m_snap_name(snap_name), m_size(size),
+ : m_local_image_ctx(local_image_ctx), m_snap_name(snap_name),
+ m_snap_namespace(snap_namespace), m_size(size),
m_parent_spec(spec), m_parent_overlap(parent_overlap),
m_on_finish(on_finish) {
}
SnapshotCreateRequest<I>, &SnapshotCreateRequest<I>::handle_snap_create>(
this);
RWLock::RLocker owner_locker(m_local_image_ctx->owner_lock);
- m_local_image_ctx->operations->execute_snap_create(m_snap_name.c_str(), ctx,
+ m_local_image_ctx->operations->execute_snap_create(m_snap_name.c_str(),
+ m_snap_namespace,
+ ctx,
0U, true);
}
public:
static SnapshotCreateRequest* create(ImageCtxT *local_image_ctx,
const std::string &snap_name,
+ const cls::rbd::SnapshotNamespace &snap_namespace,
uint64_t size,
const librbd::parent_spec &parent_spec,
uint64_t parent_overlap,
Context *on_finish) {
- return new SnapshotCreateRequest(local_image_ctx, snap_name, size,
+ return new SnapshotCreateRequest(local_image_ctx, snap_name, snap_namespace, size,
parent_spec, parent_overlap, on_finish);
}
SnapshotCreateRequest(ImageCtxT *local_image_ctx,
- const std::string &snap_name, uint64_t size,
+ const std::string &snap_name,
+ const cls::rbd::SnapshotNamespace &snap_namespace,
+ uint64_t size,
const librbd::parent_spec &parent_spec,
uint64_t parent_overlap, Context *on_finish);
ImageCtxT *m_local_image_ctx;
std::string m_snap_name;
+ cls::rbd::SnapshotNamespace m_snap_namespace;
uint64_t m_size;
librbd::parent_spec m_parent_spec;
uint64_t m_parent_overlap;
SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_create_snap>(
this);
m_remote_image_ctx->operations->snap_create(
- sync_point.snap_name.c_str(), ctx);
+ sync_point.snap_name.c_str(), cls::rbd::UserSnapshotNamespace(), ctx);
}
template <typename I>